前言
CSS,对于一个web开发者来说再熟悉不过了,即便是后端也能帮前端开发者调调样式。正是因为它的简单易懂,让很多程序员(包括我自己)觉得不用去花时间系统学习。记得有一次在项目中,按照UI设计图,画了一个很简单的样式,自己觉得百分百没问题;熟话说越是觉得简单的东西越容易出错,果不其然第二天,领导测试后,出现了严重的样式错误,被痛批了一顿。当时的我还觉得自己委屈,明明自己电脑上,旁边同事电脑测试没问题,就他自己电脑上有问题。后来才发现确实是自己布局混乱造成,从那一刻起,我就决定重新去认识下CSS。
注:本篇文章不会将每个点的知识都讲出来,只会列出对于本人来说在没系统学习前不了解的点。
引导
先出两个问题:
下面样式设定,div在浏览器里的实际展示宽度是多少呢?
.div {
width: 100px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
如果在加上一个属性:box-sizing: border-box呢?
2.一段代码
<p><img src="1.jpg"></p>
p{
text-align: center;}img { position: absolute;}
上面显示出来的样式是下面哪一个呢
流特性
流这个概念在很多语言里面都会用到,通常用在文件操作上。在CSS中,对于块状元素默认情况下,会表现出如水流般的行为,填充满整个容器(水平方向上);而行内元素则如同漂浮在水上的一个个木头,填充着每一排。流体布局指的就是利用元素“流”的特性实现各类布局效果,从而达到自适应特性。
盒子
对于元素的盒子模型,对于你来说应该不会陌生,即便是一个空元素也会有盒子模型。实际上从功能上来分,我们还可以将元素分为外在盒子和容器盒子,外在盒子用来体现一行显示或者是换行显示,容器盒子就是我们的盒子模型,容器盒子又可分为块级容器盒子和内联容器盒子。容器盒子再细分可分为:content-box、padding-box、border-box
width
width可以说是我们用的最多的一个常见属性,随便找一个后端人员也会通过这个属性设置元素的宽度。然而如果我们直接在一个行内元素上设置width会有效果吗?
.test {
width: 100px
}
<span class="test">a</span>
答案是否定的,你只会看到,这个元素只有‘a’这个字符的宽度。实际上,with只会对块级容器盒子有效。那么它具体作用在盒子模型的哪部分呢?
默认情况下,with是作用在content部分即content-box,所以元素实际上的宽度是content-box宽度+padding+border。
你可能遇到过这样的问题,一排有多个panel面板,当鼠标移到其中一个面板时,加上border以突出显示,这时可能会出现闪动问题,因为被选中的这个面板其宽度变成了原有宽度加border宽度了,如果之前是刚好排满,此时还可能会导致最后一个面板换行显示。
为了解决这个问题,我们可以通过使用box-sizing来改变with的作用对象,如将box-sizing属性设置成border-box,这时设置with时就包含了content、padding、border了。
width默认值为auto,在正常块级元素上表现为流动性,即占父元素的100%宽度;在absolute,fixed块级元素上默认表现为包裹性,即宽度由内部元素确定,但当元素设置了对位方向值,如top与bottom, left与right时,元素宽度表现为格式化宽度,宽度大小相对于最近的具有定位特性 (position 属性值不是 static)的祖先元素计算。
Height
height相对于width没那么复杂,对于普通文档流中的元素,百分比高度值要想起作用, 其父级必须有一个可以生效的高度值,所以有时候会发现直接设置height:100%会发现没有效果,原因就可能是该元素的直接父急元素没有显示设置height。
绝对定位元素的百分比计算和非绝对定位元素的百分比计算是有区别的,区别 在于绝对定位的宽高百分比计算是相对于 padding box 的,也就是说会把 padding 大小值计算 在内,但是,非绝对定位元素则是相对于 content box 计算的 。
Padding
内联元素的padding也能影响垂直方向布局,影响视觉表现,只是内联元素没有可视宽度和可视高度的说法(clientHeight 和 clientWidth 永远是 0) .此特性可用来增加点击区域。
padding 百分比值无论是水平方向还是垂直方向均是相对于当前父节点宽度计算的!
Margin
提到margin,首先让人想到的就是margin合并现象。合并产生的条件:
1.块级元素,但不包括浮动和绝对定位元素,尽管浮动和绝对定位可以让元素块状化。
2.只发生在当前文档流方向的相垂直的方向上。
合并的方式及解决方法:
1. 相邻兄弟元素 margin 合并
阻止方法:
设置其中一个元素display: inline-block;
使用padding替代;
2. 父级和第一个/最后一个子元素。
阻止父子margin-top合并方法:
父元素设置为块状格式化上下文元素;
父元素设置 border-top 值;
父元素设置 padding-top 值;
父元素和第一个子元素之间添加内联元素进行分隔。
对于 margin-bottom 合并,可以进行如下操作(满足一个条件即可):
父元素设置为块状格式化上下文元素;
父元素设置 border-bottom 值;
父元素设置 padding-bottom 值;
父元素和最后一个子元素之间添加内联元素进行分隔;
父元素设置 height、min-height 或 max-height。
3. 空块级元素的合并
阻止方式:
设置垂直方向的 border;
设置垂直方向的 padding;
里面添加内联元素(直接 Space 键空格是没用的);
设置 height 或者 min-height。
合并计算规则:正正取大,正负相加,负负取小
margin:auto: 对于具有宽度设定的块级元素如果一侧定值,一侧 auto,则 auto 为剩余空间大小;如果两侧均是 auto,则平分剩余空间。触发 margin:auto 计算有一个前提条件,就是 width 或 height 为 auto 时, 元素是具有对应方向的自动填充特性的,所以margin:auto无法对垂直方向有影响(非绝对定位元素而言);
margin 百分比值无论是水平方向还是垂直方向均是相对于当前父节点宽度计算的!
浮动
元素浮动会导致父节点高度坍塌,清除浮动的方式
可以在相邻元素里使用clear: (left/right/both),但此方式只是清除浮动,与撑开父节点高度不是同一个问题,若想撑开父节点高度,就必须让此元素显示在浮动元素下方,或者超出浮动节点高度。Clear属性对内联元素无效,对块级元素有效。
可以将父节点形成BFC
BFC
块格式化上下文(BFC)有下面几个特点:
BFC是就像一道屏障,隔离出了BFC内部和外部,内部和外部区域的渲染相互之间不影响。BFC有自己的一套内部子元素渲染的规则,不影响外部渲染,也不受外部渲染影响。
BFC的区域不会和外部浮动盒子的外边距区域发生叠加。也就是说,外部任何浮动元素区域和BFC区域是泾渭分明的,不可能重叠。
BFC在计算高度的时候,内部浮动元素的高度也要计算在内。也就是说,即使BFC区域内只有一个浮动元素,BFC的高度也不会发生塌缩,高度是大于等于浮动元素的高度的。
HTML结构中,当构建BFC区域的元素紧接着一个浮动盒子时,即,是该浮动盒子的兄弟节点,BFC区域会首先尝试在浮动盒子的旁边渲染,但若宽度不够,就在浮动元素的下方渲染。
形成BFC的方式:
根元素;
float 的值不为 none;
overflow 的值为 auto、scroll 或 hidden;
display 的值为 table-cell、table-caption 和 inline-block 中的任何一个;
position 的值不为 relative 和 static。
幽灵空白节点
在 HTML5 文档模式下,每一个“行框盒子(块级元素与内联元素父子组合)”的前面都有一个宽度为 0 的“幽灵空白节点”,其内联特性表现和普通字符一模一样 ,清除方式可以使用font-size:0.
Vertical-align
除了设置baseline、top、middle、bottom等值以外,还可以设置具体数值和百分比,如:10px,10%;当设置正数时,表现为基线往上,负值基线往下,百分比是相对于line-height计算的。
Vertical-align起作用的前提:只能应用于内联元 素以及 display 值为 table-cell 的元素;对于浮动和绝对定位 元素没有效果。通常vertical-align是和line-height一起使用,如:
.box {
height: 120px;
}
.box > img {
height: 96px;
vertical-align: middle;
}
<div class="box">
<img src="1.jpg"></div>
此时是看不出效果的,因为行框盒子前面的“幽灵空白节点”高度太小,此时在.box里加入line-height:120px,则可生效。如图:
Absolute
绝对定位元素的宽度百分比是相对于第一个 position 不为 static 的祖先元素计算的。计算和定位是相对于祖先定位元素的 padding box;
在元素只设置position:absolute而没有设置方位属性时,其表现方式为无依赖绝对定位,即所在位置与没有设置时相同,只是脱离了文档流。
下图应该很多人(包括我)会这样写代码:
.outer {
position: relative
}
.icon {
position: absolute;
top: 0;
left:0;
}
<div class="outer">
<img class=".icon" src="0.png"/>
<img src="1.png"/>
</div>
其实只需
.icon {
position: absolute;
}
<div>
<img class=".icon" src="0.png"/>
<img src="1.png"/>
</div>
在设置了相对方位时,则该元素在此方位上表现为流体特性;
Relative
relative 的定位有两大特性:一是相对自身;二是无侵入。
相对自身指的是在设置为relative的元素,再设置其方位时,表现出来的效果是相对于自身没有设置方位时的位置,没有脱离文档流。
设置图片
.img{ position: relative; right: 50px; opacity: 0.4;//为了方便观察}
可以看到,图片只是相对它的位置偏移了50px,左右两个相邻元素没有收到任何位置上的影响。
注意,虽然定位位移是相对自身,但是百分比值的计算值时相对于包含块计算的。
对立方向定位值的时候,只有一个方向的定位属性会起作用:根据文档流方式,默认top/bottom 同时使 用的时候,bottom 无效;left/right 同时使用的时候,right无效。
层叠规则
看到这里,是不是第一个想到的就是z-index?确实与z-index有关,但其实z-index只是其中的一小部分。有时候,我们明明在A元素上设定的z-index高与B元素的z-index,但A始终不能覆盖B,这时为啥呢。如:
.car-text{ z-index: 999; color: red;}img { position: relative; right: 50px;}<div> <span class="car-text">car</span> <img src="1.png"/></div>
结果如下:
虽然文字设置了z-index:999,结果还是被图片遮盖了,即便将z-index设置成999999结果也一样。为啥会这样呢?
层叠上下文:
层叠上下文是一个概念,跟“块状格式化上下文” (BFC)类似,我们可以把层叠上下文理 解为一种“层叠结界”,自成一个小世界,这个小世界中可能有其他的“层叠结界”,而自身也可能处于其他“层叠结界”中。
层叠上下文元素有如下特性。
层叠上下文的层叠水平要比普通元素高(原因后面会说明)。
层叠上下文可以阻断元素的混合模式。
层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的“层叠上下文”。
每个层叠上下文和兄弟元素独立,也就是说,当进行层叠变化或渲染的时候,只需要
考虑后代元素。
每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠
上下文的层叠顺序中。
层叠上下文有固定规则的,层级规则如下:
只有处于同一层级的元素,设置z-index才能进行比较,所以上面实例可以更改如下:
.car-text{ z-index: 999; color: red; position:relative;//将元素设为层叠上下文元素}img { position: relative; right: 50px;}
结语
常用的属性就介绍到这里了,希望大家有所收获
参考书籍《CSS的世界》
作者:Taurin
链接:https://juejin.im/post/6857523061424881672
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。