在宽度确定的情况下高度自适应

CSS今日感悟

最近在制作一个网页,在制作该网页的过程中习得了一些奇技淫巧,特来记录分享

导航栏子菜单对应

对于顶部导航栏的菜单项,如果还有子菜单项的显示,大家应该都很了解,在菜单项中添加 position:relative 然后在菜单项中的子菜单中添加 position:absolute 然后定位即可,使用 :hover 来控制显示。这样的做法非常简练,完全没有使用到js代码,注意这样的方法必须要把子菜单放在菜单项的结构当中,类似于这样的代码:

<span>菜单项 <ul> <li>子菜单项</li> </ul> </span>

现在问题来了,如果我想摆脱这种结构,想把子菜单项移到菜单项外部怎么办?

<span>菜单项</span> <ul> <li>子菜单项</li> </ul>

这个时候应该怎么办,由于CSS没有兄弟选择器,所以必须要借助JS来完成相应的操作,我以前的做法一般是两个都写好类,然后在鼠标移到菜单项的时候,通过JS寻找子菜单的类来显示出子菜单。最近我又掌握了一种没方便多少,但是看起来装逼很多的方法。

<span data-id="a">菜单项</span> <ul class="a"> <li>子菜单项</li> </ul>

那这个data-id是什么呢?不知道真相的围观群众可能已经被吓到了,其实什么都不是,就是个我自己编出来的属性,然后在JS中获得这个属性的属性值,再来寻找这个与这个属性值相同的类就好啦。

var selector = $(this).attr('data-id'); $('.' + selector).show();

在宽度确定的情况下的高度自适应

在这个网页的制作中我使用了flex来做自适应,flex大家都知道,它可以将一块区域由我们来分块,这说明了什么?宽度是以为由css帮我们算好了,左边占1/3,右边占2/3。

现在我们需要考虑的就是如何让高度能很好的自适应了。举个例子,如果我们想要让左右两边的高度相同,该怎么办?有个很简单的办法都给定死了height呗,然后如果要自适应在就在不同的宽度中修改height。这样的方法很经济,过程很简单,而且挺高效的。

这里我讲一种很厉害的方法,它能让高度随着宽度自适应改变,宽度变高度则跟着变。那什么样的属性能跟着宽度变呢?我脑里冒出来两个奇怪的东西:margin和padding两兄弟,这两兄弟的百分比设置,如果大家还有印象的话,很神奇是跟着父容器的宽度来确定的,就算是padding-top我们认为的垂直方向上的东西,也是跟着父容器的宽度来确定。那有这两兄弟能怎么样呢?首先我们知道margin是不能放入任何东西的,所以我们就使用padding来作为我们的实现的工具。

首先我们有一个明确宽度的容器,容器内没有任何东西,所以高度也是0。这里我们使用一个::before选择器,我们在容器的前面加上padding-top属性,而属性值是多少呢?就是我们需要的高度,高度是容器宽度的百分之多少。我们会发现整个容器真的就有了高度,而这个高度是由::before的padding-top所撑出来的,这里我还没有去查证,::before的父容器是不是本身,但是看表现来看,应该就为本身的宽度。

然后我们给容器设置一个 position:relative 用来为自容器做准备。这个时候如果我们直接在容器内添加元素的话,我们会发现会呈现在容器的下面,这是为什么呢?很明显因为我们使用的是padding-top属性,上面但是不能直接显示元素的,这个时候我们该怎么办?我们给子容器设置 position:absolute,保险的话,我们分别再给 top, bottomleft, right 设置为0,这个时候我们就会发现了:

子容器就很自然的挤在了我们设置的padding-top中,又由于我们给父容器设置了relative,所以这个absolute的使用也非常安全,这样我们就大功告成了。

这个方法必须要父容器宽度已知的情况才能使用。