Vanson's Eternal Blog

CSS夯实基础

Css basic.png
Published on
/51 mins read/---

CSS

Basic

为什么初始化CSS样式?

浏览器的默认样式差异

不同浏览器对HTML元素的默认样式(如margin、padding等)有所不同。如果不进行初始化,可能会导致页面在不同浏览器中显示不一致。

提高页面一致性

通过初始化CSS样式,可以确保在不同浏览器中页面的显示效果更加一致,减少因浏览器默认样式差异带来的问题。

优化布局和设计

初始化样式可以清除不必要的默认样式,使布局和设计更加灵活,便于开发者实现预期的设计效果。

初始化CSS样式对SEO的影响

初始化CSS样式可能会对SEO产生一定的影响,但这种影响通常较小。通过合理设置,可以在确保页面显示一致性的前提下,尽量减少对SEO的影响。

margin 和 padding 场景?

margin是用来隔开元素与元素的间距;padding是用来隔开元素与内容的间隔。

margin用于布局分开元素使元素与元素互不相干。

padding用于元素与内容之间的间隔,让内容(文字)与(包裹)元素之间有一段距离。

何时应当使用margin:

  • 需要在border外侧添加空白时。
  • 空白处不需要背景(色)时。
  • 上下相连的两个盒子之间的空白,需要相互抵消时。如15px+20px的margin,将得到20px的空白。

何时应当时用padding:

  • 需要在border内测添加空白时。
  • 空白处需要背景(色)时。
  • 上下相连的两个盒子之间的空白,希望等于两者之和时。如15px+20px的padding,将得到35px的空白。

什么是包含块?

元素用来计算位置和尺寸的参考空间。

  • 初始包含块:

    • 根元素(通常是<html>)建立。
    • 尺寸等于浏览器可视窗口。
    • 用于position: fixed元素的定位。
  • position: static或position: relative:

    • 包含块是其最近的块级容器祖先的content box。
  • position: absolute:

    • 包含块由最近的position不为static的祖先元素建立。
    • 如果祖先元素是块级元素,包含块是祖先的padding box。
    • 如果祖先元素是纯内联元素,规则较复杂(通常不推荐使用)。
    • 如果没有符合条件的祖先元素,退回到初始包含块。
  • position: fixed:

    • 包含块始终是初始包含块(浏览器窗口)。

注意:

  • 内联元素(display: inline)作为祖先时,包含块可能未定义(浏览器自行处理)。
  • CSS3中,transform、filter等属性也可以创建包含块。

CSS3新特性

  • 新增各种CSS选择器 (:not(.input):所有class不是“input”的节点)
  • 圆角 (border-radius:8px)
  • 多列布局 (multi-column layout)
  • 阴影和反射 (Shadow\Reflect)
  • 文字特效 (text-shadow)
  • 文字渲染 (Text-decoration)
  • 线性渐变 (gradient)
  • 旋转 (transform)
  • 缩放,定位,倾斜,动画,多背景

什么是 FOUC

是一种网页加载时出现的现象,即在样式表(CSS)加载完成之前,页面内容会以无样式(或默认样式)的形式短暂显示,随后在样式表加载完成后重新渲染为正确的样式。这种现象被称为“无样式内容闪烁”或“样式短暂失效”。

避免 FOUC 的方法

将样式表放在文档的 <head>

确保样式表在页面加载时尽早被加载和解析,从而减少无样式内容的显示时间。

避免使用 JavaScript 动态加载样式表

动态加载样式表可能导致样式表加载时间延迟,从而引发 FOUC。

确保样式表加载速度

  • 优化样式表文件:通过压缩 CSS 文件、减少不必要的样式和选择器,提高样式表的加载速度。
  • 使用 HTTP 缓存:确保浏览器缓存样式表文件,避免重复下载。
  • 使用 HTTP/2:HTTP/2 支持多路复用,可以减少资源加载的延迟。

使用 CSS 预加载(Preload)

<head>
  <link rel="preload" href="styles.css" as="style">
</head>

选择器权重

!important > 内联样式 > ID选择器 > 类选择器 = 伪类选择器 = 属性选择器 > 标签选择器 = 伪元素选择器 > 通用选择器

  • !important:最高权重
  • 内联样式:1000
  • id选择器:100
  • 类选择器:10
  • 属性选择器:10
  • 伪类选择器:10
  • 标签选择器:1
  • 伪元素选择器:1
  • 相邻兄弟选择器:0
  • 子选择器:0
  • 后代选择器:0
  • 通配符选择器:0

怎么覆盖 !important

1、只需再添加一条 带 !important 的 CSS 规则,再给这个给选择器更高的优先级(添加一个标签,ID 或类);或是添加一样选择器,把它的位置放在原有声明的后面。

table td {
  height: 50px !important;
}
.myTable td {
  height: 50px !important;
}
#myTable td {
  height: 50px !important;
}
 
 

2、使用相同的选择器,但是置于已有的样式之后。

td {
  height: 50px !important;
}
 
 

可继承和不可继承样式

可继承

文本样式

  • color
  • font-family
  • font-size
  • font-style
  • font-weight
  • line-height
  • text-align
  • text-indent
  • text-transform:用于控制文本的大小写转换
  • white-space
  • letter-spacing
  • word-spacing

