在分析CSS的布局技巧之前,我们先来复习一下CSS一些重要的规则(学了太久都忘啦)。
特异度
当多个选择器都可以匹配到同一个元素时,元素该使用哪种样式呢?这就涉及到了特异度。其实每种选择器都是有自己的权重的,从低到高依次是:id#、(伪)类.\标签、标签,把权重相加就得到了选择器的特异度,选择样式的时候当然是选特异度最高的那个啦!
<button class="btn">普通按钮</button>
<button class="btn primary">主要按钮</button>
<style>
.btn {
display: inline-block;
padding: .36em .8em;
margin-right: .5em;
line-height: 1.5;
text-align: center;
cursor: pointer;
border-radius: .3em;
border: none;
background: #e6e6e6;
color: #333;
}
.btn.primary {
color: #fff;
background: #218de6;
}
</style>
比如上面这段代码显示出来的样式就是:
继承
元素的属性可以按是否可继承分成两个类:可继承的和不可继承的。
可继承的属性在没有显式指定一个值的情况下,会自动继承其父元素对应的值,比如color、font-size属性的;
不可继承的属性无法自动继承父元素对应的值,如果想要继承,可以设置成inherit,比如box-sizing。
如果一个属性无法继承也没设置值的话,html就会自动把这个元素设为初始值initial,当然了如果想把某个元素设置初始值,也可以手动设置。
CSS求值过程
浏览器在进行样式渲染的时候都经历了些什么呢?
其实每个属性进行样式选择的时候都要经历很复杂的过程:
- 浏览器会根据html标签生成DOM树,根据样式规则和DOM树进行匹配
- 先找出能匹配上某元素某属性的所有选择器,看其中的属性是否有效,是否符合当前的media等
- 对某元素某属性所有可能的值进行根据特异性排序,选出优先级最高的那个翻牌子(bushi),也叫做层叠值
- 如果层叠值为空怎么办?使用初始值或继承值
- 把相对值、关键字、百分比转换为绝对值,相对路径转换为绝对路径,小数像素值转换为整数。
布局
元素在页面中应该在哪里显示呢?怎么确定内容的大小和位置?这就涉及到布局啦,也是这节的重点。
有三种布局相关技术:常规流、浮动和绝对定位
常规流
就是常规的盒子模型,是最基础的。还有行级元素块级元素、表格布局、FlexBox、Grid布局等等。
下面这张图很好的展示了盒子模型内部的布局,简单来说就是border是盒子的边框,外部有外边距margin,内部有内边距padding,中心有内容content
- 我们通常所说的width和height都是指的盒子中content内容的宽高,可以使用长度、百分数和auto,百分数是相对于容器的content-box尺寸,只有容器具有指定的宽度高度时,百分数才生效。
- padding用于指定元素四个方向的内边距,百分数相对于容器宽度
- border可以指定容器边框的样式、粗细和颜色,四个方向都可以单独设置
- margin指定元素四个方向的外边距,百分数也是相对于容器宽度。需要在垂直方向上会有边距的合并,只会取两者间较大的边距
- border-box:我们之前讲的都是基于默认的content-box,而border-box则是基于整个border框的结构,包含border和padding在内,content的尺寸要减去border和padding
还有要区分行级元素和块级元素。顾名思义行级元素就是内容会分散在多个行盒当中,从左到右摆放,两个行级元素之间不会换行,只有在这一行写满了才会换到下一行,比如span、em、strong、code、cite等;而块级元素会生成块级盒子,从上到下摆放,每个块级元素都是单独的一部分,没办法像行级元素一样放在一行的,比如div、body、h1-6、p、ul、il、section、srtical、main等。
但是行级元素和块级元素可以使用display属性来进行转换,bolck就是块级盒子,inline就是行级盒子,inline-block是可以设置宽高的行级盒子,作为一个整体不会被拆散成多行。
Flex是不同于行级块级的一种更灵活的布局方式,可以自己控制子级盒子的摆放流向、顺序、宽高、水平和垂直对齐、是否允许拆行等等。display的值为flex。flex的元素是有弹性的可伸缩的,比如flex-grow属性可以规定划分剩余空间的多大比例给该元素。下面是一些flex相关的缩写
如果说flex是线性的排版,那Grid布局就是二维的排版。可以随意安排某个元素在盒子中的位置,可以横着的也可以是竖着的,可以在左边也可以在右边。display的值为grid。是怎么做到的呢?其实是把盒子划分成一个个网格,再设置每个子项占哪些行或列
Float浮动
主要是为了实现文字环绕的效果,通过设置float属性来决定图片出现在文字的哪边。
position
position属性有几个取值,分别对应了几种不同的布局方式
- static:默认值,非定位元素
- relative:相对自身原本位置偏移,不脱离文档流
- absolute:绝对定位,相对最近的非static祖先元素定位,如果一直找不到就会相对HTML根元素定位
- fixed:相对于视口绝对定位
绝对定位有什么用呢?导航栏!不管页面如何滚动,导航栏总是固定的
布局案例分析
在百度的页面,我们可以看到导航栏是由一个div元素中嵌套多个超链接构成的。
.s-top-left-new中规定了外层盒子的宽高与左侧padding,定位方式是absolution,对应的非static祖先元素就是html标签。
其中嵌套的a标签(以新闻为例),display属性设置为行内块,且规定了上侧和右侧的margin,橙色部分是margin,蓝色部分是content。定位方式是relative。
.s-top-left-new {
position: absolute;
left: 0;
top: 0;
z-index: 100;
height: 60px;
padding-left: 24px
}
.s-top-left-new .mnav {
margin-right: 24px;
margin-top: 19px;
display: inline-block;
position: relative
}