自适应内部元素
我们希望 width 可以像 height 一样, 可以自动适应内容的宽度。假如有如下结构:
<p>Lorem ipsum dolor ...</p>
<figure>
<img src="./image/flower.jpg">
<figcaption>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</figcaption>
</figure>
<p>Lorem ipsum dolor sit...</p>
我们希望 figure 元素跟它所包含的图片一样宽(图片尺寸不固定),而且水平居中。而我们能想到的解决方案,如让 figure 元素浮动,或者使 figure 的父元素 text-aligin:center、再对所有子元素都设置 text-align:left。这些方法都不是特别理想。
css3中为 width 和 height 又增加了一些新的关键字,如min-content
,它能使容器的宽度为内部最大的不可断行元素的宽度。
figure{
max-width: 300px; /*回退方案*/
max-width: min-content;
margin: auto;
}
figure>img{
max-width: inherit;
}
根据兄弟元素的数量来设置样式
知识点:伪类选择器
只有一个列表项::only-child
等效于 :first-child:last-child
一个正好有四个列表项的列表中的第一个列表项: :first-child:nth-last-child(4)
ul>li{
display: inline-block;
padding: .5em 1em;
border-radius: .5em;
background: pink;
color: white;
}
li:first-child:nth-last-child(4){
background: deeppink;
}
它之后的所有兄弟元素: :first-child:nth-last-child(4)~li
li:first-child:nth-last-child(4) ~ li{
background: deeppink;
}
因此,有且只有四个列表项的情况就可以表示为:
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li{
background: deeppink;
}
如果列表项不是四个,则没有被选中。
根据兄弟元素的数量范围来匹配元素
:nth-child()
中的参数不仅可以是具体数字,也可以是an+b
这样的表达式,其中 n 的范围是0到正无穷。
例如:n+4
表示选中从第 4 个开始的所有子元素。(注意: 写成 4+n
是不对的)
选中总数是4或是更多时选中所有列表项:
li:first-child:nth-last-child(n+4),
li:first-child:nth-last-child(n+4) ~ li{
background: deeppink;
}
参数是-n+4
可以选中开头的4个元素
li:nth-child(-n+4){
background: deeppink;
}
仅当列表中有4个或更少的列表项时,选中所有的列表项:
li:first-child:nth-last-child(-n+4),
li:first-child:nth-last-child(-n+4) ~ li{
background: deeppink;
}
两种技巧混合,可以表示当列表项有2~6个时,选中所有列表项。
li:first-child:nth-last-child(n+2):nth-last-child(-n+6),
li:first-child:nth-last-child(n+2):nth-last-child(-n+6) ~ li{
background: deeppink;
}
满幅的背景,定宽的内容
要实现一个背景占据整个视口,而内容固定宽度,居中布局。如:
一般的解决方案是为每个区块准备两层元素,分别为其设置样式:
<footer>
<div class="wrapper">
Lorem ipsum dolor ...
</div>
</footer>
footer{
background: #333;
color: white;
border: 1px solid #333;/*这一行是为了不让父元素和子元素的margin重叠(父元素margin为0,子元素为1em,重叠以长的为准,即为1em,背景默认background-clip为border-box,margin下面就会没有背景颜色。)*/
}
.wrapper{
max-width: 900px;
margin: 1em auto;
}
CSS3中增加了一个calc()
函数,上面代码中的 margin 的 auto 可以替换为 calc(50%-450px)
,这是一个长度值,因此可以作为父元素的 padding 值,代码可以改为:
footer{
background: #333;
color: white;
/*border: 1px solid #333;*//*没有margin重叠问题,也就不需要这一行*/
padding: 1em calc(50% - 450px);
}
.wrapper{
/*max-width: 900px;*/
/*margin: 1em auto;*/
}
因此,最终我们不再需要一个额外的元素:
footer{
background: #333;
color: white;
padding: 1em; /*回退方案*/
padding: 1em calc(50% - 450px); /*注意:calc中减号两边须有空格*/
}
垂直居中
仅水平居中很简单:
/*针对行内元素*/
text-align: center;
/*针对块级元素*/
margin: auto;
如下结构:
<main>
<h1>Am I centered yet?</h1>
<p>Center me, please!</p>
</main>
基于绝对定位的解决方案
这个方案的前提是元素必须有固定的宽度和高度:
main{
position: absolute;
top: 50%;
left: 50%;
margin-top: -5em;
margin-left: -10em;
width: 20em;
height: 10em;
}
如果一般的块级元素,且父元素不是 <body>, 还需要对父元素进行相对定位。
借助calc()
函数,就可以省掉两行
main{
position: absolute;
top: calc(50% - 5em);
left: calc(50% - 10em);
width: 20em;
height: 10em;
}
由于translate()
函数中的百分比值是相对于自身的宽高计算的,所以可以解决固定宽高的问题:
main{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
基于视口单位的解决方案
如果使用 margin 的百分比值和 auto 关键字设置垂直水平居中,得到的效果可能并不是我们想要的:
main{
width: 20em;
margin: 50% auto 0;
transform: translateY(-50%);
}
那是因为 margin 的百分比值是以父元素的宽作为基准的,即使对 margin-top 和 margin-bottom 也是这样。
如果只是想针对视口居中,可以使用视口单位解决。
1vw 表示视口宽度的 1%
1vh 表示视口高度的 1%
1vmin 表示视口宽高较小的那个(1vw 或 1vh)
1vmax 表示视口宽高较大的那个(1vw 或 1vh)
main{
width: 20em;
margin: 50vh auto 0;
transform: translateY(-50%);
}
基于Flexbox 的解决方案
body{
display: flex;
}
main{
margin: auto;
}
当我们使用 Flexbox 时,margin:auto 不仅在水平方向上将元素居中,垂直方向上也是如此。
也可以这么写:
body{
display: flex;
justify-content: center;
align-items: center;
}
使用这种方法,还可以将匿名容器垂直居中,如没有被标签包裹的文本节点:
<main>Center me, please!</mian>
mian{
display: flex;
justify-content: center;
align-items: center;
width: 20em;
height: 15em;
}
紧贴底部的页脚
我们会遇到这样的问题,当页面内容不够长时,会出现页脚不能紧贴在最底部,而是紧跟在内容的下方。如下图:
固定高度的解决方案
如果页脚和页头的高度固定,首先我们计算出页脚和页头的高度,分别是7em和2.5em。
mian{
min-height: calc(100vh - 7em - 2.5em);
box-sizing: border-box; /*避免内边距或边框搞乱高度的计算*/
}
就OK了。
或者用一个额外的元素包裹住 <header> 和 <main> 元素:
#wrapper {
min-height: calc(100vh - 7em);
}
Flexbox解决方案
将 body 设置为flex,main 设置为可伸长。
body{
display: flex;
flex-flow: column;
min-height: 100vh;
}
main{
flex: 1;
}
搞定~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。