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

75 阅读9分钟

深入 CSS 总结


使用 CSS

CSS 的使用方式包括外链、嵌入和内联。目前,组件化开发方式非常流行,但一般不推荐使用内联样式,尽管在一些 UI 组件库中内联样式仍然较为常见。

CSS 是如何工作的?

当打开一个网页时,浏览器会加载页面的 HTML 并对其进行解析。在解析过程中,如果遇到内联、外链或嵌入的 CSS,浏览器会将所有的 CSS 收集并解析,然后将样式应用到 DOM 树上,最终渲染出完整的页面。


CSS 选择器

通配选择器

* {
  margin: 0;
  padding: 0;
}

通配选择器 * 会选择页面中的所有元素。以上代码将所有元素的 marginpadding 设置为 0,通常用于初始化样式。

ID 选择器

#h1 {
  color: red;
}

以上是一个 ID 选择器,选择了 idh1 的元素,将其文字颜色设置为红色。需要注意,ID 在页面中应该是唯一的。

类选择器 class

HTML:

<div class="box">内容</div>

CSS:

.box {
  width: 100px;
  height: 100px;
  background-color: red;
}

类选择器 .box 选择了所有 class 属性为 box 的元素,设置其宽度、高度和背景颜色。

属性选择器

属性选择器可以根据元素的属性及属性值进行选择。

示例 1:

HTML:

<label>用户名:<input type="text" name="username" /></label>

CSS:

[type="text"] {
  width: 100px;
  height: 30px;
  background-color: red;
}

以上代码选择了所有 type 属性等于 text 的输入框,设置其宽度、高度和背景颜色。

伪类选择器

状态伪类选择器

状态伪类选择器用于根据元素的状态来选择元素。以链接为例,不同状态可以应用不同的样式。

a:link {
  color: black;
}
a:visited {
  color: gray;
}
a:hover {
  color: red;
}
a:active {
  color: blue;
}
a:focus {
  color: green;
}

解释:

  • a:link:未访问过的链接。
  • a:visited:已访问的链接。
  • a:hover:鼠标悬停在链接上。
  • a:active:链接被点击时的状态。
  • a:focus:链接获得焦点时的状态。
结构伪类选择器

结构伪类选择器根据元素在 DOM 树中的位置进行选择。

HTML:

<ol>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ol>

CSS:

li:first-child {
  color: red;
}
li:last-child {
  color: blue;
}
li:nth-child(2) {
  color: green;
}
li:nth-child(odd) {
  color: yellow;
}
li:nth-child(even) {
  color: pink;
}

解释:

  • li:first-child:选择父元素中的第一个 li,文字颜色设为红色。
  • li:last-child:选择父元素中的最后一个 li,文字颜色设为蓝色。
  • li:nth-child(2):选择父元素中的第二个 li,文字颜色设为绿色。
  • li:nth-child(odd):选择父元素中的奇数序号的 li,文字颜色设为黄色。
  • li:nth-child(even):选择父元素中的偶数序号的 li,文字颜色设为粉色。

选择器的优先级

CSS:

.title {
  color: red;
}
#title {
  color: blue;
}

在上述代码中,如果一个元素同时具有 class="title"id="title",由于 ID 选择器的优先级更高,文字颜色将被设置为蓝色。

特殊性(Specificity)

CSS 选择器的优先级由其特殊性决定,计算方式如下:

选择器类型数值
内联样式(inline style)1000
ID 选择器100
类、属性、伪类选择器10
元素、伪元素选择器1
通配符 *0

注意:

  • !important 声明会覆盖其他所有声明,即使特殊性较低。但如果多个规则都使用 !important,则按照特殊性进行比较。
  • 不建议滥用 !important,以免导致样式难以维护。

选择器的覆盖

CSS:

.btn {
  display: block;
  width: 100px;
  height: 50px;
  background-color: red;
}
.btn.primary {
  background-color: blue;
}

解释:

  • 如果一个元素同时具有 class="btn primary",由于 .btn.primary 的特殊性为 10 + 10 = 20,高于 .btn 的特殊性 10,因此背景颜色将被设置为蓝色,覆盖了 .btn 中的背景颜色。

继承

在 CSS 中,某些属性会自动继承父元素的计算值,除非显式地指定其他值。如果需要强制继承,可以使用 inherit 关键字。

示例:

* {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
}

.some {
  box-sizing: content-box;
}

解释:

  • 所有元素的 box-sizing 属性被设置为继承父元素的值。
  • html 元素的 box-sizing 被设置为 border-box,因此其子元素默认会继承这个值。
  • 类名为 .some 的元素被显式设置为 content-box,覆盖了继承的值。

组合选择器

颜色

RGB 颜色表示

div {
  background-color: rgb(255, 0, 0);
}

以上代码将 div 的背景颜色设置为纯红色。

HSL 颜色表示

div {
  background-color: hsl(0, 100%, 50%);
}

以上代码使用 HSL(色相、饱和度、亮度)表示颜色,将背景颜色设置为纯红色。

透明度(Alpha)颜色

div {
  background-color: rgba(255, 0, 0, 0.5);
}

将背景颜色设置为半透明的红色,透明度为 50%。


字体

字体的选择

body {
  font-family: Arial, sans-serif;
}

font-family 属性用于设置字体系列。以上代码指定了多个字体,浏览器会按顺序选择设备上可用的字体:

  • 如果设备安装了 Arial 字体,就使用它。
  • 如果没有,则使用通用的无衬线字体 sans-serif

这种方式确保了在不同设备上都有合适的字体显示。

字体的大小

