我想你天天写css代码有时候也会以为很痛苦:这个布局的css怎么这么难实现!我也常常会有这种感受,一个看似简单的布局老是要琢磨半天才能实现,偶尔还会出现一些怪异的超出理解的现象。这是由于咱们对css只是大概知道个形,并无看透css的本质。在同事的推荐下我阅读了张鑫旭老师的《css世界》,才发现css跟想象中的不太同样。本文为《css世界》我的总结笔记,为缩减篇幅丢弃了张老师冗余的小幽默,丢掉了些含金量较低的章节内容,由于ie已经被淘汰出局,因此有关css兼容性的地方也所有忽略不记,同时对我的以为不易理解的地方加上了一些本身的理解和验证,因此错误之处还望指正。顺便推荐个好用的在线代码编辑工具,国内镜像站点,方便各位对本文实例进行测试。另外本文会随着做者对css的更深刻理解而逐步更新,但愿到最后可以文如标题展示出真正的css世界。css
这些基本概念有些可能不易理解但却都很重要,若是看完仍是很不理解的话须要本身谷歌或百度,网上关于这些概念的文章很多。html
“流”又叫文档流,是css的一种基本定位和布局机制。流是html的一种抽象概念,暗喻这种排列布局方式好像水流同样天然自动。“流体布局”是html默认的布局机制,如你写的html不用css,默认自上而下(块级元素如div
)从左到右(内联元素如span
)堆砌的布局方式。前端
这个你们确定都知道。css3
块级元素是指单独撑满一行的元素,如div、ul、li、table、p、h1
等元素。这些元素的display值默认是block、table、list-item
等。git
内联元素又叫行内元素,指只占据它对应标签的边框所包含的空间的元素,这些元素若是父元素宽度足够则并排在一行显示的,如span、a、em、i、img、td
等。这些元素的display值默认是inline、inline-block、inline-table、table-cell
等。github
实际开发中,咱们常常把display
计算值为inline
inline-block
inline-table
table-cell
的元素叫作内联元素,而把display
计算值为block
的元素叫作块级元素。web
width
、height
的默认值都是auto
。面试
对于块级元素,流体布局之下width: auto
自适应撑满父元素宽度。这里的撑满并不一样于width: 100%
的固定宽度,而是像水同样可以根据margin
不一样而自适应父元素的宽度。segmentfault
对于内联元素,width: auto
则呈现出包裹性,即由子元素的宽度决定。浏览器
不管内联元素仍是块级元素,height: auto
都是呈现包裹性,即高度由子级元素撑开。
注意父元素height: auto
会致使子元素height: 100%
百分比失效。
css的属性很是有意思,正常流下,若是块级元素的width
是个固定值,margin
是auto
,则margin
会撑满剩下的空间;若是margin
是固定值,width
是auto
,则width
会撑满剩下的空间。这就是流体布局的根本所在。
外在盒子是决定元素排列方式的盒子,即决定盒子具备块级特性仍是内联特性的盒子。外在盒子负责结构布局。
内在盒子是决定元素内部一些属性是否生效的盒子。内在盒子负责内容显示。
如 display: inline-table;
外在盒子就是inline
,内在盒子就是table
。外在盒子决定了元素要像内联元素同样并排在一排显示,内在盒子则决定了元素能够设置宽高、垂直方向的margin等属性。以下图
右侧的table和左侧的文字在一行排列(外在盒子inline的表现特征),同时有拥有自定义宽度111px(内在盒子table能够设置宽高)。
!important
曾经有道面试题把我难住了:
// 假设下面样式都做用于同一个节点元素`span`,判断下面哪一个样式会生效
body#god div.dad span.son {width: 200px;}
body#god span#test {width: 250px;}
复制代码
可怜当时作了三年前端的我居然还不知道css有权重😓
css选择器权重列表以下:
权重值 | 选择器 |
---|---|
1,0,0,0 | 内联样式:style="" |
0,1,0,0 | ID选择器:#idName{...} |
0,0,1,0 | 类、伪类、属性选择器:.className{...} / :hover{...} / [type="text"] ={...} |
0,0,0,1 | 标签、伪元素选择器:div{...} / :after{...} |
0,0,0,0 | 通用选择器(*)、子选择器(>)、相邻选择器(+)、同胞选择器(~) |
之前想固然的觉得权重是十进制的,即十个class选择器等于一个id选择器,这是错误的。CSS权重进制在IE6为256,后来扩大到了65536,而现代浏览器则采用更大的数量。因此咱们能够忽略进制的问题,从高往低比较权重值。
若是权重是十进制的比较方式,则十一个class选择器的权重高于一个ID选择器。但经测试并不是如此:地址。
能够看到十一个class选择器的样式并无覆盖一个id选择器的样式,由于:
当两个权值进行比较的时候,是从高到低逐级将等级位上的权重值来进行比较的,而不是 1000个数 + 100个数 + 10个数 + 1个数 的总和来进行比较的,换句话说,低等级的选择器个数再多也不会超太高等级的选择器的优先级的。
正确规则:
所以上面那道的面试题比较应该是在第二等级id选择器的比较就结束了:(#god + #test = 0,2,0,0) > (#god = 0,1,0,0);而上图种例子中两个权重分别是:(#test = 0,1,0,0) > (.test....test10 = 0,0,11,0),也是在第二等级id选择器的比较时就结束了。因此之后比较权重,就先比较id选择器个数,若是id同样多,再比较class选择器个数。哇,感受这能够是一道专坑中文社区的面试题啊。
在css中,!important
的权重至关的高。若是出现了!important
,则无论权重如何都取有!important
的属性值。可是宽高有例外状况,因为宽高会被max-width
/min-width
覆盖,因此!important
会失效。
width: 100px!important;
min-width: 200px;
复制代码
上面代码计算以后会被引擎解析成:
width: 200px;
复制代码
元素的内在盒子是由margin box
、border box
、padding box
、content box
组成的,这四个盒子由外到内构成了盒模型。
IE模型: box-sizing: border-box
此模式下,元素的宽度计算为border+padding+content
的宽度总和。
w3c标准模型): box-sizing: content-box
此模式下,元素的宽度计算为content
的宽度。
因为content-box
在计算宽度的时候不包含border pading
很烦人,并且又是默认值,业内通常采用如下代码重置样式:
:root {
box-sizing: border-box;
}
* {
box-sizing: inherit;
}
复制代码
内联元素是指外在盒子是内联盒子的元素。从表现来讲,内联元素的典型特征就是能够和文字在一行显示。文字也是内联元素。图片、按钮、输入框、下拉框等替换元素也是内联元素。内联盒模型是指内联元素包含的几个盒子,理解记忆下面的几个概念对css的深刻学习极其重要。
div
标签,则不会造成行框盒子。行框盒子由一个个内联盒子组成,若是换行,那就是两个行框盒子。好比一个包含了不少字符的换行的的p
标签,每一行都存在一个行框盒子。值得注意的是,若是给元素设置display: inline-block
,则建立了一个独立的行框盒子。line-height
是做用在行框盒子上的,并最终决定高度。替换元素是指内容能够替换的元素,实际上就是content box
能够被替换的元素。如存在src=""
属性的<img> <audio> <video> <iframe>
元素和能够输入文本的<input> <select> <textarea>
元素等。
全部替换元素都是内联元素,默认display
属性是inline
或inline-block
(除了input[type="hidden"]
默认display: none;
)。
替换元素有本身默认的样式、尺寸(根据浏览器不一样而不一样),并且其vertical-align
属性默认是bottom
(非替换元素默认值是baseline
)。
对于非替换元素如div
,其content
就是div内部的元素。 而对于替换元素,其content
就是可替换部分的内容。
CSS中的content
属性主要用于伪元素:before/:after
中,除了作字体库或少写个div,对于通常开发来讲并没有卵用。
padding
是四大金刚中最稳定的了,少见有什么异常。尽管如此仍是有些须要注意的地方:
box-sizing: border-box
,宽高的计算是包含了padding
的,给人一种padding
也是content box
一部分的感受,好像line-height
属性也做用于padding
上。但实际上,元素真正的内容的宽高只是content box
的宽高,而line-height
属性是不做用于padding
的。padding
不可为负值,可是能够为百分比值。为百分比时水平和垂直方向的padding
都是相对于父级元素宽度计算的。将一个div
设为padding: 100%
就能获得一个正方形,padding: 10% 50%
能够获得一个宽高比 5:1 的矩形。body {
width: 400px;
}
.box {
padding: 10% 50%;
}
复制代码
padding
配合background-clip
属性,能够制做一些特殊形状:/*三道杠*/
.icon1 {
box-sizing: border-box;
display: inline-block;
width: 12px;
height: 10px;
padding: 2px 0;
border-top: 2px solid currentColor;
border-bottom: 2px solid currentColor;
background: currentColor; /*注意若是此处背景颜色属性用缩写的话,须要放到其余背景属性的前面,不然会覆盖前面的属性值(此处为background-clip)为默认值*/
background-clip: content-box;
}
/*双层圆点*/
.icon2 {
display: inline-block;
width: 12px;
height: 12px;
padding: 2px;
border: 2px solid currentColor;
border-radius: 50%;
background-color: currentColor;
background-clip: content-box;
}
复制代码
预览以下:(currentColor是css中为数很少的变量,指当前文字的颜色值,很是好用)
margin
属性并不会参与盒子宽度的计算,但经过设置margin
为负值,却能改变元素水平方向的尺寸:<div>asdf</div>
<style> div { margin: 0 -100px; } </style>
复制代码
此时div
元素的宽度是比父级元素的宽度大200px
的。可是这种状况只会发生在元素是流布局的时候,即元素width
是默认的auto
而且能够撑满一行的时候。若是元素设定了宽度,或者元素设置了float: left
/ position: absolute
这样的属性改变了流体布局,那么margin
为负也没法改变元素的宽度了。
margin
合并,存在如下三种场景:margin
合并;margin-top
和子元素margin-top
,父元素margin-bottom
和子元素margin-bottom
;margin-top
和margin-botom
合并,例子以下。要阻止margin
合并,能够:1. 把元素放到bfc
中;2. 设置border
或padding
阻隔margin
;3. 用内联元素(如文字)阻隔;4. 给父元素设定高度。
margin
的百分比值跟padding
同样,垂直方向的margin
和水平方向上的同样都是相对于父元素宽度计算的。<div class="box">
<div></div>
</div>
<style> .box{ overflow: hidden; background-color: lightblue; } .box > div{ margin: 50%; } </style>
复制代码
此时 .box 是一个宽高比 2:1 的矩形,由于空块级元素自身的垂直方向的margin
发生了合并。
这里父元素设置overflow: hidden
是利用 bfc
的特性阻止子元素的margin
和父元素合并,换成其余 bfc
特性或者设置 1px
的 border
/ padding
都是能够达到效果的。
margin: auto
能在块级元素设定宽高以后自动填充剩余宽高。margin: auto
自动填充触发的前提条件是元素在对应的水平或垂直方向具备自动填充特性,显然默认状况下块级元素的高度是不具有这个条件的。典型应用是块级元素水平局中的实现:display: block;
width: 200px;
margin: 0 auto;
复制代码
auto
的特性是,若是两侧都是auto
,则两侧均分剩余宽度;若是一侧margin
是固定的,另外一侧是auto
,则这一侧auto
为剩余宽度。栗子:
这个特性不为人知,且很实用。
除了水平方向,垂直方向的margin
也能实现垂直居中,可是须要元素在垂直方向具备自动填充特性,而这个特性能够利用position
实现:
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
width: 200px;
height: 200px;
margin: auto;
复制代码
border
主要做用是作边框。border-style
属性的值有none/solid/dashed/dotted/double
等,基本看名字就能猜出什么来了:
border-width
属性的默认值是3px
,是为了照顾小弟border-style: double
,你懂的。值得注意的是,border-color
默认是跟随字体的颜色,至关于默认设置了border-color: currentColor
同样。
border
另外一广受欢迎的功能就是图形构建,特别是作应用普遍的三角形,其原理可看下图的1-3:
div{
float: left;
margin: 20px;
}
div:nth-child(1){
width: 20px;
height: 20px;
border: 20px solid;
border-color: blue red orange green;
}
div:nth-child(2){
width: 20px;
height: 20px;
border: 20px solid;
border-color: blue transparent transparent transparent;
}
div:nth-child(3){
border: 20px solid;
border-color: blue transparent transparent transparent;
}
div:nth-child(4){
border-style: solid;
border-width: 40px 20px;
border-color: blue transparent transparent transparent;
}
div:nth-child(5){
border-style: solid;
border-width: 40px 20px;
border-color: blue red transparent transparent;
}
复制代码
其实就是将其余三个边框的颜色设置透明,并把宽高设为 0 。图中4-5两个图形,是经过调整边框宽度和颜色调整三角形的形状,把最后一个图的红色改成蓝色,则是一个直角三角形了。
line-height
和vertical-align
line-height
和vertical-align
是控制元素垂直对齐的两大属性,也是最难理解搞懂的属性。
在内联元素的垂直方向对齐中,基线是最为重要的概念。line-height
定义的就是两基线之间的距离,vertical-align
的默认值就是基线。基线的定义则是字母 x 的下边缘。
css中有个概念叫x-height
,指的是小写字母 x 的高度。vertical-align: middle
对齐的就是基线往上1/2x-height
高度的地方,能够理解为近似字母 x 的交叉点。
css中除了px/em/rem
等,还有个单位是ex
。指的就是小写字母x的高度,即x-height
。用处不大,再也不介绍。
line-height
各种属性值normal
: 默认值normal
实际上是类型为数值的变量,根据浏览器和字体'font-family'不一样而不一样,通常约为 1.2 。
数值和百分比:最终会被计算为带单位的值,具体计算方法就是乘以字体大小font-size
。
长度值:就是100px
这样带单位的值。
这几类值的继承特性不一样:line-height
是数值的元素的子元素继承的就是这个数值,百分比/长度值继承的都是计算后得出的带单位的值(px)。
line-height
的做用:line-height
属性用于设置多行元素的空间量,如多行文本的间距。
对块级元素来讲,line-height
决定了行框盒子的最小高度。注意是行框盒子的最小高度,而不是块级元素的实际高度。(图中两个div
行高同样,div.one
的背景色区域就是行框盒子的高度,而 div.two
的背景区域则是实际高度,其行框盒子高度和 div.one
是同样的。)
对于非替代的 inline 元素,它用于计算行框盒子的高度。此时内联元素的行框盒子的高度彻底由line-height
决定,不受其余任何属性的影响。
line-height
实现垂直居中的本质:行距行距是指一行文本和相邻文本之间的距离。行距 = line-height
— font-size
。行距具备上下等分的机制:意思就是文字上下的行距是同样的,各占一半,这也是line-height
能让内联元素垂直居中的缘由。下图中字母x上下行距各占一半,共同撑起了div
。
下图中和上图惟一不一样之处就是多了个display: inline-block
的span
元素,可是此处的span
元素并无影响div
元素的高度,而只是靠着vertical-align: middle
属性将自身中心点对齐了字母x的交叉点实现垂直居中而已。div
元素的高度仍然和上图如出一辙,由字母x和行距共同撑起。此时若是删除字母x,div
的高度不变,由于span
元素的行框盒子前会产生幽灵空白节点,而幽灵空白节点+行高也能撑起div
。
<div class="box">
<span>asdf</span>
</div>
复制代码
样式1:此时 .box 高度是多少?
.box {
line-height: 100px;
background: lightgreen;
}
.box span {
line-height: 30px;
}
复制代码
样式2:此时 .box 高度是多少?
.box {
line-height: 30px;
background: lightgreen;
}
.box span {
line-height: 100px;
}
复制代码
先说结论:不管内联元素的line-height
如何设置,最终父元素的高度都是数值大的那个line-height
决定的。
样式1中,span
元素的行框盒子前存在一个幽灵空白节点,而这个幽灵空白节点的行高是100px;样式2中,幽灵空白节点的行高是30px,可是这时span元素的行高是100px。两种状况其实同样,取大值而已。
vertical-align
的属性值线类: 如baseline(默认值)
top
middle
bottom
(baseline
使元素的基线与父元素的基线对齐,middle
使元素的中部与父元素的基线往上x-height
的一半对齐。top
bottom
使元素及其后代元素的底部与整行或整块的底部对齐。)
文本类: text-top
text-bottom
(使元素的顶部与父元素的字体顶部对齐。)
上标下标: sub
super
(使元素的基线与父元素的下标基线对齐。)
数值: 20px
2em
(默认值baseline
至关于数值的 0 。使元素的基线对齐到父元素的基线之上的给定长度,数值正值是基线往上偏移,负值是往下偏移,借此能够实现元素垂直方向精确对齐。)
百分比: 20%
(使元素的基线对齐到父元素的基线之上的给定百分比,该百分比是line-height属性的百分比。)
vertical-align
的做用前提vertical-align属性起做用的前提必须是做用在内联元素上。 即display
计算值为inline
inline-block
inline-table
table-cell
的元素。因此若是元素设置了float: left
或者position: absolute
,则其vertical-align
属性不能生效,由于此时元素的display
计算值为block
了。
line-height
、vertical-align
和第三者幽灵空白节点的爱恨情仇有时候会碰见下面这样高度和设置不一致的状况:
div
的实际高度比设定的行高大了,为何呢?
内联元素的默认对齐方式是baseline
,因此此时此时span
元素的基线是和父元素的基线相对齐的,而此时父元素的基线在哪呢?
父元素的基线其实就是行框盒子前的幽灵空白节点的基线。把幽灵空白节点具象化为字母x
可能容易理解些:
因为div
行高是30px
,因此字母x
和span
元素的高度都是30px
。可是字母x的font-size
较小,span
元素的font-size
较大,而行高同样的状况下font-size
越大基线的位置越偏下,因此二者的基线不在同一水平线上。以下图左边部分:
因为内联元素默认基线对齐,因此字母x
和span
元素发生了位移以使基线对齐,致使div
高度变大。而此时字母x
的半行距比span
元素的半行距大,大出的部分就是div
的高度增长的部分。
display: inline-block
基线的不一样之处先看例子,图中span
元素设置了display: inline-block
和宽高,从而撑起了父元素div
的高度,但span
自己并没有margin
属性,那为何底部和div
下边缘之间会有空隙呢?地址
这就要说到inline-block
的不一样之处了。一个设置了display: inline-block
的元素:
overflow
为hidden auto scroll
,则其基线就是该元素下边缘;知道了这点,那么再回到上面的例子:
原来是第三者幽灵空白节点搞的鬼。此时span
的行框盒子前,还存在一个幽灵空白节点。因为span
元素默认基线对齐,因此span
元素的基线也就是其下边缘是和幽灵空白节点的基线对齐的。从而致使幽灵空白节点基线下面的半行距撑高了div
元素,形成空隙。以下图:
若是span
元素中存在内联元素呢?
能够看到,此时span
元素下边缘的空隙没了,由于此时span
元素的基线是内部最后一行内联元素的基线。
值得一提的是,因为替换元素内部不可能再有别的元素,因此其基线位置永远位于下边缘。
间隙产生本质上是由基线对齐引起的错位形成的,源头上是vertical-align
和line-height
共同形成的,因此要想解决这个问题,只要直接或间接改造两个属性中的一个就好了:
display: block
使vertical-align
属性失效;vertical-align
值如bottom/middle/top
;line-height
值;line-height
为相对值如1.4
,设置font-size: 0
间接改变line-height
。下面是张鑫旭大佬推荐的利用vertical-align
实现的水平垂直居中弹框,可以理解的话就说明你已经彻底掌握了好基友和第三者的关系了。
<div class="container">
<div class="dialog">自适应弹出层</div>
</div>
<style> .container{ position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 0, 0, .15); text-align: center; font-size: 0; white-space: nowrap; overflow: auto; } .container:after{ content: ''; display: inline-block; height: 100%; vertical-align: middle; } .dialog{ display: inline-block; width: 400px; height: 400px; vertical-align: middle; text-align: left; font-size: 14px; white-space: normal; background: white; } </style>
复制代码
如今UI框架横行的年代,咱们的css写的愈来愈少了。这对于不少老鸟来讲是件好事,可是对于初入前端的小白却未必。由于写的少了,就少了不少练手和总结的机会,对于不少样式理解就不透彻。本章介绍的float
、position
和BFC
对于前端页面布局很是重要,但愿诸位看官们静下心来仔细研读。
float
属性的特性float
属性应该是css世界最使人意外的属性了,倒不是由于他的表现,而是他的设计初衷居然只是为了实现“文字环绕图片”的效果。只不过由于float
属性的一些特性,才致使其被处处使用以至于产生了诸多不利于维护的页面。 下面看看float
属性的特性:
width
会像height
同样由子元素决定,而不是默认撑满父元素。float: left
以后,其display
的计算值就成了block
。格式化上下文是指会建立一个BFC,这个后面会讲。margin
合并;float
设计的初衷就是为了“文字环绕”效果,为了让文字环绕图片,就须要具有两个条件。第一是元素高度坍塌,第二是行框盒子不可与浮动元素重叠。而元素高度坍塌就致使元素后面的非浮动块状元素会和其重叠,因而他就像脱离文档流了。前三个特性都是正能量满满,可是最后一个特性却给咱们开发者带来了不少麻烦,须要用到clear
来清除浮动。
clear
的做用和不足你们都知道clear: both
能够清除前面浮动元素的浮动,但实际上,他并非真的清除了浮动。
clear
的定义是:元素盒子的边不能与前面的浮动元素相邻。也就是虽然浮动元素高度坍塌,可是设置了clear: both
的元素却将其高度视为仍然占据位置。
clear
只能做用于块级元素,而且其并不能解决后面元素可能发生的文字环绕问题。
BFC是一个独立的渲染区域,只有Block-level box
参与, 它规定了内部的Block-level Box
如何布局,而且与这个区域外部绝不相干。 BFC 就好像一个结界,结界里面的东西不能影响外面的布局,也就是说,BFC的子元素再翻江倒海,都不会影响外面的元素。 因此:
margin
重叠。float
不为none
的元素);position
为absolute
或fixed
);inline-blocks
(元素的 display: inline-block
);display: table-cell
,HTML
表格单元格默认属性);overflow
的值不为visible
的元素;flex boxes
(元素的display: flex
或inline-flex
);BFC包含建立该上下文元素的全部子元素,但不包括建立了新BFC的子元素的内部元素。
margin
决定。属于同一个BFC的两个相邻Box的margin
会发生重叠;float box
重叠;乍一看还挺多的,但真正要注意并用心理解的只有 3 4 6 。
特性 1 中内部的盒是指块级盒。由于<html>
根元素也是BFC,因此咱们日常写的div p
都是独自占一行。
特性 2 <html>
是BFC,因此里面的元素垂直方向的margin
会发生折叠。可是,直接子孙元素与该BFC上下边界margin
不能折叠,保证了BFC内部的元素不会影响外部的元素。两个上下相邻的BFC之间折不折叠要看具体状况,如display: inline-block
float: left
不会折叠,而overflow: hidden
则会折叠。
特性 3 彻底解读:
In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box's line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
网上不少翻译成“每一个元素的margin box
的左边, 与包含块border box
的左边相接触”的,这样的翻译是不许确甚至错误的,曾给我形成莫大的困惑和迷茫(这翻译太坑爹了一度让我怀疑人生)。正确的翻译是“每个盒子的左外边距应该和包含块的左边缘相接触”。
第一,包含块未必就是父级元素。对于position: absolute
来讲,包含块是指第一个positoin
不为static
的祖先元素。
第二,BFC中的盒子应该与其自身的包含块相接触,而非与BFC盒子自己相接触。
第三,BFC中的盒子是与其包含块的 left edge
相接触,而不是包含块的 left-border
相接触。left edge
正确的翻译为左边缘。左边缘多是content box
的左边缘(非绝对定位如position: relative
float: left
),也多是padding box
的左边缘(如绝对定位position: absolute
position: fixed
)。
理解了上面三点,其实特性 3 就是普通的流布局和定位布局默认贴着“左侧”思想的总结。
如图,aside
元素的margin box
的左边距和BFC元素的左边缘相接触。而且因为float box
高度坍塌,main
占据了body
所有空间而且和包含块BFC盒子左边缘相接触(特性3“即便存在浮动也是如此”)。
特性 4 正是BFC存在的意义。它规定了BFC子元素不管margin-top: -10000px
float: left
等都不会影响到BFC外部的元素的布局。因此BFC是最好的清除浮动的方式,连浮动的文字环绕问题都能解决。
特性 5 BFC计算高度时包含浮动元素的高度。能够利用BFC此特性解决浮动元素高度坍塌的问题。
特性 6 实现自适应两栏布局。此时main
宽度是自适应的。
除了 BFC ,还有 IFC GFC FFC 等布局,了解便可,想看点 这里。
position: absolute
和浮动元素同样,绝对定位也具备块状化、BFC、包裹性、脱离文档流、没有margin
合并的特性。
但和浮动不一样的是,绝对定位是彻底的脱离文档流。你们还记得浮动产生的目的就是为了实现文字环绕效果,因此浮动元素虽然脱离了文档流,可是后面的文字仍是会环绕在浮动元素周围。而绝对定位一但产生,就不会再对周围元素产生任何影响。
并且二者包含块不一样,浮动元素包含块只能是父级元素,绝对定位的包含块则是距离最近的position
不为static
的祖先元素。
大多数用到绝对定位的时候,都是存在包含块和left/top
等方向属性的。但其实position: absolute
是很是独立的css属性,其样式和行为表现不依赖任何css属性就能够完成。
能够看出,无依赖的position: absolute
元素定位的位置和其自己无定位属性时候的位置和display
的值有关。若是元素在没有position
的状况下是内联元素,则和内联元素在同一行显示;若是元素在没有position
属性的状况下是块级元素,则换行显示。
无依赖绝对定位的实用性虽然还行,可是其功能却彻底能够用left/top
实现。因此了解便可,若是有兴趣能够自行尝试。
overflow: hidden
其实一句话就能够表示二者之间的关系:当overflow: hidden
元素在绝对定位元素和其包含块之间的时候,绝对定位元素不会被剪裁。
如下两种绝对定位元素不会被剪裁:
<div style="overflow: hidden;">
<img src="big.jpg" style="position: absolute;">
</div>
<div style="position: relative;">
<div style="overflow: hidden;">
<img src="big.jpg" style="position: absolute;">
</div>
</div>
复制代码
如下两种绝对定位元素会被剪裁:
<div style="overflow: hidden; position: relative;">
<img src="big.jpg" style="position: absolute;">
</div>
<div style="overflow: hidden;">
<div style="position: relative;">
<img src="big.jpg" style="position: absolute;">
</div>
</div>
复制代码
position: absolute
的流体特性当绝对定位元素的水平方向(left/right
)或垂直方向(top/bottom
)的两个定位属性同时存在的时候,绝对元素在该方向上便具备了流体特性。此时的width/height
属性具备自动撑满的特性,和一个正常流的div
元素的width
属性别无二致。如图,设置了固定margin
值的元素,宽高auto
可以自动适应剩余空间:
一样的,设置了固定宽高的元素,若是margin: auto
,则margin
平分剩余空间致使垂直水平居中:
层叠规则是指当网页中的元素发生层叠时侯的遵循的规则。
层叠上下文好像是一个结界,层叠上下文内的元素若是跟层叠上下文外的元素发生层叠,则比较该层叠上下文和外部元素的层叠上下文的层叠水平高低。
建立一个层叠上下文的方法就是给position
值为relative/aboslute/fixed
的元素设置z-index
不为auto
的值。
层叠上下文内元素的层叠水平以下图:
border/background
是指当前层叠上下文元素的边框和背景色。z-index
为负值的元素在其之上。以下图所示.dad
元素默认设置z-index: auto
,没有建立层叠上下文,此时其就是一个普通的块级盒子,因此设置了z-index: -1
的.son
元素跑到了爸爸身后看不见了。
而因为.mom
设置了z-index: 0
,建立出了一个层叠上下文,因此.son
元素就算设置了z-index: -1
也跑不出老妈的视线。地址
z-index
为auto
的定位元素。下图span
就是普通定位元素:地址CSS3带来了不少新属性,其中很不惹人注意的一点就是增长了不少会自动建立层叠上下文的属性:
opacity
值不为1
,也就是透明元素;transform
值不为none
;filter
值不为none
;-webkit-overflow-scrolling: touch
;z-index
不为auto
的弹性盒子的子元素;isolation
值为isolate
;mix-blend-mode
值不为normal
;will-change
值为opacity/transform/filter/isolation/mix-blend-mode
中的一个。这些属性大都不支持z-index
,因此他们都默认z-index: auto
,跟普通定位元素层叠水平同样,因此若是发生层叠会后来居上:地址
可是弹性盒子display: flex
不一样,弹性盒子的子元素支持设置z-index
,且设置了数值的z-index
也会自动建立层叠上下文。以下图,能够看到设置了z-index: 0
的元素层叠水平更高。地址
如下css属性为文本相关。
::first-letter
应用实例::first-letter
选中首个字符:地址
text-transform
应用假设有个输入框只能输入大写字母,那么以下设置,输入小写字母出现的倒是大写字母,可用于身份证输入框或验证码输入框等:
input {
text-transform: uppercase;
}
复制代码
word-spacing
空格间隙不要被表面意思误导,word-spacing
指的是字符“空格”的间隙。若是一段文字中没有空格,则该属性无效。下面代码设定空格间隙是20px
,也就是说空格如今占据的宽度是原有的空格宽度+20px
的宽度:
<p>我有空 格,我该死......</p>
<style> p { word-spacing: 20px; } </style>
复制代码
white-space
空白处理咱们都知道若是在html
中输入多个空白符,默认会被当成一个空白符处理,实际上就是这个属性控制的:地址
text-align: justify
(本文重点例子!)text-align: justify
为两端对齐。除了实现文字的两端对齐,还能用来作一些两端对齐的布局。下面介绍个两端对齐布局的实例:地址
因为text-align: justify
最后一行是左对齐,因此利用了三个空的i
标签模拟最后一行。虽然实现了两端对齐,可是最后一行却出现间隙。根据以前的经验应该是vertical-align
和line-height
搞的鬼,咱们给i
标签加上outline
并用字母 x 模拟幽灵空白节点,现形:地址
上图分析:首先第一个i
标签基线与第二行的span
标签中的数字的基线对其,因此其位置在中间。其次最后一行的i
标签基线对齐幽灵空白节点字母x的基线,没有错位,因此此时最后一行的间隙高度就是字母x的高度。因此很容易想到把幽灵空白节点的行高设为 0 来解决问题:地址
然而间隙虽然缩小了,可是仍是存在。此时因为行高为 0 ,幽灵空白节点也就是字母x在页面中占用的真实位置实际上是红线所示。也就是说虽然字母 x 还显示在页面上,可是其真实高度已经为0,此时其中线、上边缘线、下边缘线合一,都在红线位置,其真实位置天然也就在红线位置。然而其基线却不会改变,在字母 x 下边缘。
此时i
标签的基线发生错位,位移到下面与幽灵空白节点基线对齐,致使产生了间隙。
因此只须要再改变i
标签的对齐方式,就能完全清除间隙:地址
此时i
标签的基线对齐其幽灵空白节点的下边缘线,没有了错位,也就没有了间隙。
若是改成vertical-align: top
是同样的,由于合一了。可是vertical-align: middle
却不行,由于此middle
的位置是基线往上 1/2 个e-height
的地方。
好吧本例结束了,没想到解释起来这么复杂。虽然当下两端对齐布局使用这种方法已通过时了(没 flex 实现起来简单,更没 grid 实现好),可是好好学习这个方法能加深对vertical-align
和line-height
的理解。
元素的显示隐藏方法不少,不一样方法的在不一样的场景下页面效果不一,对页面的性能也有不一样的影响。
display: none
;visibility: hidden
;transition
淡入淡出效果:地址div{
position: absolute;
visibility: hidden;
opacity: 0;
transition: opacity .5s linear;
background: cyan;
}
div.active{
visibility: visible;
opacity: 1;
}
复制代码
这里使用visibility: hidden
而不是display: none
,是由于display: none
会影响css3的transition
过渡效果。 可是display: none
并不会影响cssanimation
动画的效果。
opacity: 0
;opacity: 0; position: absolute;
;position: relative; z-index: -1;
;position: absolute ; z-index: -1;
;display: none
与visibility: hidden
的区别display: none
的元素不占据任何空间,visibility: hidden
的元素空间保留;display: none
会影响css3的transition
过渡效果,visibility: hidden
不会;display: none
隐藏产生重绘 ( repaint ) 和回流 ( relfow ),visibility: hidden
只会触发重绘;(回流重绘知识点参考:真正理解重绘和回流)display: none
的节点和子孙节点元素全都不可见,visibility: hidden
的节点的子孙节点元素能够设置 visibility: visible
显示。visibility: hidden
属性值具备继承性,因此子孙元素默认继承了hidden
而隐藏,可是当子孙元素重置为visibility: visible
就不会被隐藏。若是面试问到这个问题,回答出来这四点应该是极好的。
弹性布局是指display: flex
或display: inline-flex
的布局。注意,设为弹性布局之后,子元素的float、clear、vertical-align
属性都会失效。参见阮一峰大佬的 Flex 布局教程。
主要属性应用以下:
能够看到 .container
容器中加了不少 i
空元素,这是为了模拟项目占位,也是弹性布局实现两端对齐的惟一不足之处~
网格布局是目前最强大的 CSS 布局方案。这里总结了用 Grid 实现的经常使用 css 布局:Grid网格布局实例
css权重和超越!important
章节中权重部分的错误知识;(2019.10.16)弹性布局实现两端对齐尾行左对齐
实例;(2019.10.16)text-align: justify
连接中实例的显示,固定了容器宽度;(2019.10.16)