CSS

前端CSS基础部分

1. CSS文本模块

1.1 核心模块介绍

CSS文本模块(CSS TextModule)主要控制文本的处理方式,包括断行对齐空白处理文本转换等。它是网页排版的基础。


1.2 核心属性(必掌握)

  • 基础排版:
/*
  text-align: 控制文本的水平对齐方式(left, right, center, justify);

  line-height: 行高,垂直居中和阅读体验的关键。建议使用无单位数值(如:'1.5')以避免继承问题;
    * 例子:如果父元素是font-size: 16px; line-height: 150%; 那么子元素将会继承父元素的行高,且是固定的16 * 150% = 24px;当子元素的font-size修改为其他数值,比如40px,那么行高还是固定继承的24px;会导致混乱。 如果父元素写的是无单位的1.5,那么子元素会继承这个1.5,子元素的行高将为自己的字体大小 * 1.5。
    * 大白话:百分比是相对父元素的,无符号单位是相对子元素自身的。
  text-indent: 首行缩进;
*/
.box {
  text-align: center;
  text-indent: 4em;
  line-height: 300px;
}
  • 文本装饰与转换:
/*
  text-decoration: 文本装饰(下划线、删除线等);
  text-transform: 文本大小写转换(uppercase, lowercase, capitalize);
  text-shadow: 文本阴影,可用于增加视觉层次;
*/
.box {
  text-decoration: overline;
  text-transform: uppercase;
}
  • 间距与换行(易错点)
/*
  letter-spacing/word-spacing: 字/词间距;

  white-space: 控制空白字符和换行(normal, nowrap, pre, pre-wrap, pre-line);
    * normal:空格和换行符合并。折行。默认行为。连续空格变一个,换行变空格。
    * nowrap:空格和换行符合并。不折行。强制文字在一行显示,直到遇到<br>。
    * pre:保留空格和换行符。不折行。行为类似<pre>标签。原样输出,不自动换行。
    * pre-wrap:保留空格和换行符,折行。最常用。既保留你的代码样式,又防止溢出容器。
    * pre-line:合并空格/保留换行符。折行。自动合并空格,但保留你手动敲的Enter换行。
  overflow-wrap(原word-wrap) & word-break: 控制长单词或URL如何换行;
  overflow-wrap: break-word: 在单词过长溢出时才断开;
  word-break: break-all: 强制在任意字符间断开(适合中文/混合排版)
*/
属性值核心行为视觉效果适用场景
overflow-wrap: break-word先换行,再断开。如果一个单词太长,先把它推到下一行,如果下一行还装不下,再断开单词。可能会在右侧留下一些空白,但单词相对完整。最推荐。个人博客、评论区、通用网页布局。
word-break: break-all不换行,直接断。不论是不是单词末尾,到了边界就地“斩首”。容器边缘非常整齐(对齐),但英文阅读体验极差。强制对齐的紧凑布局,或者处理纯随机字符/长URL。
word-break: keep-all绝不断开。只在半角空格或标点处换行。中日韩文字(CJK)不会在字间断开。主要是针对中日韩文本,防止中文在不该断的地方断开。

1.3 换行对比试验案例

html
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>CSS 换行属性对比 Demo</title>
    <style>
      body {
        font-family: sans-serif;
        line-height: 1.6;
        padding: 20px;
        background-color: #f4f4f9;
      }
      .container {
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
      }
      .box {
        width: 200px;
        background: white;
        border: 2px solid #333;
        padding: 10px;
        border-radius: 8px;
      }
      h3 {
        font-size: 14px;
        color: #e67e22;
        height: 40px;
        margin-top: 0;
      }
      p {
        background: #f0f0f0;
        margin: 0;
        font-size: 14px;
      }
      code {
        display: block;
        background: #333;
        color: #fff;
        padding: 4px;
        font-size: 12px;
        margin-bottom: 10px;
      }
      /* 关键 CSS 样式 */
      .normal {
        /* 默认值 */
      }
      .overflow-wrap {
        overflow-wrap: break-word;
      }
      .word-break {
        word-break: break-all;
      }
    </style>
  </head>
  <body>
    <h2>换行属性对比实验</h2>

    <div class="container">
      <div class="box">
        <h3>1. 默认 (Normal)</h3>
        <code>overflow-wrap: normal</code>
        <p class="normal">
          This is a normal sentence.
          Supercalifragilisticexpialidocious_is_a_long_word.
          https://www.thisisaveryveryverylongurl.com/test
        </p>
        <small style="color:red">结论:长单词和URL直接溢出了盒子</small>
      </div>

      <div class="box">
        <h3>2. 优雅断行</h3>
        <code>overflow-wrap: break-word</code>
        <p class="overflow-wrap">
          This is a normal sentence.
          Supercalifragilisticexpialidocious_is_a_long_word.
          https://www.thisisaveryveryverylongurl.com/test
        </p>
        <small style="color:green"
          >结论:先尝试换行,换行也放不下时才拆分长单词。保持了单词完整性。</small
        >
      </div>

      <div class="box">
        <h3>3. 暴力断行</h3>
        <code>word-break: break-all</code>
        <p class="word-break">
          This is a normal sentence.
          Supercalifragilisticexpialidocious_is_a_long_word.
          https://www.thisisaveryveryverylongurl.com/test
        </p>
        <small style="color:blue"
          >结论:到了边缘直接砍断。第一行的 normal
          甚至被拆开了,右侧没有留白,非常整齐。</small
        >
      </div>
    </div>
  </body>
</html>

1.4 深度解析:text-decoration

这是一个简写属性,现在包含了更多的细节控制:

/*
  text-decoration-line: 线条位置(underline, overline, line-through);
  text-decoration-style: 线条样式(solid, dashed, dotted, wavy);
  text-decoration-color: 线条颜色;
  text-decoration-thickness: 线条粗细(新属性);
  text-underline-offset: 下划线与文本的偏移距离(美化下划线的神奇);
*/

1.5 常见"坑"与注意事项

注意

    * 装饰线继承无法取消:如果父元素设置了text-decoration: underline,子元素设置text-decoration: none是无效的。装饰线会延伸到子元素。必须在父元素取消,或对子元素使用display: inline-block(视情况而定)等hack。

    * 长单词溢出:英文长单词URL默认不会自动换行,会导致撑破容器。必须配合overflow-warp: break-wordword-break: break-all

    * vertical-alignline-height:虽然不属于文本模块,但文本垂直对齐常受line-heightvertial-align(基线对齐)影响,容易导致图标文字不齐。

    * 简写重置:使用text-decoration: underline简写会重置colorstyle等默认值。若只想改颜色,应该使用text-decoration-color


2. 字体模块

  字体模块(CSS Fonts Module)和刚才的文本模块是"兄弟",文本模块管"排版布局",字体模块管"字形本身的长相"。 这一块的内容跨度很大,从最基础的"设置大小"到负责的"Web Font 性能优化"。


2.1 核心属性(必掌握)

/* 这四个是最常用的,必须熟练: */

/*
  font-family(字体家族):
    * 核心机制:"Fallback Stack"(回退栈)。浏览器会从左到右查找,直到找到用户电脑有的字体。
    * 最佳实践:始终在最后加上通用字体族(Generic Family),如`sans-serif`(无衬线)或`serif`(衬线)。
    * 例子:font-family: "Helvetica Neue", Arial, sans-serif;
*/

/*
  font-size(字体大小):
    * 关键点:单位的选择(详见下文"单位避坑")。
    * 默认值:浏览器默认通常是16px。
*/

/*
  font-weight(字重):
    * 数值 vs 关键词:normal = 400,bold = 700。
    * 坑:现在的网页设计常涉及100~900的细分字重(如:light, medium, black),但前提是你引入的字体文件必须包含这些字重,否则浏览器会"伪造"加粗,效果很丑。
*/

/*
  font-style:
    * 主要用于设置斜体(italic)。
    * 冷知识:oblique(倾斜)和italic(斜体不一样)。italic是专门设置的斜体字形,oblique只是把正体字强制歪过来。
*/

2.2 单位的"江湖"(重点 & 易错)

这是新手最容易的地方,建议直接背下这个结论:

单位类型特点推荐场景
px绝对单位精准,不随浏览器设置变化边框、固定尺寸装饰、极端精细排版
em相对单位也就是"当前元素的字体大小"。会有继承叠加问题(父 1.2 * 子 1.2 = 1.44)局部组件(如按钮 padding随文字缩放)
rem相对单位根元素(html)的字体大小。无叠加问题绝大数正文、标题字体大小(首选)
vw/vh视口单位随屏幕宽度变化仅用于超大标题或响应式排版
  • 建议:设置html {font-size: 100%;}62.5%(10px),然后正文全部用rem

2.3 进阶核心:@font-face(Web Fonts)

现代网页设计离不开自定义字体,但这里是性能杀手:

@font-face {
  font-family: "MyCustomFont",
  src: url('font.woff2') format('woff2'), /* WOFF2 压缩率最高,优先 */
       url('font.woff') format('woff');   /* WOFF 兼容性好 */
  font-display: swap; /* 关键属性! */
}
  • src顺序:把压缩率最高的woff2放前面,ttf这种大文件放后面或不写。
  • font-display: swap:非常重要。它告诉浏览器:在字体下载好之前,先用系统默认字体显示文字,下载好后再替换。防止出现文字隐形(FOIT)的情况。

2.4 常见"坑"与注意事项:

Tip

font简写属性的陷阱

    font是一个及其复杂的简写,必须包含font-sizefont-family顺序必须固定:font-style font-weight font-size/line-height font-family;

    坑:很多人写font 16px arial;觉得方便,但它会重置所有没写的属性(如:font-weight变回normal)。建议新手尽量分开写属性,除非你非常清楚自己在做什么。

"伪粗体"和"伪斜体"

    如果你设置了font-weight: bold但没有引入Bold版的字体文件,浏览器会根据算法文字描边加粗。这种"伪粗体"在很多设计精良的字体上会破坏美感。

系统字体差异

    同样的font-family: sans-serif,在Windows上是Arial/Microsoft YaHei,在Mac上是San Francisco / PingFang SC。如果要保证高度一致,比如用Web Font

移动端最小字号

    部分老旧浏览器或设置限制了最小字号(如Chrome曾限制最小12px),现在虽然可以通过transform: scale()解决,但设计时尽量避免小于12px的正文。


3. 行高

    虽然行高(line-height)是在文本模块中提到的属性,但它与字体和盒模型都有紧密关联,是CSS排版中最容易产生困惑的核心概念之一

行高


3.1 行高的定义与作用

A. 什么是行高?

  • 行高的严格定义是:两行文字基线(baseline)之间的距离
  • 基线(baseline):与小写字母x最底部对齐的线
  • 行高 (line-height)定义的是文本行的最小高度。它不是指字体本身的高度,而是占据的垂直空间

B. 核心机制:行盒(Line Box)

  • 在CSS渲染中,一行文字会形成一个看不见的"行盒(Line Box)"
    • line-height决定了这个行盒的总高度;
    • 多行文本时,每个行盒的总高度加起来就是整个文本块的总高;
    • 每一行文本都会生成一个独立的行盒(Line Box)多行文本是由多个行盒"垂直堆叠"而成的;

C. 如何影响文字垂直位置?

文字内容(如字母x)会在行盒内垂直居中:

行盒高度 = 字体大小 * 行高倍数

行高 = 字体大小 + 上半部分间距 + 下半部分间距,这些额外的间距(称为"半行距(Half-leading)")会被均匀分配文字的上方和下方这就是文字垂直居中的原理


3.2 单位与推荐用法(避坑指南)

行高可以使用长度单位(px, em, rem)或无单位数值,选择无单位数值是最佳实践

单位类型示例特点推荐度避坑说明
无单位数值
line-height: 1.5
最佳。值是字体大小的倍数。继承的是倍数。⭐⭐⭐⭐⭐首选! 子元素会根据自身字体大小计算行高,避免累积错误。
百分比line-height: 150%值是字体大小的百分比。继承的是计算后的像素值。⭐⭐不推荐。易产生累积继承问题,效果和 em 类似。
em/remline-height: 1.5em值是字体大小的倍数。继承的是计算后的像素值。⭐⭐不推荐。如果父元素设置了 1.5em,子元素又缩小了字体,但行高已经固定成了父元素的像素值,可能导致行高过大。
pxline-height: 24px固定的像素值。继承的是固定的像素值。⭐⭐不推荐。缺乏弹性,如果用户调整浏览器字体大小,排版会混乱。
  • 最佳实践:始终使用无单位数值(如1.5)
body {
  font-size: 16px;
  line-height: 1.5; /* 实际行高为 16px * 1.5 = 24px */
}

3.3 行高与垂直居中

行高在CSS布局中有两个特殊应用:

A. 单行文本垂直居中:这是利用行高的最常见技巧

  • 原理:当元素的height等于line-height时文本内容会完美地在垂直方向上居中
.button {
  height: 50px;
  line-height: 50px; /* 完美居中 */
  /* ...其他样式... */
}

B. 字体大小差异与基线对齐

    在同一行中,不同字体大小的元素(如文字和图标)会根据它们的基线对齐。由于行高会产生"半行距",这可能导致文字和图标无法对齐

  • 解决方案:对齐时,经常需要配合使用vertical-align属性,将其设置为middletop来微调对齐效果。

3.4 常见的"坑"与注意事项:

  • 行高不是marginpadding行高是垂直空间,但它不会像marginpadding一样计入元素的盒模型(即不会增加元素的背景色区域,除非它只包含文本)。

  • 基线错位:默认情况下,文字是基于基线(baseline)对齐的。当你把line-height设置得非常小非常大时,相邻元素的基线位置会发生剧烈变化,可能导致错位

  • 无单位继承问题使用无单位数值1.5继承得是倍数,这是正确的。但是如果使用150%1.5em继承的是父元素计算好的像素值,这才是坑

GPT回答:

/*
1. 什么是行高(line-height)?
 - line-height决定了一行文字的“行盒”的高度
 - 它包含了文字本身的高度(字体大小font-size) +  上下的行间距(leading)
*/

/* 例如:*/
/* 这里文字大小是16px,行高是24px,所以文字上下会各有(24-16) / 2 = 4px的空白; */
p {
  font-size: 16px;
  line-height: 24px;
}

4. 选择器

选择器是告诉浏览器"你要对哪一个或哪一组HTML元素应用样式"的机制

4.1 选择器基础分类(必须掌握)

分类示例说明特异性(优先级)备注
通用*匹配所有元素最低 (0)通常用于重置样式
元素 (类型)p, div, a匹配所有指定的元素标签低 (1)最基础的选择方式
类 (Class).main-nav匹配所有具有该 class 属性的元素中 (10)最常用,用于模块化
ID#header匹配具有该 id 属性的唯一元素高 (100)优先级极高,应谨慎使用
属性[type="text"]匹配具有特定属性/属性值的元素中 (10)常用于表单或自定义属性

4.2 复合选择器(Contextual Selectors)

这些选择器用于描述元素之间的关系

选择器语法含义示例
后代A B选择所有在 A 元素内的 B 元素 (不论层级)ul li
子代A > B选择直接在 A 元素下的 B 元素 (仅限一层)ul > li
相邻兄弟A + B选择紧接在 A 元素后的第一个 B 元素h1 + p
一般兄弟A ~ B选择所有跟在 A 元素后的 B 元素 (不必相邻)h1 ~ p

4.3 伪类与伪元素(Pseudo-classes & Pseudo-elements)

这是选择器的高级应用,用于选择元素在特定状态下或逻辑上存在的部分

📌伪类(Pseudo-classes) - 单冒号:

用于选择处于特定状态或位置的元素

  • 交互状态::hover, :focus, :active, :disabled, :checked(用于交互反馈和表单控制)。
  • 结构位置(重要且常用):
    • :first-child, :last-child:匹配一组兄弟元素中的第一个/最后一个;
    • :nth-child(n):匹配第n个子元素。(例如:li:nth-child(2n)匹配偶数行);
    • :not(selector):否定伪类,匹配不符合括号内选择器的元素。
  • 链接状态::link, :visited

📌伪元素(Pseudo-elements) - 双冒号::

用于选择元素逻辑上的特定部分,或者创建不存在的元素:

  • ::before, ::after:最重要。用于在内容前面或后面插入装饰线(比如配合content属性使用)。常用于清除浮动添加图标
  • ::first-letter, ::first-line:用于控制文本的第一行或第一个字。

4.4 优先级(特异性 Specificity)

当多个选择器选中同一个元素时,浏览器如何决定应用哪个样式?答案是特异性

特异性计算规则(4个维度,从左到右比较):

Specificity = (A, B, C, D)

  • A:!important声明(最高,应尽量避免使用)
  • B:ID选择器的数量(100);
  • C:类选择器属性选择器伪类的数量(10);
  • D:元素选择器伪元素的数量(1);

举例计算:

选择器特异性说明
p$(0, 0, 0, 1)$1 个元素选择器
.nav-link$(0, 0, 1, 0)$1 个类选择器
#main-header$(0, 1, 0, 0)$1 个 ID 选择器
div.item:first-child$(0, 0, 2, 1)$1 类 + 1 伪类 + 1 元素
[style="..."]内联样式最高,特异性比 ID 还高 (但通常不计入 A, B, C, D 公式)
  • 关键点:只有更高的数字才能覆盖。例如:1个ID(100)总是比100个类(10 * 10 = 100)优先级高!

4.5 常见"坑"与最佳实践

  • ID滥用:ID特异性过高,一旦使用,很难被低优先级的类覆盖现代CSS倾向于使用Class进行模块化和样式控制
  • 后代选择器性能:div p a这样的后代选择器在深层嵌套的DOM数中,匹配性能相对较差。虽然现在浏览器性能很好,但仍建议尽量使用>(子代选择器)或直接使用Class
  • :nth-child(n)误区:div:nth-child(2)意思是"选择父元素的第二个子元素,且类型必须是div",而不是"第二个div元素"(如果要选择第二个div元素可以使用: :nth-of-type)。
  • ::before/::after必须有content,如果不设置content: "",伪元素将不会生效。
nth-child与nth-of-type大白话理解:

nth-child(n):先数数,再对暗号:

    浏览器会把所有兄弟元素排成一队,不分青红皂白先给每一个元素发一个编号(1, 2, 3, ...);

    逻辑:找到第n个元素 -> 检查它是不是指定的类型。

    风险:如果第n个元素类型对不上,选择器就失效了。