其他可继承属性

  • visibility
  • cursor
  • direction
  • tab-size:用于控制文本中的水平制表符的显示效果

不可继承

布局相关

  • display
  • position
  • float
  • clear
  • overflow
  • z-index
  • width, height
  • min-width, max-width
  • min-height, max-height

边框和背景

  • border
  • background
  • background-color
  • background-image
  • background-size
  • background-position
  • background-repeat

间距相关

  • margin
  • padding
  • box-sizing

其他不可继承属性

  • content
  • counter-reset, counter-increment
  • list-style, list-style-type, list-style-image
  • opacity
  • transform
  • transition
  • animation

如果需要显式继承或取消继承,可以使用:

  • inherit:显式继承父元素的值。
  • initial:将属性值重置为默认值。
  • unset:对于可继承属性,等同于 initial;对于不可继承属性,等同于 inherit。

block和inline的区别?

  • block:独占一行,可设置宽高、margin、padding
  • inline:不独占一行,不可设置宽高,可设置水平margin、padding但不能设置垂直方向margin、padding

隐藏元素的方式和区别?

  • display: none:完全隐藏,不占空间。当你完全不需要该元素占据空间时使用,例如隐藏一个按钮或隐藏一个未使用的模块。
  • visibility: hidden:隐藏但占空间。当你需要保留元素的空间,但暂时不想显示内容时使用,例如隐藏一个占位符或隐藏一个未启用的功能模块。
  • opacity: 0:透明但占空间。当你需要保留元素的空间,并且希望元素在某些情况下可以通过透明度变化重新显示时使用,例如实现淡入淡出效果。
  • position: absolute + 移出范围:隐藏在页面外,保留可访问性。常用于隐藏辅助性内容(如屏幕阅读器专用内容),同时保留元素的可访问性。
  • z-index: -999:不推荐,可能导致布局问题。不太推荐使用,因为这种方法可能会导致不可预测的布局问题

link和@import区别

好的,以下是Markdown表格的源码,你可以直接复制并使用:

特性<link>@import
用途加载CSS、RSS、图标等只能加载CSS
加载时机并行加载,页面加载时串行加载,页面加载后
兼容性所有浏览器支持现代浏览器支持,低版本浏览器可能不支持
可操作性可通过JavaScript操作DOM不能直接操作,但可通过修改CSS内容间接操作
性能更快(并行加载)较慢(串行加载)

RSS(Really Simple Syndication)是一种用于发布和订阅内容的标准化Web格式,通常用于在线新闻、博客、播客(Podcast)、视频等的更新推送。RSS的核心功能是允许用户通过一个统一的界面(RSS阅读器)订阅多个网站的内容更新,而无需频繁访问每个网站。

transition和animation的区别?

  • transition:过度样式,需要被动触发
  • animation:动画样式,不需要被动触发,可以自动触发,可结合@keyframe进行多个关键帧的动画

伪元素和伪类

伪元素:顾名思义,假的元素,只会显示其内容,但是并不会在dom树中找到他

 
p::before {content:"林三心";}
p::after {content:"林三心";}
p::first-line {background:red;}
p::first-letter {font-size:30px;}
 

伪类:将一些效果加到节点上,例如鼠标点击,悬浮等

