CSS随笔

146 阅读11分钟

CSS随笔

本文主要介绍些 CSS 相关的知识点:发展历程、基础语法、进阶用法、预处理器、性能优化、最佳实践和展望 CSS 未来。 供自己以后查漏补缺,也欢迎同道朋友交流学习。

引言

在现代网页设计中,CSS(层叠样式表)扮演着至关重要的角色。它允许开发者控制网页的外观布局,使网页更加美观、易于使用和可访问。

CSS 是我们前端最基础的知识点,今天写这篇文章主要是系统性的回顾下 CSS 的发展历程、基础语法、进阶用法、预处理器、性能优化、最佳实践和展望 CSS 未来。

发展历程

CSS 的发展经历了几个重要的阶段,每个阶段都带来了新的特性和改进:

  • CSS11996年发布,引入了基本的样式设置,如字体颜色背景布局
  • CSS21998年发布,增加了更多的布局选项,比如定位浮动表格式布局
  • CSS2.12004年发布,是对 CSS2 的修订和澄清,提高了规范的稳定性和一致性。
  • CSS32007年开始逐步推出,引入了大量新特性,如FlexboxGrid布局动画渐变阴影等。
  • CSS4:目前正在开发中,预计将带来更多的改进和新特性,比如更好的颜色控制容器查询等。

CSS基础

选择器的种类

  • 类型选择器:根据元素的类型(标签名)选择元素,例如 p 选择所有 <p> 标签。
  • 类选择器:使用点号 . 后跟类名选择具有特定类的元素,例如 .box 选择所有带有 class="box" 的元素。
  • ID选择器:使用井号 # 后跟ID名选择具有特定 ID 的元素,例如 #header 选择 id="header" 的元素。
  • 属性选择器:根据元素的属性其值选择元素,例如 [type="text"] 选择所有 type 属性为 text<input> 元素。
  • 伪类选择器:用于选择处于特定状态的元素,例如 :hover 选择鼠标悬停的元素。
  • 伪元素选择器:用于选择元素的特定部分,例如 ::before::after 用于在元素内容前后添加装饰性内容

选择器优先级和权重

优先级计算基于以下规则:

  • 内联样式(直接在HTML元素上设置的样式)具有最高优先级。
  • 然后是ID选择器
  • 接着是类选择器属性选择器伪类选择器
  • 类型选择器伪元素选择器的优先级最低。
  • 如果优先级相同,则最后定义的规则会生效。
  • !important声明可以覆盖所有其他规则,但应谨慎使用。

当多个 CSS 规则应用于同一个元素时,浏览器需要确定哪个规则应该被应用。CSS 权重就是用来解决这种冲突的一套规则。

CSS 权重由以下几个因素决定:

  • 内联样式:直接在 HTML 元素的 style 属性中定义的样式具有最高的权重。
  • ID选择器:每个 ID 选择器计为 100
  • 类选择器、属性选择器和伪类选择器:每个计为 10
  • 类型选择器和伪元素选择器:每个计为 1

权重计算规则如下:

  • 将ID选择器的数量乘以100
  • 将类选择器、属性选择器和伪类选择器的数量乘以10
  • 将类型选择器和伪元素选择器的数量乘以1
  • 将以上结果相加,得到总的权重值。

盒模型

CSS盒模型是设计和布局网页内容的基础。每个元素可以看作是一个盒子,盒子由以下几个部分组成:

  • 内容(Content):盒子中的内容,如文本、图片等。
  • 内边距(Padding):内容与边框之间的空间。
  • 边框(Border):围绕内边距的线。
  • 外边距(Margin):边框外的空间,用于分隔元素。

盒模型的总宽度和高度计算公式为:

  • 总宽度 = 内容宽度 + 左右内边距 + 左右边框 + 左右外边距
  • 总高度 = 内容高度 + 上下内边距 + 上下边框 + 上下外边距

定位

CSS 提供了多种定位方式,包括:

  • 静态定位(Static):元素按照正常的文档流进行布局,默认的定位方式。
  • 相对定位(Relative):元素相对于其正常位置进行偏移。
  • 绝对定位(Absolute):元素相对于其最近的已定位(非静态)祖先元素进行定位。
  • 固定定位(Fixed):元素相对于浏览器窗口进行定位,即使页面滚动也不会移动。
  • 粘性定位(Sticky):元素在一定滚动范围内保持相对定位,超出范围后变为固定定位。