nth-of-type(n):先分类,再数数:

    浏览器会先把元素按不同的标签类型(比如所有的div或所有的p)分到不同的"小组"里,然后在每个小组内部独立编号

    逻辑:在所有同类标签中 -> 找到第n个。

    优点:非常稳健,不会受到其他干扰元素(比如乱入的<span><img>)的影响。


4.6 代码演示

基础选择器

css
/* 属性选择器 */
[title] { ... }
[title=box] { ... }
[attr*=val] { ... } /* 属性值包含某一个值val */
[attr^=val] { ... } /* 属性值以val开头 */
[arrt$=val] { ... } /* 属性值以val结尾 */
[attr|=val] { ... } /* 属性值等于val或以val开头后面紧跟连接符- */
[attr~=val] { ... } /* 属性值包含val,如果有其他值必须以空格和val分割 */

/* 后代选择器 */
.foo .bar { ... } /* 后代选择器 */
.foo > .bar { ... } /* 子代选择器 */

/* 兄弟选择器 */
.foo + .bar { ... } /* 相邻兄弟选择器 */
.foo ~ .bar { ... } /* 普遍兄弟选择器 */

伪类

css
/* 伪类是选择器的一种,它用于选择处于特定状态的元素 */
/* 1.动态伪类 */
:link {...} /* 为访问的连接 */
:visited {...} /* 已访问的连接 */
:hover {...} /* 鼠标移动到元素上 */
:active {...} /* 激活后的连接(鼠标在连接上按住未松开) */
:focus {...}

/* 2.目标伪类 */
/*
  :target CSS 伪类表示一个唯一的元素(目标元素),其 id 与当前 URL 片段匹配。
  例如,以下 URL 具有一个片段(由 # 符号表示),指向名为 section2 的元素:
  http://www.example.com/index.html#section2
  若当前 URL 等于上面的 URL 时,以下元素将被 :target 选择器被选中:
  <section id="section2">Example</section>
*/
:target {...}

/* 3.语言伪类 */
/*
  *:lang(en-US) {
    outline: 2px solid deeppink;
  }

  <p lang="en-US">
    Music during road trips and long commutes aren’t a problem, but using
    headphones isn’t the best thing to do while driving in your car.
  </p>
*/
:lang() {...}

/* 4.元素状态伪类 */
:enabled {}
:disabled {}
:checked {}

/* 5.结构伪类 */
:nth-child()
:nth-last-child()
:nth-of-type()
:nth-last-of-type()
:first-child
:last-child
:first-of-type
:last-of-type
:root
:only-child
:only-of-type
:empty

/* 否定伪类 */
:not()

伪元素

/* 常见的伪元素有 */
/* 为了区分伪元素和伪类,建议伪元素使用2个冒号,反之 */
::first-line
::first-line
::first-letter
::first-letter
:before
::before
:after
::after

5. 盒子模型

  📦 盒模型(Box Model)是CSS布局的基石,理解了它,就掌握了CSS布局的百分之80%。所有的HTML元素在浏览器中都被视为一个个矩形的"盒子"


5.1 盒模型的结构

每个CSS盒子都由四个部分组成,从内到外分别是:

  • 内容区(Content):
    • widthheight属性设置,用于承载文本、图片等实际内容。
  • 内边距(Padding):
    • 内容区和边框之间的空间,用于填充内容,增加舒适度。
    • 属性:padding-top, padding-right, padding-bottom, padding-left或简写padding
  • 边框(Border):
    • 环绕内容和内边距的线。
    • 属性:border-width, border-style, border-color或简写border
  • 外边距(Margin):
    • 边框外侧的空间,用于控制元素与其他元素之间的距离。
    • 属性:margin-top, margin-right, margin-bottom, margin-left或简写margin
/* 👉 顺序口诀:上 → 右 → 下 → 左(顺时针) */
padding: 10px; /* 四边 */
padding: 10px 20px; /* 上下 左右 */
padding: 10px 20px 30px; /* 上 左右 下 */
padding: 10px 20px 30px 40px; /* 上 右 下 左 */

5.2 标准模式 vs. IE盒模型

在CSS3出现之前,盒模型的计算方式让很多开发者感到困惑,因此需要掌握两种模型:

A. 传统的W3C标准盒模型(默认)

计算方式

/*
  元素总宽度 = width + padding-left + padding-right + border-left-width + border-right-width + margin-left + margin-right
*/
  • 特性widthheight只定义内容区的大小。
  • 缺点:如果你设置了一个元素width: 200px,然后增加了padding: 10px,它的实际占用宽度会变成200 + 10 * 2 = 220px。这使得布局计算非常繁琐。

B. IE盒模型(现称:边框盒)

计算方式

/* 
  元素总宽度 = width + margin-left margin-right 
*/
  • 特性wdithheight定义的是内容区 + 内边距 + 边框的总和。
  • 优点:设置width: 200px并增加padding: 10px,它的实际内容区会自动缩小,但总占用宽度始终是200px。这极大地简化了布局计算

5.3 救星属性:box-sizing

为了解决标准模型的计算痛点,CSS引入了box-sizing属性,可以强制使用更方便的边框盒模型

属性值对应模型推荐度
content-box标准盒模型 (W3C 默认值)
border-boxIE 盒模型 (边框盒)⭐⭐⭐⭐⭐

    最佳实践(布局神器):几乎所有现代CSS项目都会在全局设置box-sizing: border-box,让布局计算变得可预测。

/* 开发者推荐的全局设置 */
*,
*::before,
*::after {
  box-sizing: border-box;
}

5.4 常见的"坑"与注意事项

外边距合并(Margin Collapsing) 这是盒模型中最容易出错的概念之一:

  • 定义:当两个垂直相邻的元素(兄弟元素父子元素、甚至空块级元素)的margin-topmargin-bottom相遇时,它们会合并成一个外边距--取两者中的较大值
  • 注意:水平外边距(左和右)永远不会合并
  • 解决/避免:使用paddingborder隔开、使用overflow: hidden、使用flexgrid布局。

内联元素不接受垂直属性

  • 内联元素(如span, a, strong)不支持设置width, height, margin-topmargin-bottom
  • 它们只受padding-left/right和margin-left/right影响。
  • 解决方案:如果你需要设置这些元素应用垂直尺寸,必须将其转换为块级或内联块级:
    • display: block;
    • display: inline-block;(最常用,即保持内容流又运行设置尺寸)

Padding的百分比计算:

  • padding(包括垂直和水平)使用百分比时,是基于父元素的width来计算的,而不是基于高度。
    • 用于:这是制作固定纵横比容器(如:16:9视频播放器)的关键技巧。
html
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>16:9 比例演示</title>
    <style>
      body {
        display: flex;
        gap: 20px;
        padding: 20px;
        font-family: sans-serif;
      }

      /* 父容器:固定 300px 宽度 */
      .parent {
        width: 300px;
        background-color: #eee;
        border: 2px dashed #999;
      }

      /* 方案 A:传统 Padding 技巧 */
      .ratio-padding {
        width: 100%;
        height: 0; /* 必须为 0 */
        padding-top: 56.25%; /* 9 / 16 = 0.5625 */
        background-color: #333;
        position: relative; /* 方便放入文字内容 */
      }

      /* 方案 B:现代 aspect-ratio 属性 */
      .ratio-modern {
        width: 100%;
        aspect-ratio: 16 / 9; /* 直接写比例,不用算 */
        background-color: #42b883;
      }

      /* 辅助样式:让内容铺满比例盒 */
      .content {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-size: 14px;
      }

      h4 {
        margin-bottom: 8px;
      }
    </style>
  </head>
  <body>
    <div>
      <h4>Padding 技巧 (16:9)</h4>
      <div class="parent">
        <div class="ratio-padding">
          <div class="content">300 x 168.75</div>
        </div>
      </div>
      <p><small>height: 0 + padding-top: 56.25%</small></p>
    </div>

    <div>
      <h4>现代属性 (16:9)</h4>
      <div class="parent">
        <div class="ratio-modern">
          <div
            style="height:100%; display:flex; align-items:center; justify-content:center; color:white;"
          >
            无需 height: 0
          </div>
        </div>
      </div>
      <p><small>aspect-ratio: 16 / 9</small></p>
    </div>
  </body>
</html>

5.5 总结

属性作用易错点
width/height内容区尺寸 (标准模型) 或 元素总尺寸 (边框盒)box-sizing 决定了它们的含义
padding内边距百分比基于父宽度计算
margin外边距垂直方向会合并 (Collapsing)
box-sizing模型切换建议全局设置为 border-box

6. 盒子和文字阴影

    盒子阴影(box-shadow)和文本阴影(text-shadow)在"效果"上非常相似,都用于增加元素的立体感和视觉层次,但它们在CSS模块中是分开的,作用的"对象"完全不同


6.1 文本阴影(text-shadow)

  作用对象:仅作用于元素的内容文本本身

语法结构:

/* 允许设置多层阴影,用逗号分隔 */
text-shadow:
  [水平偏移] [垂直偏移] [模糊半径] [颜色],
  [水平偏移] [垂直偏移] [模糊半径] [颜色];

参数说明:

  • 水平偏移(Required):阴影在X轴上的位置。正值向右,负值向左。
  • 垂直偏移(Required):阴影在Y轴上的位置。正值向下,负值向上。
  • 模糊半径(Optional):阴影的模糊程度。值越大,阴影越分散和柔和。
  • 颜色(Optional):阴影的颜色。

常见应用:

  • 让浅色文字在复杂背景上更容易阅读(增加一圈模糊的深色阴影)。
  • 创建霓虹灯、浮雕或3D文字效果。