a:hover {color: #FF00FF}
p:first-child {color: red}
 

盒模型?

  • 标准盒模型:width、height的计算范围只包含content
  • IE盒模型:width、height的计算范围包含content、padding、border

通过box-sizing进行设置

  • box-sizing: content-box 标准盒模型(默认)
  • box-sizing: border-box IE盒模型(怪异盒模型)

CSS提升性能方式?

CSS代码压缩

减少CSS文件的体积,加快加载速度。

  • 删除多余空格和换行:移除不必要的空格、换行符和注释。
  • 简写属性:使用简写形式(如 margin、padding、background)代替冗长的属性。
  • 工具支持:使用工具如 CSSNano 或 UglifyJS 自动压缩CSS代码。
/* 原始代码 */
body {
  font-family: Arial, sans-serif;
  background-color: #f0f0f0;
  padding: 20px;
  margin: 0;
}
 
/* 压缩后 */
body{font-family:Arial,sans-serif;background-color:#f0f0f0;padding:20px;margin:0}
 

使用 link 代替 @import

减少页面加载时间,避免阻塞渲染。

  • link 是并行加载,浏览器会在页面加载时同时加载CSS文件。
  • @import 是串行加载,会阻塞页面的进一步加载,直到当前CSS文件加载完成。
<!-- 推荐 -->
<link rel="stylesheet" href="styles.css">
 
<!-- 不推荐 -->
<style>
  @import url("styles.css");
</style>

避免多层选择器

减少CSS解析时间和重绘/重排的开销。

  • 减少选择器嵌套深度:尽量避免超过3层的选择器嵌套。
  • 使用类选择器:类选择器的性能优于ID选择器和标签选择器。
  • 避免过度使用通配符选择器(*):通配符选择器会匹配页面上所有元素,性能开销较大。

动画GPU加速

提高动画性能,减少卡顿,提升用户体验。

  • 使用 transform 和 opacity:这些属性可以通过GPU加速,性能优于 left、top 等属性。
  • 触发GPU加速:通过 will-change 或 translateZ(0) 等技巧,将动画元素的渲染任务交给GPU处理。
  • 避免过度使用动画:复杂的动画可能会导致页面卡顿,尤其是同时运行多个动画时。

为何使用less、sass?

他们是css预处理器,使用他们的变量、继承、运算、函数等功能,大大提高样式编写效率,大多数打包工具最后都会将他们解析为原始css样式代码

postCss ?

使用 JavaScript 插件来转换 CSS 的工具。它本身并不直接处理 CSS,而是通过插件来实现各种功能,比如自动添加浏览器前缀、支持未来的 CSS 特性、优化代码、检查错误等。

  • PostCSS 本身是一个工具:它通过解析 CSS 文件,将其转换为抽象语法树(AST),然后通过插件对 AST 进行操作,最后将修改后的 AST 转换回 CSS。
  • 插件系统:PostCSS 的强大之处在于它的插件生态系统。开发者可以根据需要选择和组合不同的插件来实现特定的功能。

实现 单行和多行 溢出省略号?

单行

overflow: hidden; 
text-overflow: ellipsis;
white-space: nowrap;

多行

overflow: hidden;  #隐藏超出容器范围的内容。
text-overflow: ellipsis; #在文本超出容器时,在末尾显示省略号(...)。
display: -webkit-box; #将元素的显示类型设置为弹性盒模型(Flexbox)。
-webkit-box-orient: vertical; #设置弹性盒模型的方向为垂直。
-webkit-line-clamp: 3; #限制文本显示的行数。
 

自适应布局方式

媒体查询@media:通过监听不同的窗口宽度,展示不同的效果 rem:监听不同窗口宽度,为根节点设置对应font-size,并进而使所有使用到rem的样式得到变化(rem的“r”就是“root”)

布局方式

实现居中

内链元素水平居中:line-height + text-align

块级元素水平居中:margin + auto

多块级元素水平居中

flex-row 居中

flex-col 居中

grid居中

table-cell 居中

子绝父相 + transform

子绝父相 + margin:auto

两栏布局

左边固定,右边自适应

Flexbox 实现

Grid 实现

浮动(Float)实现

三栏布局

左右固定,中间自适应

flex实现

grid实现

position + margin 实现

table实现

圣杯布局

sfy-sb-2025-07-04-15-40-46

特点:

  • 左右两边固定宽度,中间自适应。
  • 通过设置外层容器的 padding 和左右栏的 margin 来实现布局。
  • 中间内容区通过 padding 避免被左右栏覆盖。

实现方式:

  • HTML结构:header、container(包含左栏、中栏、右栏)、footer。
  • CSS:左栏和右栏使用浮动,中间栏通过外层容器的 padding 来预留空间

float实现

flex实现

grid实现

双飞翼布局

特点:

  • 左右两边固定宽度,中间自适应。
  • 中间内容区通过内嵌的 inner 容器和 margin 来避免被左右栏覆盖。

实现方式:

  • HTML结构:与圣杯布局类似,但在中间栏内嵌套一个 inner 容器。
  • CSS:左栏和右栏使用浮动,中间栏通过内嵌的 inner 容器和 margin 来实现内容显示

float实现

flex实现

grid实现

多列等高实现

table-cell实现

flex实现

margin+padding实现

清除浮动方式?

  • 给父元素定义高度:不建议,会导致其他布局问题
  • 末尾空div并设置clear:both不建议,增加无用dom节点
  • 父元素设置overflow:hidden不建议,会导致部分内容被隐藏
  • 使用伪元素after+clear:both强烈推荐

推荐:通过在父容器的末尾添加一个伪元素 ::after,并设置 clear: both,可以清除浮动的影响,使父容器的高度能够正确计算。

<div class="container">
  <div class="float-left">Left Float</div>
  <div class="float-right">Right Float</div>
</div>
/* 清除浮动的clearfix方法 */
.container::after {
  content: ""; /* 必须设置content属性 */
  display: block; /* 或者 display: table; */
  clear: both; /* 清除浮动 */
}
 
/* 浮动样式 */
.float-left {
  float: left;
  width: 200px;
  background-color: lightblue;
  padding: 20px;
}
 
.float-right {
  float: right;
  width: 200px;
  background-color: lightcoral;
  padding: 20px;
}

zoom: 1 的清除浮动原理

触发 hasLayout:

  • 在 IE 浏览器中,zoom: 1 可以触发元素的 hasLayout 属性。
  • hasLayout 是 IE 的一个内部属性,当元素拥有 hasLayout 时,它会成为一个独立的渲染单元,可以解决许多布局问题,例如浮动元素导致的父元素高度塌陷问题。

解决浮动问题:

  • 当子元素浮动时,父元素的高度可能会塌陷(即父元素的高度无法自动包含浮动子元素)。
  • 通过设置 zoom: 1,父元素会重新计算高度和宽度,从而包含浮动子元素。

浮动

特点

  • 脱离文档流:浮动元素会脱离正常的文档流,不再占据原来的位置,因此不会影响后续元素的布局。
  • 向左或右浮动:通过设置 float: left 或 float: right,元素会向左或右移动,直到碰到父容器的边界或其他浮动元素。
  • 形成块级框:浮动元素会生成一个块级框,即使它的原始显示类型是行内元素(如 <span>)。
  • 与其他浮动元素堆叠:多个浮动元素会依次排列,形成一行或多行,直到父容器的宽度不足以容纳更多浮动元素。
  • 文本环绕:非浮动元素(如文本或其他块级元素)会环绕浮动元素,就像文字环绕图片一样。

缺点

浮动元素脱离文档流,可能会导致父容器的高度塌陷(无法包含浮动元素)。因此,需要使用清除浮动(Clearfix)技术来解决这个问题。

浮动元素会自动变成块级元素(display: block),即使它的原始显示类型是行内元素(display: inline)。

原因:浮动布局需要元素能够独立占据空间并进行水平排列,因此需要将元素提升为块级元素,以便更好地控制其宽度、高度和其他布局属性。

BFC的理解

BFC(Block Formatting Context,块级格式化上下文) 是 CSS 中的一个布局机制,用于定义块级盒子的布局方式。它是一个独立的渲染区域,其中的元素布局不会受到外部元素的影响,也不会影响外部元素的布局。

特点

  • 独立布局区域:BFC 内的元素布局独立于外部元素,不会与外部元素的布局相互影响。
  • 防止外边距折叠:BFC 内的元素不会与外部元素的外边距发生折叠。
  • 限制浮动元素的影响:BFC 可以包含浮动元素,防止浮动元素“溢出”到其他区域。
  • 处理溢出:BFC 可以正确处理 overflow 属性,确保内容不会超出指定区域。

如何触发BFC

  • 根元素:body。根元素默认会创建一个 BFC。
  • 元素设置浮动:float 不为 none。
  • 元素设置绝对定位:position为position 为 absolute 或 relative 或 fixed。
  • display为:inline-block、table-cell、table-caption、flex等
  • overflow为:hidden、auto、scroll。
  • 溢出非 visible 的元素(overflow 不为 visible)

应用

防止外边距折叠

在CSS中,两个相邻的块级元素的外边距(margin)会发生折叠(collapsing)。例如,如果一个元素的底部外边距(margin-bottom)与另一个元素的顶部外边距(margin-top)相邻,这两个外边距会合并为一个更大的外边距。

BFC 的作用 当一个元素触发了 BFC 时,它会创建一个独立的布局区域,内部的外边距不会与外部的外边距发生折叠。

包含浮动元素

浮动元素(float)会脱离文档流,导致它们的父容器无法正确包裹它们。如果没有额外的处理,父容器的高度可能会塌陷。

BFC 的作用

当一个元素触发了 BFC 时,它会自动包含内部的浮动元素,防止浮动元素“溢出”到父容器之外。

处理溢出

当内容超出其容器的边界时,可能会导致布局问题。CSS 的 overflow 属性用于控制内容的溢出行为。

当一个元素触发了 BFC 时,它会正确处理 overflow 属性,确保内容不会超出指定的区域。

什么是高度塌陷?

高度塌陷(Height Collapsing)是指父容器的高度无法正确包裹其子元素,导致父容器的高度“塌陷”为0或小于预期值的现象。这种问题通常发生在使用浮动(float)布局时,因为浮动元素会脱离文档流,导致父容器无法感知其高度。

在CSS中,浮动元素(float: left 或 float: right)会脱离正常的文档流,这意味着它们不会占据父容器的空间。如果没有其他非浮动元素来撑起父容器的高度,父容器的高度可能会塌陷为0,导致布局问题。

解决办法

  • 使用 clearfix 技巧

  • 触发 BFC

实现一个三角形?

宽度设置0,四个border中,透明掉三个,剩一个显示,就是三角形了

div {
    width: 0;
    height: 0;
    border: 100px solid transparent;
    border-bottom-color: red;
}

实现扇形

跟三角形差不多,只不过多设置一个border-radius

div{
    border: 100px solid transparent;
    width: 0;
    heigt: 0;
    border-radius: 100px;
    border-top-color: red;
}

如何显示小于12px的文字?

使用transform: scale()进行缩小

span {
      font-size: 12px;
      -webkit-transform: scale(0.8);
      display: block;
    }

为什么css选择器是自右往左解析?

性能优化 自右往左解析可以更快地定位到目标元素。浏览器在解析选择器时,从最右边的元素(即最具体的元素)开始查找,这样可以快速缩小匹配范围。因为页面中元素的数量通常比组合选择器的数量多得多,从右往左查找可以减少不必要的遍历,提高性能。 例如,对于选择器 .container .item,浏览器先查找所有.item元素,再判断它们是否是.container的后代。如果从左往右查找,就需要遍历所有.container元素及其所有后代,效率较低。

符合文档对象模型(DOM)的结构 HTML文档是树形结构,浏览器在解析时会构建DOM树。自右往左解析选择器,更符合DOM树的遍历方式。从最右边的元素开始,可以快速沿着DOM树向上查找父级元素,判断是否符合选择器的规则。

减少回溯 自右往左解析可以减少回溯操作。如果从左往右解析,一旦发现某个组合选择器不符合条件,就需要回溯重新查找,这会增加计算复杂度。而自右往左解析,一旦发现某个元素不符合最右边的选择器,就可以直接跳过,避免不必要的回溯。

<div class="container">
  <div class="box">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
  </div>
</div>
<div class="box">
  <div class="item">Item 3</div>
</div>
<div class="item">Item 4</div>

假设选择器是 .container .box .item .sub-item,但页面中没有 .sub-item:

  • 从左往右解析时,浏览器会先找到 .container,然后找到 .box,再找到 .item,最后发现没有 .sub-item,此时需要回溯到 .item,再回溯到 .box,最后回溯到 .container,重新查找下一个 .container(如果有的话)。
  • 而从右往左解析时,浏览器一开始就会发现没有 .sub-item,直接跳过这个分支,无需回溯。

display 详解

  • block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
  • none 元素不显示,并从文档流中移除。
  • inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
  • inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
  • list-item 像块类型元素一样显示,并添加样式列表标记。
  • table 此元素会作为块级表格来显示。
  • inherit 规定应该从父元素继承display属性的值。

position 详解

描述
static默认值,元素按照正常文档流布局,不受定位属性影响。
relative相对定位,元素相对于自身位置偏移,但不脱离文档流。
absolute绝对定位,元素相对于最近的非 static 定位祖先元素定位,脱离文档流。
fixed固定定位,元素相对于浏览器窗口定位,不随滚动条移动,脱离文档流。
sticky粘性定位,元素在滚动时会在指定范围内“粘附”到视口上,结合文档流和固定定位。

雪碧图

将多个小图标或背景图像合并到一张大图中,然后通过 CSS 的 background-image、background-repeat 和 background-position 属性来控制背景图像的显示区域

优点

  • 减少 HTTP 请求:将多个小图像合并为一张大图,显著减少页面加载时的 HTTP 请求次数,从而提升页面加载速度。
  • 优化性能:合并后的图像文件通常比多个小图像的总字节更小,节省带宽并加快下载速度。
  • 缓存优化:浏览器只需缓存一张大图,后续访问时可直接从缓存加载。

缺点

  • 维护成本高:添加或删除图标时,需要重新生成精灵图并调整 CSS 中的背景位置。
  • 灵活性受限:图像位置固定,难以实现灵活的布局,如居中显示。
  • 缓存失效:精灵图中任何一个图标更新,整个精灵图的缓存都会失效。
  • 大图加载问题:如果精灵图过大,初次加载时间可能会变长

兼容性问题

浏览器默认的 margin 和 padding 不同

不同浏览器对 HTML 元素的默认样式(如 margin 和 padding)有不同的设置,导致页面布局在不同浏览器中表现不一致。

  • 使用通用的 CSS 重置样式表(如 Normalize.css 或 Eric Meyer 的 Reset CSS)来统一默认样式。
  • 在项目中引入 Normalize.css。

IE6 双边距 Bug

在 IE6 中,浮动元素的外边距会加倍,导致布局错乱。

  • 给浮动元素添加 display: inline 属性,可以修复双边距问题。
  • 使用 zoom: 1 触发 HasLayout

IE6/IE7 中元素高度超出设置高度

在 IE6 和 IE7 中,元素的实际高度可能会超出设置的高度,原因是浏览器会自动添加默认的行高。

  • 显式设置 line-height
  • 使用 overflow: hidden

min-height 在 IE6 下不起作用

IE6 不支持 min-height 属性。

解决

设置 height 为最小高度,并结合 overflow: auto 或 overflow: hidden

.element {
  height: 100px; /* 模拟 min-height */
  overflow: auto;
}

使用条件注释为 IE6 提供特殊样式:

<!--[if IE 6]>
<style>
  .element {
    height: 100px; /* 模拟 min-height */
    overflow: auto;
  }
</style>
<![endif]-->

透明性兼容性问题

IE 使用 filter: Alpha(Opacity=60),而其他浏览器使用 opacity: 0.6

解决 在 CSS 中同时设置 opacity 和 filter,确保兼容所有浏览器。

.transparent-element {
  opacity: 0.6; /* 标准透明性 */
  filter: alpha(opacity=60); /* IE 透明性 */
}

input 边框问题

在 IE6 中,border: none 无法正确移除 input 的边框。

解决 在 IE6 中,border: 0 的优先级高于 border: none,可以正确移除边框。

input {
  border: 0; /* 修复 IE6 边框问题 */
}

使用条件注释为 IE6 提供特殊样式

<!--[if IE 6]>
<style>
  input {
    border: 0; /* 修复 IE6 边框问题 */
  }
</style>
<![endif]-->

外边距重叠

指的是相邻的两个或多个外边距(margin)会合并成一个单独的外边距。这种现象主要发生在垂直方向上,水平方向的外边距不会发生重叠。

在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。

可通过创建 BFC、添加 border/padding 或插入分隔元素避免。

折叠结果遵循下列计算规则:

  1. 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
  2. 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
  3. 两个外边距一正一负时,折叠结果是两者的相加的和。

rgb

特性rgba()opacity
作用范围仅对当前元素的背景颜色或边框颜色生效对当前元素及其所有子元素整体生效
透明效果可以设置颜色的透明度,不影响其他样式属性设置整个元素的透明度,包括内容、背景、边框等
对子元素影响不影响子元素的透明度子元素会继承父元素的透明度,无法单独设置
兼容性所有现代浏览器支持,但 IE8 及以下不支持 rgba()所有现代浏览器支持,IE9 及以上支持 opacity,IE8 及以下需要使用 filter: alpha(opacity=xx)
使用场景适用于需要为背景或边框设置透明度的场景适用于需要整体调整元素透明度的场景

li之间的空白间隔

默认是 display: inline-block 或 display: inline,浏览器会把 inline 元素间的空白字符(空格、换行、Tab等)渲染成一个空格。

因此,当每个 <li> 元素独占一行时,换行符会被浏览器解析为一个空格,从而导致空白间隔。

使用 float: left

使它们浮动排列,从而消除空白间隔。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Float Method</title>
    <style>
        ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }
        li {
            float: left;
            margin-right: 10px; /* 添加一些间距 */
        }
    </style>
</head>
<body>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
    </ul>
</body>
</html>

缺点:浮动元素可能会导致布局问题,需要清除浮动。

将所有 li 写在同一行

将所有 <li> 元素写在同一行,避免换行符被解析为一个空格。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Single Line Method</title>
    <style>
        ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }
        li {
            display: inline-block;
            margin-right: 10px; /* 添加一些间距 */
        }
    </style>
