CSS 并不是面试的重点考察项,这也导致现在国内业界对 CSS 的专注不够,真正精通并专注于 CSS 的团队和人才并不多。因此如果能在 CSS 领域有自己的见解和经验,反而会为相当的加分并脱颖而出。
1 . 盒子模型 (box-sizing)
理论上盒子模型可以分为四种,但现在 w3c
与 mdn
规范中均只支持 content-box
与 border-box
;
content-box (W3C 标准盒模型)
border-box (IE 盒模型)
padding-box (FireFox 曾经支持)
margin-box (浏览器未实现)
一个盒子包括,margin(外边距)
,border(边框)
,padding(内边距)
,content(内容)
盒子模型的默认值是box-sizing = content-box
当设置 box-sizing = content-box
时,就是 width = content
当设置 box-sizing = border-box
时,就是 width = content + border + padding
box-sizing = border-box
的主要应用场景是:
1 . 盒子的宽高固定,无论如何设置border
或者padding
,都不会超出固定宽高
2 . 盒子的宽高固定,设置padding
,调整content
中元素的位置
2 . BFC (块级格式化上下文)
BFC的定义和解释非常杂,有兴趣细致了解的可以看一下这位师兄的文章,点击跳转,我这里只做一下精简总结
BFC 可以解决的实际开发问题
1 . 避免相邻两个box
的margin
重叠。
2 . 清除浮动。
3 . 实现自适应两栏布局(或者说,不被浮动元素覆盖)
如何创建BFC
虽然有这么多规则创建BFC
,但是最常用的还是overflow: auto;
和overflow: hidden;
1、float的值不是none。
2、position的值不是static或者relative。
3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex
4、overflow的值不是visible
1 . 避免相邻两个box
的margin
重叠。
因为同一个BFC
的两个相邻Box
的margin
会发生重叠。
利用BFC
的特性,创建两个BFC
彼此之间就不会出现重叠现象
<style>
* {
margin: 0;
padding: 0;
}
p {
color: #f55;
background: yellow;
width: 200px;
line-height: 100px;
text-align: center;
margin: 30px;
}
div {
overflow: auto;
}
</style>
<body>
<p>看看我的 margin是多少</p>
<div>
<p>看看我的 margin是多少</p>
</div>
</body>
2 . 清除浮动、浮动元素无法撑起父元素。(清除内部浮动、也是BFC应用最广泛的一点)
通常情况下父元素的高度会被子元素撑开,而如果父元素没有设置高度,其子元素又均为浮动元素,此时父元素会发生了高度坍塌,上下边界重合,即浮动元素无法撑起父元素。
<style>
.par {
border: 5px solid rgb(91, 243, 30);
width: 300px;
overflow: hidden;
}
.child {
border: 5px solid rgb(233, 250, 84);
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
注意:在父元素上设置形成BFC的属性
3 . 实现自适应两栏布局(或者说,不被浮动元素覆盖)
<style>
* {
margin: 0;
padding: 0;
}
body {
width: 100%;
position: relative;
}
.left {
width: 100px;
height: 150px;
float: left;
background: rgb(139, 214, 78);
text-align: center;
line-height: 150px;
font-size: 20px;
}
.right {
overflow: hidden;
height: 300px;
background: rgb(170, 54, 236);
text-align: center;
line-height: 300px;
font-size: 40px;
}
</style>
<body>
<div class="left">LEFT</div>
<div class="right">RIGHT</div>
</body>
3 . 层叠上下文
详细可以看这位师兄的,这里只做精简提炼,点击跳转
层叠上下文的定义: 是一个HTML
的三维概念,表现为X,Y
轴平铺,Z
轴上层叠的关系
(通俗说:就是为什么网页上的元素,有的在上面,有的被覆盖在下面的情况,平时最常用的就是设置z-index
来设置层级,达到把想要的内容放在其他元素上面的目的)
有几点重要的开头先说明
1 . z-index属性值并不是在任何元素上都有效果
2 . 层叠等级(z-index
)的比较只有在当前
层叠上下文元素中才有意义。不同层叠上下文中比较层叠等级是没有意义的。
<style>
div {
width: 100px;
height: 100px;
position: relative;
}
.box1 {
z-index: 2;
}
.box2 {
z-index: 1;
}
p {
position: absolute;
font-size: 20px;
width: 100px;
height: 100px;
}
.a {
background-color: blue;
z-index: 100;
}
.b {
background-color: green;
top: 20px;
left: 20px;
z-index: 200;
}
.c {
background-color: red;
top: -20px;
left: 40px;
z-index: 9999;
}
</style>
<body>
<div class="box1">
<p class="a">a</p>
<p class="b">b</p>
</div>
<div class="box2">
<p class="c">c</p>
</div>
</body>
虽然 c.box
的z-index: 9999
,但仍然排在其他元素下面,因为c
和a
,b
的层叠上下文不同,没有比较的意义,仅仅是因为a,b
的父元素index
值比c
的父元素高,c
就永远排在a,b
下面
如何形成层叠上下文
1 . 根层叠上下文(html
),HTML
中的根元素本身就具有层叠上下文,称为“根层叠上下文”。
2 . 定义了position
属性,且属性值为非 static
值的元素
3 . css3属性flex
、 transform
、 opacity
、filter
、 will-change
、-webkit-overflow-scrolling
层叠等级
注意:行内元素 > 浮动元素 > 块级元素
4 . 选择器优先级
!important
权值最大,甚至可以覆盖行内样式,但是一般不推荐使用
内联、行内样式 | style= " " | 1000 |
---|---|---|
ID选择器 | #id | 0100 |
类,伪类和属性选择器 | .class 、:first-child、a[href][title] | 0010 |
标签选择器、伪元素选择器 | h1、p、::after | 0001 |
通用选择器、子选择器,相邻同胞选择器 | *、>、+ | 0000 |
5 . 元素居中方法
1 . 水平居中
son是文本、行内元素、行内块级元素text-align: center
要设置在父元素上
.parent{
text-align: center;
}
son是块级元素,子元素要设置宽高,否则无法居中
(如果不设置height
,box
的height
由子元素撑起来,width = 100%
父元素,居中不了)
.son{
width: 100px;
height: 100px;
margin: 0 auto;
}
son是任意元素
(兼容性较差,针对性较弱,不是排版的话,不建议使用)
.parent{
display: flex;/*给父容器开启flex布局*/
justify-content: center;/*让容器下的布局在主轴居中 */
}
transform + absolute
(父元素要设置相对定位 position: relative
,优点:block
元素,inline
元素都行,就算不知道元素宽高也可以使用,子元素就算不设置宽高也可以)
缺点:绝对定位,脱离文档流,可能对下面的元素节点造成不必的麻烦
.parent {
position: relative;
}
.parent>div {
background-color: rgb(187, 255, 0);
position: absolute;
left: 50%;
transform: translateX(-50%);
}
2 . 元素垂直居中
son是文本、行内元素、行内块级元素( inline-block )
利用 line-height=height
的特性,在父元素中设置line-height
的值,达到垂直居中
缺点:需要知道父元素的高度
.parent{
height: 200px;
line-height: 200px;/*让line-height=height*/
}
.son是块级元素
利用table-cell
,使表格内容对齐方式为middle
,需要给父元素设置高度
.parent{
width: 100vw;
height: 100vh;
display: table-cell;
vertical-align: middle;
}
.son是任意元素 (transform + absolute,父节点需要设置高度)
子元素不需要设置宽高,也不需要知道子元素的宽高
缺点:绝对定位,脱离文档流,可能对下面的元素节点造成不必的麻烦
.parent {
position: relative;
height: 100vh;
}
.parent>div {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
还有几个变种
需要设置子元素的高度,但是不用知道子元素的高度
.parent{
position: relative;
}
.son{
position: absolute;
height: 100 px;
top: 0;
bottom: 0;
margin: auto 0;
}
不用设置子元素的高度,也不用知道子元素的高度(可以说非常好用)
.parent {
height: 100vh;
}
.son {
position: relative;
top: 50%;
transform: translateY(-50%);
}
最经典的,负边距居中法
需要设置子元素的高度,也需要知道子元素的高度
(父元素还需要设置overflow: hidden;)
.parent {
height: 100vh;
overflow: hidden;
}
.son {
position: relative;
height: 100px;
top: 50%;
margin-top: -50px;
}
flex布局
父元素需要设置高度,子元素不用管
.parent {
height: 100vh;
display: flex;
align-items: center;
}
3 . 元素,水平、垂直居中
flex实现垂直居中
.parent{
display: flex;
align-items: center;/*让项目在侧轴方向居中*/
justify-content: center;/*让项目在主轴方向居中*/
}
利用绝对定位的特性:宽高由内容撑开
子元素需要设置高度
缺点:绝对定位,脱离文档流
.parent {
height: 100vh;
position: relative;
}
.son {
height: 100px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
负边距居中
父元素需要设置BFC
子元素需要设置宽高,还需要知道子元素的宽高
.parent {
height: 100vh;
overflow: hidden;
}
.son {
height: 100px;
width: 100px;
position: relative;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
}
在不知道子元素宽高时,也可以这样写
.parent {
background-color: rgb(86, 255, 64);
height: 100vh;
overflow: hidden;
}
.son {
background-color: rgb(255, 252, 64);
height: 100px;
width: 100px;
position: relative;
left: 50%;
top: 50%;
transform: translateY(-50%) translateX(-50%);
}
6 . 清除浮动,防止父级高度塌陷,手写清除浮动代码
1 . 手动设置父元素高度
2 . 使用BFC,清除浮动
3 . 使用伪元素,手写clearfix,清除浮动,也可以在parent上直接加伪元素,但是写一个单独的属性,复用起来比较方便
<style>
* {
margin: 0;
padding: 0;
}
.parent {
background-color: rgb(86, 255, 64);
border: 2px solid red;
}
.parent .son {
background-color: rgb(255, 252, 64);
height: 100px;
width: 100px;
float: left;
}
.clearfix::after {
content: '';
clear: both;
display: block;
}
</style>
</head>
<body>
<div class="parent clearfix">
<div class="son">这是一段测试文字</div>
</div>
</body>