咱们但愿 width 能够像 height 同样, 能够自动适应内容的宽度。假若有以下结构:css
<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
css3中为 width 和 height 又增长了一些新的关键字,如min-content
,它能使容器的宽度为内部最大的不可断行元素的宽度。app
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
flex
li:first-child:nth-last-child(4) ~ li{ background: deeppink; }
所以,有且只有四个列表项的状况就能够表示为:spa
li:first-child:nth-last-child(4), li:first-child:nth-last-child(4) ~ li{ background: deeppink; }
若是列表项不是四个,则没有被选中。code
:nth-child()
中的参数不只能够是具体数字,也能够是an+b
这样的表达式,其中 n 的范围是0到正无穷。
例如:n+4
表示选中从第 4 个开始的全部子元素。(注意: 写成 4+n
是不对的)orm
选中总数是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%); }
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); }
将 body 设置为flex,main 设置为可伸长。
body{ display: flex; flex-flow: column; min-height: 100vh; } main{ flex: 1; }
搞定~