</head>
<body>
    <ul>
        <li>Item 1</li><li>Item 2</li><li>Item 3</li>
    </ul>
</body>
</html>

缺点:代码可读性差,维护困难。

设置 font-size: 0

<ul> 的字体大小设置为 0,从而消除空白间隔。然后在 <li> 中重新设置字体大小。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Font-Size Method</title>
    <style>
        ul {
            list-style: none;
            padding: 0;
            margin: 0;
            font-size: 0; /* 消除空白间隔 */
        }
        li {
            display: inline-block;
            font-size: 16px; /* 重新设置字体大小 */
            margin-right: 10px; /* 添加一些间距 */
        }
    </style>
</head>
<body>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
    </ul>
</body>
</html>

缺点:需要重新设置字体大小,且在某些浏览器(如Safari)中可能仍然出现空白间隔。

使用 letter-spacing: -8px

通过设置 <ul> 的 letter-spacing 为负值,消除空白间隔。然后在 <li> 中将 letter-spacing 设置为正常值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Letter-Spacing Method</title>
    <style>
        ul {
            list-style: none;
            padding: 0;
            margin: 0;
            letter-spacing: -8px; /* 消除空白间隔 */
        }
        li {
            display: inline-block;
            letter-spacing: normal; /* 重新设置字符间隔 */
            margin-right: 10px; /* 添加一些间距 */
        }
    </style>
