CSS布局技巧 | 豆包MarsCode AI刷题

108 阅读6分钟

在分析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>

比如上面这段代码显示出来的样式就是: image.png

继承

元素的属性可以按是否可继承分成两个类:可继承的和不可继承的。
可继承的属性在没有显式指定一个值的情况下,会自动继承其父元素对应的值,比如colorfont-size属性的;
不可继承的属性无法自动继承父元素对应的值,如果想要继承,可以设置成inherit,比如box-sizing
如果一个属性无法继承也没设置值的话,html就会自动把这个元素设为初始值initial,当然了如果想把某个元素设置初始值,也可以手动设置。

CSS求值过程

浏览器在进行样式渲染的时候都经历了些什么呢?
其实每个属性进行样式选择的时候都要经历很复杂的过程:

  • 浏览器会根据html标签生成DOM树,根据样式规则和DOM树进行匹配
  • 先找出能匹配上某元素某属性的所有选择器,看其中的属性是否有效,是否符合当前的media等
  • 对某元素某属性所有可能的值进行根据特异性排序,选出优先级最高的那个翻牌子(bushi),也叫做层叠值
  • 如果层叠值为空怎么办?使用初始值或继承值
  • 把相对值、关键字、百分比转换为绝对值,相对路径转换为绝对路径,小数像素值转换为整数。

布局

元素在页面中应该在哪里显示呢?怎么确定内容的大小和位置?这就涉及到布局啦,也是这节的重点。
有三种布局相关技术:常规流、浮动和绝对定位

常规流

就是常规的盒子模型,是最基础的。还有行级元素块级元素、表格布局、FlexBox、Grid布局等等。

下面这张图很好的展示了盒子模型内部的布局,简单来说就是border是盒子的边框,外部有外边距margin,内部有内边距padding,中心有内容content
image.png

  • 我们通常所说的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相关的缩写 image.png

如果说flex是线性的排版,那Grid布局就是二维的排版。可以随意安排某个元素在盒子中的位置,可以横着的也可以是竖着的,可以在左边也可以在右边。display的值为grid。是怎么做到的呢?其实是把盒子划分成一个个网格,再设置每个子项占哪些行或列 image.png

image.png

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
            }

image.png

image.png