代码示例
h1 {
  text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5); /* 黑色半透明阴影 */
}

6.2 盒子阴影(box-shadow)

这是在学习盒模型或视觉效果模块时应该掌握的属性,作用对象:作用于元素的整个盒子模型(内容、内边距和边框)

语法结构:

/* 允许设置多层阴影,用逗号分割 */
box-shadow: [inset?] [水平偏移] [垂直偏移] [模糊半径] [扩散半径] [颜色];

参数说明(比文本多一个参数):

  • inset(Optional):关键字,如果设置,阴影会变成内阴影(凹陷效果),默认时外阴影。
  • 水平偏移(Required):X轴位置。
  • 垂直偏移(Required):Y轴位置。
  • 模糊半径(Optional):模糊程度。
  • 扩散半径(Optional, NEW):比text-shadow多出的参数。正值会扩大阴影的尺寸,负值会缩小。
  • 颜色(Optional):阴影颜色。

常见应用:

  • 创建漂浮卡片效果,模拟高光和深度。
  • 使用inset制作内凹的输入框。
  • 使用多层阴影创建复杂的边框和光晕效果。
代码示例
/* 示例:外阴影 */
.card {
  /* x: 0, y: 4px, 模糊: 8px, 扩散: -2px, 颜色: 黑色半透明 */
  box-shadow: 0 4px 8px -2px rgba(0, 0, 0, 0.2);
}

/* 示例:内阴影 */
input:focus {
  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
}

6.3 核心差异总结

特性text-shadowbox-shadow
作用对象文字内容本身整个盒子元素 (Content, Padding, Border)
可否内嵌不可以可以 (inset 关键字)
扩散参数没有有 (扩散半径)
模块归属文本模块视觉效果/盒模型相关
继承性不继承 (需要单独设置)不继承 (需要单独设置)

7. 背景模块

  🖼️背景属性是创建视觉吸引力的关键,它控制着元素的背景色、背景图、重复方式和位置。现代CSS背景模块包含了一些非常强大的属性,特别是控制背景图片大小和定位方面


7.1 核心属性(简写与拆分)

background属性是一个非常常用的简写属性,它涵盖了7个独立的背景属性

属性名称作用简写属性中的顺序 (常用)
background-color设置背景颜色任意位置
background-image设置背景图片 (可多图,用逗号分隔)紧随 url() 函数
background-repeat设置背景图片是否重复以及如何重复紧随 background-image
background-position设置背景图片在元素中的起始位置紧随 background-repeat
background-size重点! 控制背景图片的尺寸position 后,用 / 分隔
background-attachment设置背景图片是否随页面滚动任意位置
background-origin设置背景图片定位的起点任意位置
background-clip设置背景颜色/图片裁剪的范围任意位置
Tip

background-originbackground-clip:

    三个值:padding-box(background-origin的默认值), border-box(background-clip的默认值), content-box

    background-origin:决定从哪里开始画(起点)。

    background-clip:决定在哪被裁剪(边界)。

    如果你设置了originborder-box(从边框开始画), 但clip设置为content-box(只在内容显示),那么最终你只能看到内容区那部分的背景,边框下的背景被剪掉了。

简写示例:

css
.hero {
  /* color image repeat position / size */
  background: #333 url(img.jpg) no-repeat center / cover;
}

7.2 关键属性深度解析(必须掌握)

background-size(响应式布局的关键)

这是控制背景图片如何在盒子中填充或缩放的属性,对于响应式设计至关重要:

属性值含义场景
contain
缩放图片以完全适应容器,不被裁剪。可能会留下背景色。(放缩一边到容器边缘停止!)保证 Logo 或重要图标完整显示。
cover缩放图片以完全覆盖容器,图片可能会被裁剪。全屏背景、英雄区 (Hero Section) 大图。
length (px, rem)固定宽高,如 300px 200px。背景纹理、固定大小的装饰图。
percentage (%)相对于容器的宽度和高度。保持比例缩放。

background-attachment(视差滚动效果)

  • 控制背景图的滚动行为:
    • scroll(默认):背景图随元素内容和页面一起滚动。
    • fixed:背景图固定在视口中,不随页面滚动。元素内容滚动过图片,可用于创建视差滚动(Parallax)效果。
    • local:背景图随元素的内容滚动(用于有滚动条的内层容器)。

background-clip(裁剪范围)

  • 它定义了背景(颜色或图片)应该延伸到的范围:
    • border-box(默认):覆盖边框、内边距和内容区;
    • padding-box:覆盖内边距和内容区,边框没有背景;
    • content-box:仅覆盖内容区;
    • text(实验性):将背景裁剪为文字的形状(常用于特殊视觉效果);

7.3 多重背景(Multiple Backgrounds)

  • CSS允许在一个元素上设置多张背景图,用逗号,分割。
  • 顺序原则:列表中的第一张在最上层,最后一张在最底层。
css
.multi-bg {
  background-image:
    /* 最上层(例如一个半透明叠加层) */
    url("overlay.png"),
    /* 底层 */ url("main-photo.jpg");

  /* 其他属性也需要按顺序或统一设置 */
  background-position:
    top left,
    center;
  background-repeat: no-repeat, no-repeat;
  background-size: 100%, cover;
}

7.4 常见的"坑"与最佳实践

  • 简写覆盖:使用background简写时,任何没有设置的值都会被重置为默认值。例如:如果你要只想设置颜色,写background: red;也会把background-image重置为none如果只想修改一个属性,请使用它的完整属性名称(如:background-color)。
  • background-position相对定位:默认的百分比值是相对于背景图的左上角。例如:background-position: 50% 50%不仅将图片水平垂直居中,而且是让图片中心与容器中心重合。

偏移距离 = (容器宽/高度 - 背景图宽/高度) × 百分比

  • 背景图和透明度:
    • 设置background-color: rgba(0, 0, 0, 0.5);可以获得一个半透明背景。
    • 注意:如果使用opacity: 0.5;,它会使整个元素(包括文字和子元素)都变得半透明。如果只想背景半透明,请使用rgba()颜色。
  • 无单位background-size:当background-size只设置一个长度值时,例如:background-size: 200px;,第二个默认值为auto,浏览器会根据图片的原始比例自动计算高度。

8. 定位模块

📍定位模块(position)是CSS布局中让元素"脱离文档流"的魔法棒。它能让元素自由地堆叠、覆盖或固定在屏幕的某个位置


8.1 核心属性:position

这个属性决定了元素如何定位。共有5个核心值:

属性值描述是否脱离文档流参照物(基准点)
static默认值。按照正常的文档流排列。top/left 等属性无效。
relative相对定位。相对于自己原来的位置进行微调。否 (原位保留占位)自身原始位置
absolute绝对定位。移出文档流,不占空间。最近的已定位 (非 static) 的祖先元素
fixed固定定位。钉在屏幕上,不随滚动条滚动。浏览器窗口 (视口)
sticky粘性定位。滚动到特定位置前是 relative,之后变成 fixed否/是 (动态切换)滚动容器

8.2 坐标属性与层级

只有当position不是static时,以下属性才生效:

  • 偏移量:top, bottom, leftright
    • 注意:topbottom同时设置时,通常top优先(取决于具体情况),建议只设置一个;
  • 层级:z-index:
    • 控制元素的堆叠顺序(谁压在谁上面);
    • 数值越大越靠上;
    • 坑:只有定位元素(positionstatic)的z-index才生效!;

8.3 核心口诀:子绝父相(必背)

这句中国前端圈最著名的布局口诀,用于解决"我想把一个图标精确地放在一个大盒子的右上角"这类问题

  • 子绝(Son Absolute):你想自由移动的子元素,设置为position: absolute
  • 父相(Father Relative):你想让子元素以此为边界的父元素,设置为position: relative
  • 原理:绝对定位(absolute)会向上寻找参照物。如果父元素没有定位,它就继续向上找爷爷...直到找到body。为了限制它只在父元素内跑,我们给父元素加上一个relative(因为它不脱离标准流,副作用最小),从而成为子元素的"参照锚点"。

8.4 常见的"坑"与注意事项:

A. absolute导致的父高度塌陷

  • 因为绝对定位元素脱离了文档流,它不再占有空间。
  • 如果一个父元素里只有绝对定位的子元素,父元素的高度会变成0。
  • 解决:必须给父元素显示设置高度,或者用JavaScript计算。

B. sticky不生效:

  • position: sticky必须配合至少一个方位值(如:top: 0)才能生效。
  • 如果它的父元素设置了overflow: hidden或auto,粘性定位通常会失效

C. fixed遇到transform:

  • 通常fixed是相对于浏览器窗口定位的。
  • 深坑:如果fixed元素祖先元素设置了transform(CSS变换)filter属性非none时,那么fixed元素会改为相对于这个祖先定位,导致固定效果失效

D. 居中大招(定位板)

在Flexbox普及之前,这是最强的居中方式(现在依然常用):

index.css
.center-box {
  position: absolute;
  top: 50%;
  left: 50%;
  /* 向坐上回退自身宽高的 50% */
  transform: translate(-50%, -50%);
}

9. 浮动

    🛁 这是一个充满"历史沉淀"的模块。在FlexboxGird出现之前,浮动(float)统治了网页布局十几年。虽然现在它作为主力布局方式已经退役,但在处理"图文环绕"维护老项目时,它依然是必修课。

    最重要的是:学习浮动主要是为了学习如何"清除"它带来的一系列副作用。