</head>
<body>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
    </ul>
</body>
</html>
 

缺点:需要额外设置 <li> 的字符间隔,且在某些情况下可能需要调整负值的大小。

visibility属性collapse值

用于控制元素的可见性,尤其在表格元素中表现特殊。

  • 对普通元素:表现与 visibility: hidden 相同,即元素不可见,但仍占据页面空间。
  • 对表格元素(如 <table><tr><td> 等):表现类似于 display: none,即隐藏表格的行、列或单元格,并且不占用空间

width为auto和100%区别

width: 100%

  • 宽度 = 父元素的 content 宽度(不包括 padding)。
  • 可能溢出:如果子元素有 padding 或 border,总宽度可能超出父元素。
  • 常用 box-sizing: border-box 避免溢出(让 100% 包含 padding 和 border)。

width: auto

  • 自动计算宽度,考虑 margin、padding、border,不会溢出。
  • 块级元素默认行为,会占满剩余空间。
<div style="width: 200px; padding: 20px; background: #eee;">
  <div style="width: 100%; background: red;">100%(实际宽度 200px,可能溢出)</div>
  <div style="width: auto; background: blue; padding: 10px;">auto(宽度自动适应)</div>
</div>
 

为什么 width: 100% 可能溢出?

父元素有 padding

<div style="width: 200px; padding: 20px; background: lightgray;">
  <div style="width: 100%; background: red;">子元素</div>