布局

布局方面,CSS提供了多种布局技术:

  • Flexbox:一种灵活的布局模型,用于一维布局(水平或垂直)。
  • Grid:一种二维布局模型,用于创建复杂的网格布局。
  • 传统的布局技术:如浮动(Float)和清除(Clear)。

颜色和字体属性

颜色和字体就非常基础了,简单介绍下:

  • 颜色(Color):可以使用颜色名(如 red)、十六进制代码(如 #FF0000)、RGB(如 rgb(255, 0, 0))和HSL(如 hsl(0, 100%, 50%))来设置颜色。
  • 字体(Font):包括 font-family(字体族)、font-size(字体大小)、font-weight(字体粗细)、font-style(字体风格)等。
  • 文本样式:如 text-align(文本对齐)、text-decoration(文本装饰)、text-transform(文本转换)等。

CSS进阶用法

伪类和伪元素

伪类和伪元素是 CSS 中用于选择元素的特殊状态或部分的机制。常用的伪类和伪元素包括:

  • 伪类:用于选择处于特定状态的元素。
    • :hover:鼠标悬停在元素上时。
    • :focus:元素获得焦点时。
    • :nth-child():选择其父元素的特定子元素。
    • :checked:用于选择被选中的<input>元素。
  • 伪元素:用于选择元素的特定部分。
    • ::before::after:在元素内容的前后插入内容。
    • ::first-line::first-letter:选择元素的第一行或第一个字母。

CSS变量(Custom Properties)

CSS 变量允许你定义可重复使用的值,这些值可以在整个文档中被引用和修改。变量可以用于颜色、字体大小、间距等,使得样式更加灵活和可维护。

  • 定义变量:--red-color: #d81127;
  • 使用变量:color: var(--red-color);

媒体查询和响应式设计

媒体查询允许你根据不同的媒体特征(如屏幕尺寸分辨率等)应用不同的CSS规则。

@media (max-width: 600px) {
  body {
    background-color: red;
  }
}

响应式设计是一种设计方法,它使用媒体查询来确保网站在不同设备和屏幕尺寸上都能良好显示。

Flexbox和Grid布局

  • Flexbox:一种用于一维布局的模型,非常适合于创建响应式布局。

    • display: flex; 将容器设置为 flex 容器。
    • justify-contentalign-items 用于控制项目在主轴交叉轴上的对齐方式
  • Grid:一种用于二维布局的模型,允许你创建复杂的网格布局。

    • display: grid; 将容器设置为 grid 容器。
    • grid-template-columnsgrid-template-rows 用于定义网格的列和行。

CSS动画(Transitions和Animations)

  • Transitions:用于在状态改变时创建平滑的过渡效果。

    • 定义过渡transition: all 0.3s ease;
    • 触发过渡:hover { background-color: red; transition: all 0.3s ease; }
  • Animations:用于创建更复杂的动画效果。

    • 定义关键帧

      @keyframes slideIn { 
          from { transform: translateX(0); } 
          to { transform: translateX(100px); } 
      }
      
    • 应用动画animation: slideIn 5s infinite;

CSS预处理器

我们现在在开发过程中,直接使用纯CSS的已经很少了,我们一般使用预处理器来进行开发,常用的就是 sasslessstylus

CSS预处理器是一类工具,它们在被浏览器解析之前扩展 CSS 语言,增加了变量混合(Mixins)函数(Functions)等高级功能,使得 CSS 代码更加模块化可复用易于维护

Sass、Less和Stylus的比较

预处理器语法特点编译
SassSCSS和缩进语法(Sass)功能强大,社区支持广泛,与 Ruby on Rails 框架集成良好需要 Ruby 环境
Less类似于SCSS,但更为简洁易于上手,与 Node.js 环境良好集成通常在客户端(浏览器)进行,也可以在服务器端
Stylus最为灵活,支持JavaScript表达式功能丰富,支持函数式编程通常在 Node.js 环境中使用

写法规则(scss为例)

嵌套规则

预处理器允许 CSS 规则嵌套,使得结构更清晰,减少重复的 CSS 选择器。

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    li { display: inline; }
  }
}
混合(Mixins)