9.1 浮动的初心与本质

设计初衷:并不是为了布局,而是为了实现文字环绕图片的效果(像报纸排版那样)

  • 核心特性:
    • 脱离文档流:元素会"漂浮"在普通块级元素之上;
    • 向左/右挤压:浮动元素会一直向左或向右移动,直到碰到父元素的边缘或另一个浮动元素;
    • 文字环绕文字会围着浮动元素排列,而不会被覆盖(这是它与绝对定位最大的区别);

9.2 核心属性

开启浮动

  • float: left:向左浮动。
  • float: right:向右浮动。
  • float: none:不浮动(默认值)。

清除浮动(控制影响)

  • clear: left:元素的左侧不允许有浮动元素(强制换行)。
  • clear: right:元素的右侧不允许有浮动元素。
  • clear: both:两侧都不允许(最常用)。

9.3 最大痛点:高度坍塌(Height Collapse)

这是浮动模块中必须死记硬背的"坑":

  • 现象:如果一个父元素(容器)里面所有的子元素都浮动了,因为子元素脱离了文档流,父元素会觉得"我里面是空的",导致父元素高度变为0
  • 后果:父元素的背景色消失、边框缩成一条线、下面的布局直接跑上来被盖住。

9.4 清除浮动(Clearfix)

这是面试必考题,也是实战必备技巧。虽然有多种方法,建议掌握最标准的Clearfix Hack

方法一:BFC触发法(简单但有副作用)

给父元素添加overflow: hidden;

  • 原理:触发BFC(块级格式化上下文),强制父元素计算浮动元素的高度。
  • 缺点:如果子元素有定位并超出了父元素范围,超出的部分被剪裁掉

方法二:伪元素清除法(标准最佳实践):

给父元素添加一个.clearfix类。这是目前最主流、兼容性最好的方案。

index.css
<style>
  /* 建议加入到你公共CSS类库中 */
  .clearfix::after {
    content: "";  /* 必须有内容,哪怕是空的 */
    display: block;  /* 必须是块级元素 */
    clear: both;  /* 核心:清除两侧浮动 */
  }
</style>

<div class="container clearfix">
  <div class="float-left">...</div>
  <div class="float-right">...</div>
</div>

9.5 常见"坑"与注意事项:

  • 行内元素浮动后变块级:
    • 一旦给span等行内元素设置了float,它就会自动变成"块级框",可以设置widthheight了。不需要再写display: block
  • 浮动元素的重叠:
    • 浮动元素虽然脱离文档流,但它们之间是互斥的(不会重叠)。但如果空间不够,后面的浮动元素会被"挤"到下一行。
  • 不要用浮动做整个页面的布局:
    • 这是2015年以前的做法。现在请使用FlexboxGrid。现在float只建议用于单纯的"图片/图标在左,文字在右"的内部微小布局。

10. flex布局

flex布局

核心要点预览:

  • 一维布局思维:Flexbox处理的是"一条线"(行或列)上的排列。
  • 轴线翻转:flex-direction: column是移动端开发最常用的属性,但它会把主轴变成垂直方向
  • 完美居中:justify-content: center + align-items: center是现在的居中标准写法。
  • flex: 1:这是让子元素自动填充满剩余空间的"魔法属性"

10.1 核心概念

  • 一维布局:Flexbox最擅长处理一行或一列上的元素排列。
  • 父容器(Container) vs. 子元素(items):属性分为两组,一组给爸爸(控制整体),一组给孩子(控制个体)。
  • 主轴(Main Axis)与交叉轴(Cross Axis):这是Flexbox的灵魂。默认主轴是水平向右交叉轴是垂直向下
  • 关键:flex-direction会改变主轴的方向,随之justify-contentalign-items控制的方向也会

10.2 父容器属性(Container) - 必掌握

flex-direction:flex items默认是沿着main axis(主轴)从main start开始往main end方向排布

  • flex-direction决定了main axis的方向,有4个取值
  • row(默认值)、row-reversecolumncolumn-reverse

flex布局direction


flex-wrap

  • 决定了flex container单行还是多行
  • nowrap(默认):单行wrap:多行wrap-reverse:多行反转对比wrap,cross start与cross end相反)[改的是交叉轴的方向]

flex布局direction

  • align-items是控制单行的交叉轴排版,而align-content则是控制交叉轴多行的排版

justify-content:决定了flex-items在mian axis上的对齐方式

  • flex-start(默认值):与main start对齐
  • flex-end:与main end对齐
  • center居中对齐
  • space-between
    • flex items之间的距离相等
    • main startmain end两端对齐
  • space-aroud:
    • flex items之间的距离相等
    • flex itemsmain startmain end之间的距离是flex items之间距离的一半
  • space-evenly:
    • flex items之间的距离相等
    • flex itemsmian startmain end之间的距离等于flex items之间的距离

flex布局direction


align-items:

  • align-items决定了flex itemscross axis上的对齐方式
  • normal:在弹性布局中,效果和stretch一样
  • stretch:当flex itemcross axis方向的sizeauto时,会自动拉伸至填充flex container
  • flex-start:与cross start对齐
  • flex-end:与cross end对齐
  • center:居中对齐
  • baseline:与基线对齐

flex布局direction


align-content决定了多行flex items在cross axis上的对齐方式,用法与justify-content类似

  • stretch(默认值):与align-itemsstretch类似
  • flex-start:与cross start对齐
  • flex-end:与cross end对齐
  • center:居中对齐
  • space-between
    • flex items之间的距离相等
    • cross startcross end两端对齐
  • space-around
    • flex items之间的距离相等
    • flex itemscross startcross end之间的距离是flex items之间距离的一半
  • space-evenly
    • flex items之间的距离相等
    • flex itemscross startcross end之间的距离等于flex items之间的距离
属性说明
display: flex激活弹性布局。子元素自动变成flex-items,默认排成一行。
flex-direction: row | column | row-reverse | column-reverse(主轴方向)row(水平排列)、column(垂直排列)、row-reversecolumn(反向)
justify-content(主轴对齐)flex-start(靠起点)、center(居中)、flex-end(靠终点)、space-between(两端对齐,中间间距相等,首尾无间距)、space-around(环绕对齐,每个元素两侧间距相等)。
align-items(交叉轴对齐)strech(拉伸填满,默认,前提是子元素没有设置高度)、center(居中,垂直居中神器)、flex-startflex-end(靠上/靠下)
flex-wrap(换行)nowrap(不换行,默认,塞不下会压缩子元素)。wrap(允许换行)

10.3 子元素属性(items) - 进阶

  • flex简写属性(最常用):包含flex-grow, flex-shrink, flex-basis
    • flex: 1:意思是"所有剩余空间我都占了",或者大家平分。常用于自适应宽度。
    • flex: none固定尺寸,不可伸缩
  • align-self:
    • 允许某个特定的子元素覆盖父容器的align-items设置。
  • flex-item属性 - order
    • order决定了flex items的排布顺序
    • 可以设置任意整数(正整数、负整数、0),值越小就越排在前面
    • 默认值是 0

10.4 终极应用:完美居中

index.css
.container {
  display: flex;
  justify-content: center; /* 主轴居中 */
  align-items: center; /* 交叉轴居中 */
  height: 100vh; /* 确保有高度 */
}

10.5 常见"坑"

  • justify-content: space-between;失效:只有一行且填不满时才有效。如果只有1个子元素,他会靠左(start)或靠右(end)。
  • flex-direction: column;时的对齐:此时主轴变垂直了,justify-content变成控制垂直方向,align-items变成控制水平方向。切记!
  • 子元素文字溢出:在flex item中,长文本有时会导致布局撑开,需要设置min-width: 0overflow: hidden来修复。

10.6 复合属性总结

Flex布局
/* 1. flex */
.container {
  /* 单值仅无单位数字: flex-grow */
  /* 此时: flex-basis等于0 */
  flex: 1;

  /* 单值,宽度/高度:flex-basis */
  flex: 10px;

  /* 双值:flex-grow | flex-basis */
  flex: 1 30px;

  /* 双值:flex-grow | flex-shrink */
  flex: 2 2;

  /* 三值:flex-grow | flex-shrink | flex-basis */
  flex: 2 2 10%;

  /* 全局值 */

  flex: inherit;
  /* 
    元素会根据自身宽高设置尺寸。它会缩短自身以适应 flex 容器。
    但不会伸长并吸收 flex 容器中的额外自由空间来适应 flex 容器。
    相当于将属性设置为"flex: 0 1 auto"。
  */
  flex: initial;
  flex: revert;
  flex: revert-layer;
  flex: unset;

  /* 2. flex-flow */

  /* flex-flow 属性是 flex-direction 和 flex-wrap 的简写 */
  /* 单值 */
  flex-flow: row;
  flex-flow: nowrap;

  /* 双值 */
  flex-flow: row nowrap;
}

11. CSS形变与动画

🎬形变(Transform)、过度(Transition)和动画(Animation)这三剑客,让网页终于动起来了


11.1 核心一:形变(transfrom)