</div>
  • 父元素:width: 200px + padding: 20px → 实际可视宽度 = 200px(但 content box 仍然是 200px)。
  • 子元素:width: 100% → 宽度 = 200px(父元素的 content box)。
  • 结果:子元素宽度 200px + 父元素 padding: 20px → 总宽度 = 240px(超出父容器可视范围)。

子元素有 border 或 padding

<div style="width: 200px; background: lightgray;">
  <div style="width: 100%; padding: 20px; background: red;">子元素</div>
</div>

子元素:width: 100%(200px) + padding: 20px → 实际宽度 = 200px + 40px = 240px(溢出)。

定位下的宽高百分比

绝对定位元素

对于使用 position: absolute 或 position: fixed 的元素,其宽高百分比是相对于其最近的 position 不为 static 的祖先元素的 padding box 来计算的。

非绝对定位元素

对于使用 position: static、position: relative 或 position: sticky 的元素,

其宽高百分比是相对于其父元素的 content box 来计算的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>百分比宽高计算示例</title>
    <style>
        /* 父元素样式 */
        .parent {
            position: relative; /* 为绝对定位元素提供定位上下文 */
            width: 300px; /* 父元素宽度 */
            height: 200px; /* 父元素高度 */
            padding: 20px; /* 父元素内边距 */
            border: 2px solid black; /* 父元素边框 */
            box-sizing: border-box; /* 包含 padding 和 border 在 width 和 height 内 */
            background-color: #f0f0f0; /* 父元素背景色 */
        }
 
        /* 非绝对定位元素 */
        .child-static {
            position: static; /* 默认值,也可以是 relative 或 sticky */
            width: 50%; /* 相对于父元素的 content box */
            height: 50%; /* 相对于父元素的 content box */
            background-color: lightblue; /* 子元素背景色 */
            margin-top: 10px; /* 子元素外边距 */
        }
 
        /* 绝对定位元素 */
        .child-absolute {
            position: absolute;
            top: 0;
            left: 0;
            width: 50%; /* 相对于父元素的 padding box */
            height: 50%; /* 相对于父元素的 padding box */
            background-color: lightgreen; /* 子元素背景色 */
        }
    </style>