body {
  font-size: 16px;
}

font-size 属性用于设置字体的大小。可以使用像素(px)、百分比(%)、em 等单位。

em 单位:

  • em 是相对于父元素的字体大小来设定的。
  • 例如,如果父元素的 font-size16px,那么 1em 等于 16px

行高

body {
  line-height: 1.5;
}

line-height 属性用于设置行高,控制文本行与行之间的距离。可以使用数值、百分比或单位。

字体的粗细

body {
  font-weight: bold;
}

font-weight 属性用于设置字体的粗细。常用的值有:

  • normal:正常字体重量。
  • bold:加粗字体。
  • 数值:100200、...、900,数值越大,字体越粗。

文本缩进

p {
  text-indent: 50px;
}

text-indent 属性用于设置文本的首行缩进。以上代码将段落 p 的首行缩进 50 像素。

文本对齐

p {
  text-align: center;
}

text-align 属性用于设置文本的对齐方式。可选值包括:

  • left:左对齐(默认值)。
  • center:居中对齐。
  • right:右对齐。
  • justify:两端对齐。

渲染过程

下图展示了 CSS 的渲染过程:

image.png


布局

CSS 布局的相关技术中,盒模型(Box Model)是最基础的概念。

盒子模型转存失败,建议直接上传图片文件

常规流

CSS 中最经典的就是盒模型,由以下部分组成:

  • content:内容区域,显示文本和内嵌元素。
  • padding:内边距,围绕在内容区域周围的空白区域。
  • border:边框,围绕在内边距外部。
  • margin:外边距,元素与其他元素之间的空白区域。
宽度和高度
  • width
    • 可以使用长度值(如 px)、百分比或 auto
    • auto:根据内容的大小自动决定。
    • 百分比:相对于父容器的 content box 的宽度计算。
  • height
    • 如果容器没有指定高度,子元素的高度百分比将无效。
内边距 padding
  • padding 的百分比是相对于父容器的宽度计算的。
边框 border
  • border 有多种属性可设置:
border: 1px solid red;
  • 可以利用 border 属性设计出三角形:
#triangle {
  width: 0;
  height: 0;
  border-width: 100px;
  border-style: solid;
  border-color: red transparent transparent transparent;
}

以上代码创建了一个红色三角形。

外边距 margin

margin 位于 border 的外部,用于控制元素与其他元素之间的距离。


行内格式化上下文(IFC)

  • 行内级别(Inline Level)
    • 生成行内级别的盒子,默认情况下,行内元素不能设置宽高。
    • 但是,可以将行内元素转换为块级元素。
  • inline-block 元素
    • 本身是行内元素,可以在行内格式化上下文中使用。
    • 可以设置宽高,作为一个整体,不会被拆分到多行。

块级格式化上下文(BFC)

  • 块级元素(Block Level Elements)
    • 生成块级别的盒子,默认情况下,从上到下垂直排列,占据其父容器的整个宽度。
  • 块级格式化上下文(Block Formatting Context,简称 BFC)
    • 某些元素会创建一个新的 BFC,这是 CSS 布局的重要概念。

BFC 的特性:

  • 避免外边距合并: 在同一个 BFC 内,垂直方向相邻元素的外边距可能会合并。但 BFC 内部的元素的外边距不会与外部元素的外边距合并。
  • 包含浮动元素: BFC 会包含内部的浮动元素,从而防止浮动元素影响外部元素的布局。
  • 阻止元素重叠: BFC 不会与浮动元素发生重叠,布局时会自动避开浮动元素。

创建 BFC 的常见方式:

  • 设置 overflow 属性为 hiddenautoscroll
  • 使用 display: flow-root;
  • 应用 floatposition: absolute/fixed;

示例:

.container {
  overflow: hidden; /* 创建 BFC */
}

.float-box {
  float: left;
  width: 150px;
  height: 150px;
  background-color: lightcoral;
}

.content {
  background-color: lightblue;
  padding: 20px;
}

HTML:

<div class="container">
  <div class="float-box"></div>
  <div class="content">
    <p>这段内容不会与左侧的浮动元素重叠,因为它位于一个创建了 BFC 的容器中。</p>
  </div>
</div>
  • .container 通过设置 overflow: hidden; 创建了一个新的 BFC。
  • .float-box 设置了 float: left;,使其左浮动。
  • .content.container 内部,由于 BFC 的作用,它不会与 .float-box 重叠,而是正常地排列在浮动元素的旁边。
弹性布局

弹性布局就是使用 flex 属性来实现的。

.container {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

这里的 justify-content 属性是用来设置弹性容器内部的子元素在主轴上的对齐方式的 可以使用 flex-grow 属性来设置弹性格子中把原本的宽度撑满之后扩展的比例

当容器的空间不够的时候可以通过 flex-shrink 属性来设置弹性格子的收缩比例

网格布局

网格布局是使用 grid 属性来实现的。我们发现 flex 是一种单一方向上的布局,但是 grid 是一种二维的布局

grid-template-columns: 100px 100px 1fr;
grid-template-rows: 100px 100px 100px;

浮动

float 是实现图片环绕的一种效果

img {
  float: left;
}

绝对定位

static 是默认的定位方式,relative 是相对于自身的定位,absolute 是相对于非 static 父元素的定位,fixed 是相对于视口的定位

.container {
  position: relative;
}
.box {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
}

flex实现居中

<div class="container">
  <div class="box"></div>
</div>
.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

这是 flex 布局的,displayflex 是将容器设置为弹性容器,justify-content:center 是将子元素在主轴上居中,align-items:center 是将子元素在侧轴上居中