混合是一组 CSS 声明的集合,可以在多个选择器中重复使用。

@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
  border-radius: $radius;
}
.box { @include border-radius(10px); }
函数(Functions)
@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
  border-radius: $radius;
}
.box { @include border-radius(10px); }

CSS性能优化

CSS 性能优化是我们前端比较容易忽略的一点,但它也是前端性能优化中的一个重要部分。

它涉及到减少浏览器的渲染负担、提高页面加载速度和响应速度。以下是一些关键的CSS性能优化策略:

重绘(Repaint)和回流(Reflow)

  • 回流(Reflow):当 DOM 结构变化时,浏览器需要重新计算元素的布局,这个过程称为回流回流通常比重绘更消耗性能
  • 重绘(Repaint):当元素的外观发生变化,但不影响布局时,浏览器需要重新绘制元素,这个过程称为重绘。

从回流和重绘的介绍中,我们可以看出,回流的成本要比重绘高得多,因此我们应该尽量减少回流的次数。

  • 避免复杂的选择器深层次的DOM结构,以减少回流次数。
  • 使用 transformopacity 属性进行动画,因为它们通常只引起重绘,不会引起回流。
  • 使用 will-change 属性来告知浏览器哪些元素将被改变,以优化性能。

will-change

will-change 属性允许开发者声明一个元素即将被改变的属性,浏览器可以据此进行优化,比如预渲染或者预先准备图层。

但过度使用 will-change 可能会导致性能问题,因为它会占用额外的内存和资源。

.element {
  will-change: transform, opacity;
}

优化CSS选择器的性能

尽可能使用 ID选择器类选择器,避免使用过于复杂的选择器。

使用后代选择器时,尽量简化路径,减少匹配次数。

利用浏览器缓存

通过设置合适的 HTTP 缓存头,可以让浏览器缓存 CSS 文件,减少重复请求。

CSS Sprites

CSS Sprites 是将多个图片合并成一个图片文件的技术,通过背景位置来显示不同的部分,减少 HTTP 请求次数。

异步加载CSS文件

异步加载 CSS 可以减少页面渲染的阻塞,提高首屏加载速度。使用 asyncdefer 属性在 <link> 标签中异步加载 CSS 文件。

<link rel="stylesheet" href="style.css" async>

CSS最佳实践

代码组织和模块化

  • 模块化:将CSS代码分解成独立的模块,每个模块负责不同的功能或组件。这有助于保持代码的清晰和可管理性。
  • BEM(Block Element Modifier):一种模块化的命名方法,通过_(元素)--(修饰符)来组织类名,例如.block__element--modifier
  • 文件结构:根据功能或页面将 CSS 文件分开,例如为每个页面或组件创建单独的 CSS 文件。
  • 避免魔法值:使用 CSS变量 代替硬编码的值,使得修改和维护更加容易

使用CSS框架

目前前端常用的 CSS 框架就是 BootstrapTailwind CSS 等,它们提供了丰富的组件和样式,减少了开发时间和工作量。

这些框架都提供了预制的组件和网格系统,加快开发速度;内置响应式布局,易于实现不同设备上的适配;提供大量工具类,使得开发者可以按需构建组件;

CSS的未来

CSS 的未来发展趋势正朝着提高开发效率、增强页面性能、优化用户体验的方向不断演进。

  • CSS HoudiniHoudini 是一组允许开发者访问浏览器渲染引擎的底层功能API。我们可以编写更低级的样式和动画,实现更精细的控制和优化。
  • CSS4CSS4 正在开发中,它将继续扩展 CSS 的能力,包括新的选择器、更多的字体特性、改进的图像效果等。CSS4 可能会引入如:matches()选择器、:dir()伪类、改进的calc()函数等新特性。
  • 容器查询:允许开发者基于容器的大小而非视口大小来编写样式。
  • 环境变量:提供了一种全局定义和使用变量的方式,这些都将极大地扩展 CSS 的能力。

随着浏览器厂商对新 CSS 特性的重视和支持,开发者能够更广泛地使用这些新特性,而不必担心兼容性问题。