前言
本篇章主要讲述CSS布局内容,了解选择器优先级、常见的盒模型、BFC容器、定位布局、flex布局、常见布局,最后总结移动端响应式布局方案。
面试回答
1.选择器优先级:!important>内联样式>id选择器>类选择器>标签选择器
2.盒模型:主流有两种盒模型,分别是标准盒模型和IE盒模型,两者的区别是标准盒模型设置width是实际内容,而IE盒模型设置的width包括了实际内容、内边距、边框。
3.BFC:BFC就是块级格式化上下文,它会在页面上一个隔离的独立容器,容器内外的元素不会互相影响,因此可以解决margin塌陷和清除浮动的问题,触发条件一般可以通过设置浮动、定位、overflow以及display实现。
4.水平垂直居中:第一种是使用flex布局,把父元素的justify-content和align-item都设置为center即可。第二种是position布局,父元素position设置为relative,子元素设置为absolute,然后把left、right都设置为50%,用transform的translate属性调整-50%。第三种是伪元素布局,首先父元素text-align设置为center,即水平居中,然后设置父元素before中的display为inline-block,vertical-align为middle,同时设置子元素样式与父元素before一致,否则会偏移。
5.flex布局:常见的属性有flex-direction,用来控制主轴方向,flex-wrap用来控制换行,justify-content控制水平对齐,align-items控制垂直对齐,flex-grow控制子项占据的份额类似百分比。
6.弹性布局:常见的有flex+rem+媒体查询,来完成弹性布局,不过flex存在兼容问题,需要兼容低版本的各类浏览器,如果没有浏览器要求,这是比较好用简便的方式。当然还可以用给父元素添加BFC来实现弹性布局,给父元素添加一些float、position或者overflow:hidden,都可以实现BFC。
知识点
1.选择器优先级
选择器 | 权重 | 格式 | 实例 |
---|---|---|---|
!important | 最高 | xxx:xxx !important | color:#000 !important |
内联样式 | 1000 | style="xxx:xxx" | style="color:#000" |
id选择器 | 100 | #id名 | #test{color:#000} |
类选择器 | 10 | .类名 | .test{color:#000} |
属性选择器 | 10 | [属性名] | h2[title]{color:#000} |
伪类选择器 | 10 | :last-child | p:first-child{color:#000} |
标签选择器 | 1 | 标签名 | p{color:#000} |
伪元素选择器 | 1 | ::after | p::after{color:#000} |
相邻兄弟选择器 | 0 | 标签名/类名+标签名/类名 | div+p |
子选择器 | 0 | 父元素名>子元素名(仅一代) | div>p |
后代选择器 | 0 | 父元素名 子元素名 | div p |
注意事项:
属性选择器既可以单个出现,也可以添加限制,如下:
<div title="abc"> <p>11111</p> <h2 title="abc">22222</h2> </div> [title]{ color:red } h2[title] { color: green; } //1为红,2为绿
伪类与伪元素的区别在于伪元素创造新的显示元素, 伪类没有,伪类选择器
:
前的为主元素,如<div class="aaa"> <p>11111</p> <h2>22222</h2> <p>333333</p> </div> <style> p:first-child{ color:red } </style> //p元素的父元素内第一个p元素的样式为红
相邻兄弟选择器只应用于相邻两个HTML,且相邻顺序与css一致,如下
<div>1111</div> <p>22222</p> <div>33333</div> <div>aaa</div> <p>44444</p> <style> p+div{ color:red; } </style> //只有3符合
子选择器与后代选择器的区别在于,子选择器仅限直接后代,而后代选择器则是所有的后代
<div> <p><span class="a">1</span></p> <span class="b">2</span> </div> <style> //2为红 div>span{ color:red; } //1、2均为绿 div span{ color:green; } </style>
- 如果优先级相同,则最后出现的样式生效,继承得到的样式的优先级最低,比如font-size、font-family、color
2.盒模型
CSS 中任何元素都可以看成是一个盒子,而一个盒子是由 4 部分组成的:内容(content)、内边距(padding)、边框(border)和外边距(margin)。 盒模型有 2 种:标准盒模型和 IE 盒模型,分别是由 W3C 和 IExplore 制定的标准。
标准盒模型:盒子的实际尺寸 = 内容(width) + 内边距(padding)+边框 (border)
IE盒模型认为:盒子的实际尺寸(width)= 内容 + 内边距(padding) +边框(border)
在 CSS3 中新增了一个属性 box-sizing
,允许开发者来指定盒子使用什么标准,它有 2 个值:
content-box
:标准盒模型;border-box
:IE 盒模型;
可以通过控制台Elements中style最下方的图例查看每个元素的盒模型,如下图
3.BFC
概念
BFC即块级格式化上下文
,官方解释:BFC
决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,当涉及到可视化布局时,BFC
提供了一个环境,HTML在这个环境中按照一定的规则进行布局。简单来说就是页面盒模型布局中的一种CSS渲染模式,相当于一个独立的容器,里面的元素和外部的元素都相互不影响。
触发条件
- 浮动元素(float),且值不为none
- 定位元素(position:absolute/fixed)
- 具有overflow且值不是visible的块元素
- 设置display的值为inline-block、flex、table-cell、table-caption、inline-flex、flow-root
渲染规则
BFC
中有特定的渲染规则,如:
- 垂直方向的距离由margin决定,同一个BFC中两个相邻的元素的
margin重叠
问题 - BFC在计算高度是即使浮动的元素也会参与高度计算
- BFC的区域不会与float的元素区域重叠
- 每个元素的左外边距与包含块的左边界相接触,即使浮动也如此
- 内部的盒子会一在垂直方向上一个个放置
- BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素
应用场景
防止margin重叠(塌陷)
<body> <div> <p>1111</p> <p>2222</p> </div> </body> <style> p { color: #f55; background: #fcc; width: 200px; line-height: 100px; text-align: center; margin: 100px; } </style>
两个P元素之间的距离理论上应该为200px,但是发生了margin重叠(塌陷),margin以最大的为准,比如两个元素的margin一个为100px一个为80px,那么两个元素之间的距离还是100px。
解决方式:可以在P外面包裹一层容器,并触发这个容器生成一个BFC
,那么两个P元素就不属于同一个BFC
,则不会出现margin重叠。
<body>
<p>11111</p>
<div class="wrap">
<p>22222</p>
</div>
</body>
<style>
.wrap {
overflow: hidden;
}
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align: center;
margin: 100px;
}
</style>
清除内部浮动
元素在加上float属性脱离文档流之后,会产生高度塌陷的问题,除了清除浮动,我们还可以通过
BFC
的特性去处理, 如<style> .par { border: 5px solid #fcc; width: 300px; } .child { border: 5px solid #f66; width: 100px; height: 100px; float: left; } </style> <body> <div class="par"> <div class="child"></div> <div class="child"></div> </div> </body>
使用BFC解决高度塌陷问题:
.par { overflow: hidden; } //其他代码同上,只要是par的div符合BFC即可
两栏布局
一般两栏布局,常常会写两个div,其中一个div调整为浮动,如下
<body> <div class="aside"></div> <div class="main"></div> </body> <style> .aside { width: 100px; height: 150px; float: left; background: #f66; } .main { height: 200px; background: #fcc; } body { width: 300px; } </style>
此时,aside浮动于左侧,同时由于每个元素的左外边距与包含块的左边界相接触,所以main的div会多出一块内容,将main的div改为BFC,可以改变这种情况。
.main {
overflow: hidden;
}
//其他代码同上,只要是par的div符合BFC即可
4.定位方式
咱们先了解下文档流,简单说就是元素按照其在HTML中的位置顺序决定排布的过程。HTML的布局机制就是用文档流模型的,即块元素(block)独占一行,内联元素(inline),不独占一行。只要不是float和绝对定位方式布局的,都在文档流里面。CSS有三种基本定位机制:普通流,浮动和定位。标准流在最底层,而浮动的盒子在中间层,定位的盒子在最上层。 下面我们看看定位的几种模式:
属性值 | 说明 |
---|---|
static | 静态定位(默认值) |
relative | 相对定位 |
absolute | 绝对定位 |
fixed | 固定定位 |
静态定位
在默认情况下,元素是静态定位的,即正常出现在标准文档流中,对其的top、bottom、left、right 不生效。
<div class="a">1</div>
//不生效class
<style>
.a{
top:100px;
bottom:100px;
left:100px;
right:100px;
}
</style>
相对定位
相对定位是元素相对于他自己原来在标准流中的位置来移动的。
<div class="div1">div1</div>
<div class="div2">div2</div>
<div class="div3">div3</div>
<style>
.div1,
.div3 {
height: 100px;
width: 200px;
background-color: green;
}
.div2 {
height: 100px;
width: 200px;
background-color: green;
position: relative;
top: 50px;
left: 50px;
}
</style>
绝对定位
当使用绝对定位时,此元素脱离文档流,其他元素会当这个元素不存在。 绝对定位是依据最近的(绝对、固定或者相对定位)的父元素进行定位,如果没有则以浏览器为标准定位。
<div class="div1">div1</div>
<div class="div2">div2</div>
<div class="div3">div3</div>
<style>
.div1,
.div3 {
height: 100px;
width: 200px;
background-color: green;
border: 1px solid black;
}
.div2 {
height: 50px;
width: 50px;
background-color: red;
position: absolute;
top: 50px;
left: 50px;
}
</style>
固定定位
固定的元素不会随着滚动条的拖动而改变位置, 只认浏览器的可视窗口, 跟父级元素无任何关系,不随滚动条而滚动。
<div class="div1">div1</div>
<div class="div2">div2</div>
<style>
.div1 {
height: 2000px;
width: 200px;
background-color: green;
display: table-cell;
vertical-align: middle;
}
.div2 {
height: 100px;
width: 100px;
position: fixed;
background-color: red;
top: 100px;
left: 300px;
}
</style>
5.flex布局
这边给一个表格,用于熟悉日常常见属性
属性 | 描述 |
---|---|
display | 指定 HTML 元素的盒子类型 |
flex-direction | 指定弹性盒子中子元素的排列方式 |
flex-wrap | 设置当弹性盒子的子元素超出父容器时是否换行 |
flex-flow | flex-direction 和 flex-wrap 两个属性的简写 |
justify-content | 设置弹性盒子中元素在主轴(横轴)方向上的对齐方式 |
align-items | 设置弹性盒子中元素在侧轴(纵轴)方向上的对齐方式 |
align-content | 修改 flex-wrap 属性的行为,类似 align-items,但不是设置子元素对齐,而是设置行对齐 |
order | 设置弹性盒子中子元素的排列顺序 |
align-self | 在弹性盒子的子元素上使用,用来覆盖容器的 align-items 属性 |
flex | 设置弹性盒子中子元素如何分配空间 |
flex-grow | 设置弹性盒子的扩展比率 |
flex-shrink | 设置弹性盒子的收缩比率 |
flex-basis | 设置弹性盒子伸缩基准值 |
6.常见布局
居中
行内元素
<body> <div class="main" style="width:100px;height:100px;"> 11111 </div> </body> <style> .main { line-height: 100px; //垂直居中 text-align: center; //水平居中 } </style>
块级元素
<body> <div id="center"> aaa </div> </body> <style> #center { margin: 0 auto; //水平居中,指的是div元素而不是div内容(aaa) width: 100px; height: 100px; background: red; } </style>
flex居中
<body> <div id="parent"> <div class="child1">1</div> <div class="child">2</div> <div class="child">3</div> </div> </body> <style> #parent { display: flex; align-items: center; justify-content: center; height: 300px; } .child { width: 100px; height: 100px; color: aqua; background-color: brown; margin: 5px; } .child1 { width: 100px; height: 100px; color: aqua; background-color: brown; margin: 5px; display: flex; align-items: center; justify-content: center; } </style>
parent的居中设置只针对其内的三个div,每个div的内容需要额外设置,如child1
不定宽高时:position+transform
<body> <div class="parent"> <div class="child">1111111111111111111111111111</div> </div> </body> <style> .parent { position: relative; height: 100px;//用于方便识别是否垂直居中 } .child { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } </style>
伪元素居中
<body> <div class="parent"> <div class="child"></div> </div> </body> <style> .parent { width: 300px; height: 300px; border: 1px solid red; text-align: center; } .child { background: blue; width: 100px; height: 40px; display: inline-block; vertical-align: middle; } .parent::before { content: ''; height: 100%; display: inline-block; vertical-align: middle; } </style>
圣杯
<div class="header"></div>
<div class="content">
<div class="middle"></div>
<div class="left"></div>
<div class="right"></div>
</div>
<div class="footer"></div>
<style>
body {
margin: 0;
}
.header {
width: 100%;
height: 30px;
background: red;
}
.content {
overflow: hidden;
padding: 0 100px;
}
.footer {
width: 100%;
height: 30px;
background: red;
}
.middle {
position: relative;
width: 100%;
float: left;
height: 80px;
background: green;
}
.left {
position: relative;
width: 100px;
float: left;
left: -100px;
height: 80px;
margin-left: -100%;
background: yellow;
}
.right {
position: relative;
width: 100px;
float: left;
right: -100px;
height: 80px;
margin-left: -100px;
background: pink;
}
</style>
双飞翼
<div class="header"></div>
<div class="content">
<div class="middle">
<div class="inner-middle"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
<div class="footer"></div>
<style>
body {
margin: 0;
}
.header {
width: 100%;
height: 30px;
background: red;
}
.content {
overflow: hidden;
}
.footer {
width: 100%;
height: 30px;
background: red;
}
.middle {
width: 100%;
float: left;
}
.inner-middle {
width: 100%;
height: 80px;
background: green;
padding: 0 100px;
}
.left {
width: 100px;
float: left;
height: 80px;
margin-left: -100%;
background: yellow;
}
.right {
width: 100px;
float: left;
height: 80px;
margin-left: -100px;
background: pink;
}
</style>
虽说圣杯和双飞翼的样式展示出来都是一样的,但是本质上不同,圣杯布局是中间栏为两边腾开位置;双飞翼布局则是中间栏不变,将内容部分为两边腾开位置。可以类比盒模型:标准盒模型-圣杯布局,IE盒模型-双飞翼模型,参考下图:
圣杯布局:整个宽度=左边栏+中间栏(内容栏)+右边栏
双飞翼布局:整个宽度(中间栏) = 左边栏+内容栏+右边栏
7.移动端响应式布局
1、设置viewport
width=device -width 可视区域窗口的大小 = 设备大小
//在主HTML(现在大部分都是单页面应用)里设置meta
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover" />
2、媒体查询
支持媒体查询的浏览器版本
语法:@media 媒体类型 逻辑操作符 (媒体属性) {样式代码}
媒体类型
逻辑操作符
- not:not是用来排除掉某些特定的设备的,比如 @media not print(非打印设备)。
- only:用来定某种特别的媒体类型。对于支持Media Queries的移动设备来说,如果存在only关键字,移动设备的Web浏览器会忽略only关键字并直接根据后面的表达式应用样式文件。对于不支持Media Queries的设备但能够读取Media Type类型的Web浏览器,遇到only关键字时会忽略这个样式文件。
- and:符合媒体即能应用css样式
all:所有设备。
媒体属性
@media mediaType not|only|all (media feature) {
//CSS样式
}
//1.用@media开头
//2.mediatype是媒体类型,比如screen、print、all
//3.关键字and、not、only、all
//4.media feature媒体特性,必须有小括号包,比如常见的width、min-width、max-width
@media only screen and (max-device-width:480px) {
/css样式/
}
@media (min-width: 768px) {
color:#000
}
如何确定媒体查询的分割点也是一个开发中会遇到的问题,下面是市场上的移动设备和电脑屏幕分辨率的分布情况。
3、字体适配(字体单位)
css常用单位:px、%、em、rem、vw 、vh
建议直接使用px,因为px是绝对像素,其他的都是相对像素
4、布局
- 结合flex,grid,BFC,栅格系统等已经成型的方案
最后
走过路过,不要错过,点赞、收藏、评论三连~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。