它不是动画,它是让元素改变形状、位置或角度的属性。它是静态的,除非你配合过度或动画使用:

  • 特点:使用transform移动元素性能极高(由GPU加速),不会触发布局重排(Reflow)。
  • 常用函数:
    • translate(x, y):平移。比top/left性能好得多;
      • 经典用法:translate(-50%, -50%)用于绝对定位居中。
    • scale(n):缩放。1是原始大小,1.5是放大1.5倍;
    • rotate(deg):旋转。例如:rotate(45deg);
    • skew(x-deg, y-deg):倾斜;
  • 基点(transform-origin):默认是中心点(center),可以改为top left等,决定了元素围绕哪里旋转或缩放。

11.2 核心二:过度(transition)

这是最简单的动画形式。它描述了从状态A变到状态B的过程

  • 触发条件:必须有状态变化触发(如:hover:focusJavaScript添加class)。
  • 语法:transition: [属性] [时间] [速度曲线] [延迟];
  • 常用简写:
index.css
.btn {
  background: blue;
  /* 所有属性在0.3秒内平滑过度 */
  transition: all 0.3s ease-in-out;
}

.btn:hover {
  background: red;
}

11.3 核心三:关键帧动画(animation + @keyframs)

如果需要元素自动运行,或者过程很复杂(A -> B -> C -> A),就需要用这个:

  • 第一步:定义剧本(@keyframes)
@keyframes bounce {
  0% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-20px);
  }
  100% {
    transform: translateY(0);
  }
}
  • 第二步:调用动画(animation)
/*
  填充模式:执行动画最后保留哪一个值
    * none:回到没有执行动画的位置
    * forward:动画回到最后一帧位置
    * backwards:动画第一帧的位置
*/

.ball {
  /* 动画名 | 时长 | 速度 | 延迟 | 次数 | 方向 | 填充模式 */
  animation: bounce 1s infinite;
}

.ball:hover {
  animation-play-state: paused;
}
  • animation-play-state:指定动画运行或暂停(在JavaScript中使用,用于暂停动画)。

11.4 常见"坑"与性能优化(非常重要)

A. 性能陷阱(Reflow vs Repaint)

  • 坑:很多新手喜欢用transition改变width, height, margin, top, left来做动画。
  • 后果:这些属性会触发重排(Reflow),浏览器要重新计算布局,很卡顿。
  • 最佳实践:只对transform(位置/大小)和opacity(透明度)做动画。这两个属性由GPU单独处理,丝般顺滑。

B. display: none无法过渡

  • 如果你把一个元素从display: none改为display: blocktransition是不会生效的(它会瞬间出现)。
  • 解决:使用opacity: 01,配合visibility: hidden
  • 现在一些浏览器开始有display: none的动画效果了。

C. 动画结束后的状态(animation-fill-mode)

  • 现象:动画播放完后,元素默认会瞬间跳回初始状态。
  • 解决:设置animation-fill-mode: forwards;,让元素停留在动画结束时的样子。

D. 行内元素的限制

  • transform属性对display: inline元素(如普通的<span>)是无效的。必须将其设为inline-blockblock

总结建议:

需求使用方案
鼠标移上去变色/变大transition (过渡)
加载时的转圈圈/弹跳球animation (关键帧动画)
将元素居中或旋转transform (形变)
移动元素位置优先用 transform: translate(),尽量不用 top/left

12. 画布与视口

画布与视口


13. Vertical-align

🚀官方文档的翻译:vertical-align会影响行内块级元素在一个行盒中垂直方向的位置


13.1 块级元素高度的真相:

  • 无内容:高度为0
  • 有内容:高度由内容撑起。
  • 核心机制:内容在块级容器中生成了Line Box(行盒)。行盒包裹了所有的inline-level(内联级别元素)。
  • 高度来源:内联元素的line-height决定了Line Box的高度,从而决定了父级div的高度。

13.2 什么是基线(Baseline)

  • 文本基线:字母"x"的下边缘。
  • 替换元素(如<img>):底边缘(margin-bottom边缘)。
  • inline-block元素:
    • 默认/有文字:最后一行文字的基线。
    • 无文字或设置了overflow: !visible;盒子的底边缘(margin-bottom边界)。

13.3 vertical-align的对齐标准

它是相对于父元素的基线来对齐的:

  • baseline(默认):元素的基线与父元素基线对齐。
  • middle:元素的中点与父元素基线加上x-height的一半对齐(近似垂直居中)。
  • top/bottom:与整个Line Box的顶部或底部对齐。

13.4 实战避坑指南

  • 图片底部的空隙:img默认是基线对齐,基线下方有留给字母g, j, p的下沉空间(descenders),所以图片底部会有几像素空白。
    • 解决办法:给img设置display: blockvertical-align: top/middle/bottom
  • 对齐失效:检查元素是否是inline-level。如果是块级元素,vertical-align不起作用。

14. FC与BFC

  1. 什么是BFC
  • FC(Formatting Context):页面中的一块渲染区域,有一套渲染规则。
  • BFC(Block Formatting Context):简单理解为一个绝对隔离的独立集装箱。在这个集装箱里面的元素布局,不会在空间上影响到外面的元素。
    • 也就是说block level box都是在BFC中布局的;
  • IFC(Inline Formattion Context):行内级元素的布局规则。
    • inline level box都是在IFC中布局的;

  1. 怎么触发BFC(开启集装箱)
  • overflow: hidden / auto / scroll(最推荐,副作用最小)。
  • display: flow-root(专门为了触发BFC诞生的新属性,无副作用,兼容性较新)。
  • float: left / right
  • position: absolute / fixed
  • display: inline-block / flex / grid

  1. BFC的四大神力(解决什么问题)

① 解决高度塌陷 (包含浮动)

  • 原理:计算BFC高度时,浮动元素也参与计算。
  • 场景:父元素没设置高度,子元素浮动导致父元素高度变0。

② 阻止 Margin 折叠 (消除间距重叠)

  • 规则:只有处于同一个BFC中的两个相邻块级盒子的上下margin才会折叠。
  • 解决方法:给其中一个盒子套一个外层div并触发其BFC,让两个盒子处于不同的BFC中。

③ 阻止元素被浮动元素覆盖 (自适应布局)

  • 规则:BFC的区域不会与浮动盒子重叠。
  • 应用:左侧一个浮动图片,右侧一个div。给右侧div触发BFC,它就会自动填满右侧剩余空间,而不会钻到图片下面去。

  1. 易错坑点:
  • overflow: hidden的风险:虽然好用,但如果子元素有需要"超出父容器"显示的阴影、下拉菜单、定位角标,会被无情切掉。
  • display: inline-block的间隙:虽然能触发BFC,但会带来空格间隙问题。
  • 绝对定位的BFC:绝对定位元素本身确实开启了BFC,但因为它脱离了文档流,所以它没法解决"父元素高度塌陷"的问题(因为父元素根本管不到它)。
扩展知识:

  我们已经学过了flex布局,其实,当我们给一个容器设置display: flex时,就已经开启了一个类似BFC的东西(叫FFC - Flex Formatting Context)。

  为什么Flex布局里没有Margin折叠?正是因为FFC(和BFC类似)改变了渲染规则。


15. 媒体查询

媒体查询核心语法(Media Queries)

/* 常用的方式是Mobile First(从小到大) */

/* 默认:移动端样式 */
.container {
  width: 80%;
}

/* 平板端(>=768px) */
@media (min-width: 786px) {
  .container {
    width: 750px;
  }
}

/* 桌面端(>= 1200px) */
@media (min-width: 1200px) {
  .container {
    width: 1170px;
  }
}

避坑与性能优化

  • 不要滥用@import:在CSS内部使用@import会增加HTTP请求延迟。推荐使用<link media='...'>,因为浏览器会优先下载当前屏幕匹配的CSS,而不匹配的CSS下载优先级会被降低。
  • 断点(Breakpoints)选什么?:不要针对特定手机型号(如iphone 14),要针对内容。常见的标准断点参考(Bootstrap标准):
    • 576px(小屏)768px(中屏 - 平板)992px(大屏 - 电脑)1200px(超大屏)
<!-- 方式一:使用media属性为<style>, <link>和<srouce>和其他HTML元素指定特定的媒体查询 -->
<link rel="stylesheet" media="(max-width: 600px)" href="./css/miniScreen.css" />

<style>
  /* 方式二:通过@media和@import使用不同的CSS规则 */
  @import url(./css/minScreen.css) (max-width: 600px);
</style>

<!-- 方式三:使用Window.matchMedia()和MediaQueryList.addListener()方法来测试和监控媒体状态 -->

<!-- 方式四:比较常用的是通过@media来使用不同的CSS规则,目前掌握这个即可 -->

媒体查询的新语法(Range Syntax)

现在浏览器支持更直观的写法了(像写数据不等式一样):

/* 旧写法 */
@media (min-width: 300px) and (max-width: 600px) { ... }

/* 新写法(更易读) */
@media (300px <= width <= 600px) { ... }

媒体特性(Media Features)

除了宽度,这两个也很常用:

  • orientation: andscape | portrait:横屏或竖屏;
  • prefers-color-scheme: dark:用户是否开启了系统的深色模式(现在网页做适配必备);

媒体查询 - 媒体类型

  • 在使用媒体查询时,必须指定要使用的媒体类型:
    • 媒体类型是可选的,并且会(隐式地)应用all类型;
  • 常见的媒体类型值如下:
    • all:适用于所有设备、print:适用于在打印预览模式下在屏幕上查看分页材料和分档、screen:主要用于屏幕、speech:主要用于语音合成器;
@media screen and (min-width: 320px) and (max-width: 375px) { ... }
@media screen and (min-width: 375px) and (max-width: 414px) { ... }
@media screen and (min-width: 414px) and (max-width: 600px) { ... }