</head>
<body>
    <div class="parent">
        <div class="child-static">Static Child</div>
        <div class="child-absolute">Absolute Child</div>
    </div>
</body>
</html>
 

父元素 .parent:

  • 宽度:300px
  • 高度:200px
  • 内边距:padding: 20px

非绝对定位元素 .child-static:

  • 宽度:50%,相对于父元素的 content box(300px - 40px = 260px),计算结果为 130px。
  • 高度:50%,相对于父元素的 content box(200px - 40px = 160px),计算结果为 80px。

绝对定位元素 .child-absolute:

  • 宽度:50%,相对于父元素的 padding box(300px),计算结果为 150px。
  • 高度:50%,相对于父元素的 padding box(200px),计算结果为 100px。

base64 编码的优点和缺点

优点

  • 减少 HTTP 请求

    • 图片直接嵌入 HTML/CSS,无需额外请求,适合小图标(如 1-2KB 的图标)。
    • 提升页面加载速度(减少网络延迟)。
  • 无跨域问题

    • 直接内联在代码里,不受跨域限制(适合 CDN 或第三方资源受限的情况)。
  • 简化部署

    • 无需额外管理图片文件,HTML/CSS 自带图片数据。

缺点

  • 体积变大:Base64 编码后比原文件大约 1/3,大图片会导致 HTML/CSS 文件臃肿,加载变慢。
  • 无法单独缓存:浏览器只能缓存整个 HTML/CSS 文件,不能像普通图片那样独立缓存(更新成本高)。
  • 兼容性问题:IE7 及更早版本不支持(现代项目影响较小)。
  • 代码可读性差:长字符串污染代码,难以维护。

display position float

none > absolute/fixed > float > 默认流,且 position/float 可能强制修改 display。

  1. display: none(最高优先级)

    • 直接隐藏元素,不渲染、不占空间,忽略 position 和 float。
  2. position: absolute/fixed(次优先级)

    • 脱离文档流,相对于非 static 祖先定位。
    • float 失效,display 可能被强制转换(如 inline → block,但 Flex/Grid 保持原样)。
  3. float: left/right(最低优先级)

    • 仅对非 Flex/Grid 布局有效,display 可能被强制转换(如 inline → block)。
    • 若同时设置 position: relative,偏移基于浮动后的位置。
  4. 默认情况(无特殊属性)

    • display 保持声明值(如 inline、flex 等)。

IFC 行级格式化上下文

  1. 水平排列:内部行内级元素(inline/inline-block)水平方向依次排列,超出容器宽度时自动换行。

  2. 高度计算:高度由行高(line-height)和最高内联盒子决定,与内容实际高度无关(如文字、图片)。

  3. 垂直对齐:通过 vertical-align 控制对齐方式(如顶部、基线、底部对齐)。

  4. 空白处理:空格、换行符会渲染为一个空格(可通过 font-size: 0 消除)。

  5. 无块级元素:块级元素(如 div)会强制换行,破坏 IFC(需用 inline-block 保持行内流)。

应用场景:文本流、导航菜单、水平排列小图标等。

移动端布局与媒体查询

媒体查询的作用

  • 适配不同设备:根据屏幕宽度、设备类型(如打印、屏幕、投影)等条件,应用不同的 CSS 样式。
  • 响应式设计核心:使网页在手机、平板、PC 等不同设备上自适应显示。
@media 媒体类型 and (条件) {
  /* 符合条件的样式 */
}
/* 手机 */
@media (max-width: 768px) {
  .container { flex-direction: column; }
  button { padding: 12px; }
}
 
/* 平板 */
@media (min-width: 769px) and (max-width: 1024px) {
  .container { grid-template-columns: 1fr 1fr; }
}
 
/* PC */
@media (min-width: 1025px) {
  .container { grid-template-columns: 1fr 1fr 1fr; }
}

