纯CSS实现响应式正方形 & nth-last-child 等选择器的应用

看到一个slide,里面的东西挺有趣的就动手实践一下.

effortless style (需翻墙)

首先看到这样的布局就思考了好久...肿么可以不用JS只用CSS就弄出来正方形呢...

1

stackoverflow了一下发现了解决办法

<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

ul{
    width:500px;
    margin:0 auto;
    list-style:none;
}
li{
    width:25%;  / 注意这里 /
    padding-bottom:25%; / 注意这里 /
    float: left;
    background-color: #000;
    position: relative;
    border: 3px solid #fff;
    margin: -3px;  / hack for border /
}

这里用了一个很巧妙的方法: 把padding-bottom设置成和width一样的值. 原理很简单: 垂直方向上的padding和margin百分比的取值是取决于容器的元素的宽度的, 当然这里的paddin-bottom可以换成padding-top.

注意: 由于正方形(这里的li)的高度是又padding-bottom决定的,因此li如果有处于文档流中的子元素那么li的高度就会被撑大,因此需要把li的子元素脱离文档流,例如设置position:absolute.

注意: 这里的li不能设置box-sizing:border-box, 因为这里有一个3px的边框, 设置了box-sizing:border-box会导致li显示出来的宽比高少了6px

last-child

li:last-child {
    width:100%;
    background-color: green;
}

伪类叠加使用1

li:nth-child(3n+1):last-child {
    background-color: green;
}

看到这里我才知道原来伪类是可以叠加使用的. :nth-child(3n+1):last-child的意思就是选择不仅是每三个的第一个而且是最后一个的li (表达能力有待提高呀...)

伪类叠加使用2

li:nth-child(3n+1):nth-last-child(2), li:nth-child(3n+1):nth-last-child(2) + *{
    width:50%;
    background-color:green;
}

选择不仅是每三个的第一个而且是倒数第二个的li和紧邻它的有相同父元素的li

相邻兄弟选择器使用了加号(+),即相邻兄弟结合符(Adjacent sibling combinator)。 相邻兄弟选择器(Adjacent sibling selector)可选择紧接在另一元素后的元素,且二者有相同父元素。

伪类叠加使用3

伪类叠加使用4

li:nth-last-child(3), li:nth-last-child(3) ~ *{
    width: 33.33%;
    background-color:green;
}

选择倒数第四个的li和它后的有相同父元素的兄弟元素li

相邻兄弟选择器~,选择第一个元素后的兄弟元素,两者拥有相同的父元素

这里要实现的效果就是无论多少列,最后一行的格子都需要把整行给撑满.

原slide用sass写了一个关于这种布局的函数,我用stylus改写一下:

cols = 5

li width (100%/cols) padding-top (100%/cols)

for i in (1..cols) li:nth-child({cols}n+1):nth-last-child({i}) width (100%/i) padding-top (100%/i) & ~ li width (100%/i) padding-top (100%/i)

demo地址

« 返回