16. 设备像素、逻辑像素和CSS像素

像素单位常见的有三种像素名称:设备像素(也称之为物理像素)、设备独立像素(也称之为逻辑像素)和CSS像素


16.1 物理像素(Physical Pixel)

  • 定义:屏幕上最小的显示单元,是硬件层面真实存在的点(即屏幕上的发光二极管点)。
  • 特性:
    • 每个物理像素只能显示一种颜色;
    • 不可直接控制,网页或App开发者无法指定它的数量,只能间接通过系统映射;
    • 一个物理像素可能由三个及以上的子像素构成。
  • 例子:
    • 一台iPhone 14 pro的物理分辨率是 2556 * 1179
    • 一台1080p显示器的物理分辨率是1920 * 1080

16.2 逻辑像素(Logical Pixel)

  • 定义:操作系统定义的虚拟像素单位,用来描述"设备坐标系"中一个点的大小。
  • 作用:逻辑像素是"操作系统和开发框架(如AndroidiosWindows)用于抽象屏幕坐标的单位,避免不同分辨率屏幕下控件太大或太小。
  • 映射关系:
    • 1逻辑像素 = n个物理像素
    • 其中n取决于设备的像素密度(DPI)或缩放因子(Scale Factor);
  • 示例:
    • Android上叫做dp(density-independent pixel);
    • ios上叫pt(point)
    • macOS/Windows上,系统缩放150%200%时,也体现为逻辑像素到物理像素的缩放;

16.3 CSS 像素(CSS Pixel)

  • 定义:在浏览器渲染页面时使用的基本单位(即CSS中的px)
  • 本质上等价于:网页渲染时的逻辑像素单位:
    • 即在浏览器中,逻辑像素 ≈ CSS像素;
index.css
/* 这表示元素宽高为100个CSS像素,但在高分屏上,1个CSS像素可能会用多个物理像素渲染 */
div {
  width: 100px;
  height: 100px;
}

16.4 三者之间的关系

物理像素(Physical Pixel)

 缩放系数 = 设备像素比(Device Pixel Ratio,DPR)

逻辑像素(Logical Pixel)≈ CSS 像素(CSS Pixel)

物理像素 = CSS像素 × 设备像素比(DPR)

📱 举例说明

设备物理分辨率DPRCSS视口大小(逻辑像素)关系
普通显示器1920×108011920×10801 CSS px = 1 物理 px
MacBook Retina2560×160021280×8001 CSS px = 2×2 物理 px
iPhone 14 Pro2556×11793852×3931 CSS px = 3×3 物理 px

16.5 扩展概念:设备像素比(DPR)

  • 定义:DPR = 物理像素 / CSS像素
  • 浏览器查看:window.devicePixelRatio
  • 作用:
    • DPR决定浏览器如何将CSS像素映射到物理像素;
    • DPR设备显示更清晰,但图像需要更高分辨率(例如:2x / 3x图);

16.6 总结对比表

名称层级定义可控性示例单位
物理像素硬件层屏幕真实像素点不可控屏幕发光点
逻辑像素系统层操作系统抽象单位半可控iOS pt / Android dp
CSS像素浏览器层网页布局单位可控CSS px

17. DPR、PPI、DPI


17.1 DPR(Device Pixel Ratio)设备像素比

  • 全称:Device Pixel Ratio
  • 层级:浏览器 / 操作系统层。
  • 定义:设备的物理像素与逻辑像素(或CSS像素)之间的比例。
  • 公式:DPR=物理像素(Physical Pixel) / CSS像素(CSS Pixel)。
  • 作用:
    • 用于告诉浏览器在渲染页面时,一个CSS像素需要映射多少个物理像素;
    • 在高分屏(Retina屏)上能显示更清晰的图像;
  • 开发者查看方法:window.devicePixelRatio
设备物理分辨率CSS 视口DPR
普通电脑1920×10801920×10801
MacBook Retina2560×16001280×8002
iPhone 14 Pro2556×1179852×3933

📱 总结:DPR 越高,显示越清晰,但网页和图像资源需要更高分辨率。


17.2 PPI(Pixels Per Inch)每英寸像素数

  • 全称:Pixels Per Inch

  • 层级:硬件层。

  • 定义:显示屏上每英寸包含的物理像素数量,是衡量屏幕精细度的核心指标。

  • 公式:PPI = √(水平像素² + 垂直像素²) ÷ 屏幕对角线英寸

  • 特点:

    • 数值越大,屏幕越细腻,像素越看不见;
    • 300 PPI 以上通常称为“Retina”级别(人眼难以分辨像素颗粒);
  • 例子:

# 一台 13" MacBook Pro(2560×1600):
PPI(2560² + 1600²) / 13 227

# iPhone 14 Pro(2556×1179,6.1 英寸):
PPI(2556² + 1179²) / 6.1 460

📺 总结:PPI 是硬件清晰度指标,与屏幕大小和分辨率有关。


17.3 DPI(Dots Per Inch)每英寸点数

  • 全称:Dots Per Inch
  • 层级:打印 & 显示设备。
  • 定义:
    • 在打印领域:表示打印机每英寸打印的墨点数量;
    • 在显示领域:有时与PPI混用,但更偏向输出密度;
  • 例子:
    • 打印机:
      • 普通办公打印机:300DPI
      • 专业图像打印机:1200DPI甚至更高;
    • 鼠标:
      • 鼠标的"DPI"其实指移动灵敏度(每英寸移动检测的点数),不是像素密度。

📠 总结:DPI 是“输出设备(打印或显示)分辨率”的概念;PPI 是“屏幕物理密度”;它们在数值意义上相似,但语义不同。


17.4 三者区别与联系

名称全称所属层级主要应用定义是否与物理尺寸有关
DPRDevice Pixel Ratio软件(浏览器 / 系统)网页渲染、前端开发物理像素 ÷ CSS 像素
PPIPixels Per Inch硬件(显示屏)屏幕清晰度每英寸的物理像素数量
DPIDots Per Inch输出设备(打印/显示)打印/鼠标/图像输出每英寸点数(或光学感应)

17.5 综合理解图

                    ┌────────────────────────────┐
         显示硬件层
 物理像素密度 = PPI (像素精细度) │
                    └────────────────────────────┘

                                 │(影响)

                    ┌────────────────────────────┐
       系统 / 浏览器层
 DPR = 物理像素 / CSS像素
                    └────────────────────────────┘

                                 │(影响网页缩放)

                    ┌────────────────────────────┐
         输出层/打印层
 DPI = 每英寸输出点密度
                    └────────────────────────────┘

18. 移动端适配

自适应:

  • 根据不同的设备屏幕大小来自动调整尺寸、大小;

响应式:

  • 会随着屏幕的实时变动而自动调整,是一种自适应;

18.1 认识移动端视口viewport

  • 因为移动端的网页窗口往往比较小,我们可能会希望一个大的网页在移动端可以完整的显示。
  • 所以在默认情况下,移动端的布局视口是大于视觉视口的。
  • 所以在移动端,我们可以将视口划分为三种情况:
    • 布局视口(layout viewport);
    • 视觉视口(visual layout);
    • 理想视口(ideal layout);

18.2 布局视口

  • 默认情况下,一个在PC端的网页在移动端会如何展示。
    • 第一,它会按照宽度为980px来布局一个页面的盒子和内容;
    • 第二,为了可以完整的显示页面,对整个页面进行缩小;
  • 我们相对于980px布局的这个视口,称之为布局视口(layout viewport)。
    • 布局视口的默认宽度是980px

18.3 视觉视口

  • 如果默认情况下,我们按照980px显示内容,那么右侧有一部分区域就会无法显示,所以手机端浏览器会默认对页面进行缩放以显示到用户的可见区域中。
  • 那么显示在可见区域的这个视口,就是视觉视口(visual viewport)。

18.4 理想视口

  • 如果所有的网页都按照980px在移动端布局,那么最终页面都会被缩放显示。
    • 事实上这种方式是不利于我们进行移动端的开发的,我们希望的是设置100px,那么显示的就是100px
  • 默认情况下的layout viewport并不适合我们进行布局。
  • 我们可以对layout viewport进行宽度和缩放的设置,以满足正常一个移动端窗口的布局
  • 这个时候可以设置meta中的viewport

18.5 移动端适配方案

方案一:百分比设置:

  • 为不同属性的百分比值,相对的可能是不同参照物。
  • 所以百分比在移动端适配中使用是非常少的。

方案二:rem单位+动态html的font-size:

  • 针对不同的屏幕,设置html不同的font-size。
  • 将原来要设置的尺寸,转化成rem单位。

方案三:vw单位


方案四:flex的弹性布局


19. Grid布局

    网格布局(Grid)是最强大的 CSS 布局方案:它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。以前,只能通过复杂的 CSS 框架达到的效果,现在浏览器内置

    Grid 布局与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别

    Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局Grid 布局则是将容器划分成"行""列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局Grid 布局远比 Flex 布局强大。


19.1 Grid布局的基本概念

采用网格布局的区域,称为“容器”。容器内部采用网格定位子元素,称为“项目”

<!--
  下面代码中,.container元素就是容器,内层的两个.item元素就是项目
  项目只能是容器的顶层子元素,不包含项目的子元素,比如第一个.item里面的p元素就不是项目,Grid布局只对项目生效!