注意事项

  • 移动优先:建议先写默认样式(小屏幕),再用 min-width 逐步适配大屏幕。
  • 性能优化:即使媒体查询不匹配,CSS 文件仍会被下载,但仅应用匹配的样式。
  • 兼容性:CSS3 媒体查询支持所有现代浏览器(IE9+)。

性能优化

加载性能优化

  • 压缩 CSS:使用工具(如 cssnano、webpack)压缩代码,减少文件体积。
  • 避免 @import: @import 会阻塞渲染,改用 <link> 并行加载 CSS。
  • 使用单一样式:优先用 margin-bottom: 10px; 而非 margin: 10px 0;(减少解析复杂度)。

选择器性能优化

  • 关键选择器(Key Selector)
    • 浏览器从右向左匹配选择器(如 .box a 先遍历所有 <a>)。
    • 优化:避免深层嵌套(如 .nav ul li a → 改用 .nav-link)。
  • 避免通配符 * 和标签选择器:通配符 (* ) 会遍历所有元素,改用类选择器(如 .class)。
  • 减少后代选择器:后代选择器(如 div span)开销高,尽量用 类名直连(如 .item)。
  • ID 选择器高效但慎用:#id 速度最快,但不要叠加标签(如 div#id 多余)。

渲染性能优化

  • 减少重排(Reflow)与重绘(Repaint)
    • 避免频繁操作 width、height、margin 等触发重排的属性。
    • 使用 transform 和 opacity(不触发重排)实现动画。
  • 避免空规则 :删除无意义的空样式,减少文件体积。
  • 数值优化:
    • 0 不加单位(如 margin: 0;)。
    • 省略小数前的 0(如 .5s 代替 0.5s)。
  • 慎用高性能属性:float、position: absolute 脱离文档流,滥用会影响渲染。
  • 浏览器前缀标准化
.box {
  -webkit-border-radius: 5px; /* 前缀在前 */
          border-radius: 5px; /* 标准在后 */
}

元素竖向百分比值的基准

  1. height 的百分比

    • 基准:相对于包含块(父元素)的高度(height)。
    • 条件:父元素必须显式设置高度(非 auto),否则百分比无效(高度仍为 auto)。
  2. padding-top / padding-bottom 的百分比

    • 基准:相对于包含块的宽度(width),与高度无关。
    • 用途:常用于实现等比例自适应容器(如 16:9 视频框)。
  3. margin-top / margin-bottom 的百分比

    • 基准:同样相对于包含块的宽度(width)。
  4. 特殊情况,绝对定位元素:

    • top / bottom 的百分比基准为包含块的高度。
    • left / right 的百分比基准为包含块的宽度。
<!DOCTYPE html>
<html>
<head>
  <style>
    /* 包含块(父元素) */
    .container {
      width: 300px;
      height: 200px;  /* 必须显式设置高度 */
      border: 2px solid #333;
      position: relative; /* 为绝对定位子元素建立包含块 */
    }
    
    /* 普通子元素 */
    .child {
      height: 50%;          /* 100px (父height的50%) */
      width: 60%;           /* 180px (父width的60%) */
      padding-top: 10%;     /* 30px (父width的10%) */
      margin-bottom: 5%;    /* 15px (父width的5%) */
      background: lightblue;
    }
    
    /* 绝对定位子元素 */
    .abs-child {
      position: absolute;
      bottom: 20%;         /* 40px (父height的20%) */
      right: 10%;          /* 30px (父width的10%) */
      width: 25%;          /* 75px (父width的25%) */
      height: 15%;         /* 30px (父height的15%) */
      background: pink;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="child">普通子元素</div>
    <div class="abs-child">绝对定位子元素</div>
  </div>
</body>
</html>

特效

全屏滚动

全屏滚动(Fullpage Scroll)的本质是通过控制外层容器的滚动位置,每次只显示一个屏幕高度的内容。

CSS实现

CSS实现

  • scroll-snap-type: y mandatory
    • 在 html 或滚动容器上设置,强制垂直滚动时吸附到指定位置。
    • mandatory 表示必须吸附,proximity 表示接近时吸附(更宽松)。
  • scroll-snap-align: start
    • 在每个 section 上设置,滚动时对齐到元素的起始位置(顶部)。
    • 可选 center(居中)、end(底部)。
  • scroll-behavior: smooth
    • 让滚动更平滑(非必需,但体验更好)。

CSS + Js实现

CSS + Js实现

实现原理

  • 所有section使用绝对定位叠加在一起
  • 通过transform: translateY()控制垂直位置
  • 当前显示的section位于0%位置,其他section根据索引计算偏移量
  • 使用CSS过渡实现平滑动画效果

CSS关键点

  • 视口设置: html, body设置为100%高度并隐藏溢出
  • 全屏容器: 使用100vh和100vw确保占满视口
  • section定位: 使用absolute定位和transform实现位置控制
  • 过渡动画: transition属性实现平滑滚动效果
  • 导航点样式: 固定定位在右侧,显示当前激活状态

视差滚动

视差滚动效果是一种通过不同速度移动背景层和前景层来创建立体运动效果的技术。

CSS实现

按钮

流光按钮1

flow-light-button-2025-07-04-22-38-58

flowing-light-button

← Previous postHTML夯实基础