-->
<box class="container">
  <box class="item">
    <p></p>
  </box>
  <box class="item"></box>
</box>

行和列

  • 从左到右称之为(row)。
  • 从上到下称之为(column)。

单元格

  • 行和列的交叉区域,称之为“单元格”(cell)。
  • 正常情况下,n行和m列会产生n * m个单元格。
  • 例如下图中的图片就是三行与三列,所以一共有 3 * 3 = 9个单元格。

网格线

  • 划分网格的线,称之为“网格线”(grid line)水平网格线划分出行垂直网格线划分出列
  • 正常情况下,n行有n + 1根水平的网格线m列有m + 1根垂直网格线。

网格线


19.2 Grid基本属性

grid-template-columns与grid-template-rows:

  • 容器指定了网格布局以后,接着就要划分列和行。grid-template-rows属性定义每一行的行高grid-template-columns属性定义每一行的列宽
  • repeat():有时候,重复写同样的值非常麻烦,尤其网格很多时。这个时候可以使用repeat()函数,简化重复的值:
    • 接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值(重复某种模式也是可以的);
    • repeat(3, 10px 20px 30px) = 10px 20px 30px 10px 20px 30px 10px 20px 30px;
Grid布局
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <style>
      .container {
        width: 500px;
        height: 500px;
        background-color: #333;

        display: grid;
        grid-template-columns: 100px 100px;
        grid-template-rows: 100px 100px;
        gap: 30px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
    </div>

    <script>
      function randomColor() {
        return Math.floor(Math.random() * 256);
      }

      console.log(`rgb(${randomColor()}, ${randomColor()}, ${randomColor()});`);

      const items = document.querySelectorAll(".item");

      items.forEach((e) => {
        e.style.backgroundColor = `rgb(${randomColor()}, ${randomColor()}, ${randomColor()})`;
      });
    </script>
  </body>
</html>

grid-template:

  • grid-templategrid-template-columnsgrid-template-rowsgrid-template-areas三个属性的缩写:
  • 具体用法下面有讲解,这里先简单了解有个印象即可。
css
.container {
  grid-template: 100px 1fr 50px / 200px 1fr;
  /* 等价于 */
  grid-template-rows: 100px 1fr 50px;
  grid-template-columns: 200px 1fr;
}

/* ------------------------------------- */
.container {
  grid-template:
    "header header" 80px
    "sidebar main" 1fr
    "footer footer" 60px
    / 250px 1fr;
}
/* 等价于 */
.container {
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-rows: 80px 1fr 60px;
  grid-template-columns: 250px 1fr;
}

19.3 auto-fill与auto-fit关键字

  • 有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充
  • 两者的行为基本是相同的。只有当容器足够宽,可以在一行容纳所有单元格时,并且单元格宽度不固定的时候,才会有行为差异,auto-fill会用空格子填满剩余宽度auto-fit则会尽量扩大单元格的宽度
  • 重点auto-fillauto-fit 几乎总是需要配合 minmax() 使用,这是最佳实践
    • grid-template-columns: repeat(auto-fit, 200px) /* 这样写没有意义 */
    • 轨道固定为200px,无法响应式调整、无法充分利用可用空间、失去了自动布局的核心优势
Grid布局
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <style>
      .container {
        display: grid;
        gap: 10px;
        margin-bottom: 20px;
        background: #f0f0f0;
        padding: 10px;
      }

      .auto-fill {
        grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
      }

      .auto-fit {
        grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
      }

      .item {
        background: #4caf50;
        padding: 20px;
        text-align: center;
        color: white;
      }
    </style>
  </head>
  <body>
    <div class="container auto-fill">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
    </div>

    <div class="container auto-fit">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
    </div>
  </body>
</html>

fr关键字

  • 为了方便表示比例关系,网格布局提供了fr关键字(fraction的缩写,意为“片段”)。
  • fr可以与绝对长度的单位结合使用grid-template-columns: 150px 1fr 2fr;

minmax()

  • minmax()函数产生一个长度范围,表示长度就在这个范围之内。它接受两个参数,分别是最小值和最大值
  • 一般结合auto-fillauto-fit使用:
    • repeat(auto-fill, minmax(200px, 1fr));

给网格线命名

  • grid-template-columns: [c1 mio] 100px [c2] 100px [c3] 100px [c4];
  • grid-template-row: [r1] 100px [r2] 100px [r3] auto [r4];
  • 上面代码指定网格布局为3 * 3,因此有4根垂直网格线4根水平网格线方括号里面依次是这八根线的名字。网格布局允许一根线有多个名字,比如[c1 bar]

gap属性

  • gap是column-gaprow-gap的简写属性

area

  • grid-areagrid-template-areas两者需要配合使用
  • grid-area用在子项,给子项命名,grid-template-areas用在容器上
  • 某些不需要的单元格可以使用.来占位
  • 响应式布局的“降维打击”
    • 这是它最强大的地方。当屏幕变小时(手机端),你不需要修改每个子元素的 CSS,只需要修改父元素的“地图”:
Gird布局
@media (max-width: 600px) {
  .container {
    /* 手机端:全部变成一列,垂直堆叠 */
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "footer";
  }
}
html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <style>
      .container {
        width: 500px;
        height: 500px;
        background-color: #333;

        display: grid;
        grid-template-areas:
          "one one one one"
          "two three three three"
          "two four four ."
          "two five five five";
        gap: 10px;

        .item:nth-child(1) {
          grid-area: one;
        }

        .item:nth-child(2) {
          grid-area: two;
        }

        .item:nth-child(3) {
          grid-area: three;
        }

        .item:nth-child(4) {
          grid-area: four;
        }

        .item:nth-child(5) {
          grid-area: five;
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
    </div>

    <script>
      function randomColor() {
        return Math.floor(Math.random() * 256);
      }

      console.log(`rgb(${randomColor()}, ${randomColor()}, ${randomColor()});`);

      const items = document.querySelectorAll(".item");

      items.forEach((e) => {
        e.style.backgroundColor = `rgb(${randomColor()}, ${randomColor()}, ${randomColor()})`;
      });
    </script>
  </body>
</html>

grid-auto-flow属性

  • 划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格中。默认的放置顺序是“先行后列”,即先填满第一行,再开始放入第二行
  • 默认值row:即“先行后列”,也可以设置成column,变成先列后行
  • 还可以设置row densecolumn dense。某些项目指定位置以后,剩下的项目怎么自动放置,并且尽可能紧密填满,尽量不出现空格。

grid-auto-flow


justify-items、align-items和place-items属性

如果子项目自己的大小,那么设置的就是子项目在自己单元格中的布局位置

  • justify-items属性设置单元格内容水平位置(左中右)
  • align-items属性设置单元格内容的垂直位置(上中下)
  • place-items属性是align-items属性和justify-items属性的合并简写形式
css
/**
    start: 对齐单元格的起始边缘
    end: 对齐单元格的结束边缘
    center: 单元格内部居中
    stretch: 拉伸,沾满单元格的整个宽度(默认值)
*/
.container {
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}

justify-content、align-content和place-content属性

如果整个网格的大小小于容器的大小,那么设置的就是整个网格容器中的位置

  • justify-content属性是整个内容区域在容器里面的水平位置(左中右)
  • align-content属性是整个内容区域在容器里面的垂直位置(上中下)
  • place-content属性是align-content属性和justify-content属性的合并简写形式
css
.container {
  justify-content: start | end | center | stretch | space-around | space-between
    | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between |
    space-evenly;
}

place-content: end

grid-auto-flow


grid-auto-columns和grid-auto-rows属性

css
.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
  /* 指定在3 * 3的网格布局中,新增的一行的高度为固定的50px(原始行高为100px) */
  grid-auto-rows: 50px;
}

项目属性

  • grid-column-startgrid-column-endgird-row-startgrid-row-end属性
    • 项目的位置是可以指定的,具体方法就是指定项目的四个边框,分别定位在哪根网格线
    • grid-column-start属性:左边框所在的垂直网格线
    • grid-column-end属性:右边框所在的垂直网格线
    • grid-row-start属性:上边框所在的水平网格线
    • gird-row-end属性:下边框所在的水平网格线
  • span关键字
    • 表示跨越,即左右边框(上下边框)之间跨越多少个网格
  • grid-columngrid-row属性
    • grid-column属性是grid-column-startgrid-column-end的合并简写形式
    • grid-row属性是grid-row-startgrid-row-end的合并简写形式
html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <style>
      .container {
        width: 600px;
        height: 600px;
        background-color: #ccc;

        display: grid;
        grid-template: repeat(3, 1fr) / repeat(3, 1fr);

        gap: 10px;

        .item:nth-child(1) {
          grid-column: 2 / 4;
        }

        .item:nth-child(4) {
          grid-column: 3 / span 1;
          grid-row: span 2 / 4;
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
      <div class="item">6</div>
    </div>

    <script>
      function randomColor() {
        return Math.floor(Math.random() * 256);
      }

      console.log(`rgb(${randomColor()}, ${randomColor()}, ${randomColor()});`);

      const items = document.querySelectorAll(".item");

      items.forEach((e) => {
        e.style.backgroundColor = `rgb(${randomColor()}, ${randomColor()}, ${randomColor()})`;
      });
    </script>
  </body>
</html>

justify-self、align-self和place-self属性

  • justify-self属性设置单元内内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目
  • align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目
  • place-self属性是align-self属性和justify-self属性的合并简写形式