CSS 基础与核心布局

让网页变得美丽动人的魔法

CSS:网页的魔法师

CSS(层叠样式表)是用于控制网页视觉呈现的语言。如果把 HTML 比作网页的骨架,那么 CSS 就是它的皮肤、衣服和妆容。

通过 CSS,我们可以控制网页的颜色、布局、字体、动画效果等各种视觉元素,让网页变得美观、有序且富有个性。

在这个教程中,我们将学习 CSS 的基础知识、盒模型、Flex 布局以及 Sass 扩展语言,并通过生动的演示和互动实例来加深理解。

HTML
HTML + CSS

CSS 基础知识

CSS 的三种引入方式

内联样式
内部样式表
外部样式表

内联样式直接在 HTML 元素的 style 属性中定义样式。这种方式适用于只需要为单个元素设置样式的情况。

<p style="color: blue; font-size: 16px;">这是蓝色文本</p>

这是蓝色文本

内部样式表在 HTML 文档的<head>部分使用<style>标签定义样式。这种方式适用于为单个页面设置样式。

<head>
  <style>
    p {
      color: blue;
      font-size: 16px;
    }
  </style>
</head>

这是蓝色文本

外部样式表在单独的 .css 文件中定义样式,然后通过<link>标签引入。这种方式是最推荐的,因为它实现了内容与样式的分离,便于维护。

HTML 文件:

<head>
  <link rel="stylesheet" href="styles.css">
</head>

styles.css 文件:

p {
  color: blue;
  font-size: 16px;
}

这是蓝色文本

CSS选择器

基本选择器
组合选择器
伪类选择器
选择器优先级

元素选择器

选择所有指定类型的 HTML 元素

p {
  color: blue;
}

类选择器

选择具有特定 class 属性的元素

.highlight {
  background-color: yellow;
}

ID 选择器

选择具有特定 id 属性的元素

#header {
  background-color: black;
  color: white;
}

实时演示

这是一个段落元素

这是一个带有 highlight 类的元素
这是一个带有 header ID 的元素

后代选择器

选择作为另一个元素后代的元素

.parent p {
  color: red;
}

子选择器

选择作为另一个元素直接子元素的元素

.parent > p {
  color: red;
}

相邻兄弟选择器

选择紧接在另一个元素后的元素

h2 + p {
  font-weight: bold;
}

实时演示

这是父元素中的段落

这是子元素中的段落

这是一个标题

这是紧跟在标题后的段落

:hover

鼠标悬停在元素上时

button:hover {
  background-color: red;
}

:active

元素被激活(如按钮被点击)时

button:active {
  background-color: green;
}

:focus

元素获得焦点时

input:focus {
  border-color: blue;
}

:nth-child()

基于元素在其父元素中的位置

li:nth-child(even) {
  background-color: #f2f2f2;
}

实时演示

  • 列表项 1
  • 列表项 2
  • 列表项 3
  • 列表项 4
  • 列表项 5

当多个选择器应用于同一元素时,CSS使用优先级规则确定哪个样式生效:

内联样式

1000分

ID选择器

100分

类选择器

10分

元素选择器

1分

#nav .item p {
  color: red;  /* 优先级: 100 + 10 + 1 = 111 */
}

body #nav p {
  color: blue; /* 优先级: 1 + 100 + 1 = 102 */
}

实时演示

CSS 盒模型

CSS 盒模型描述了元素在页面上占据的空间。每个 HTML 元素都被视为一个矩形盒子,由以下部分组成:

外边距 (Margin)
边框 (Border)
内边距 (Padding)
内容 (Content)

盒模型属性

.box {
  /* 内容区域大小 */
  width: 300px;
  height: 200px;
  
  /* 内边距 */
  padding-top: 10px;
  padding-right: 20px;
  padding-bottom: 10px;
  padding-left: 20px;
  /* 简写形式 */
  padding: 10px 20px; /* 上下 左右 */
  
  /* 边框 */
  border-width: 1px;
  border-style: solid;
  border-color: green;
  /* 简写形式 */
  border: 1px solid green;
  
  /* 外边距 */
  margin-top: 10px;
  margin-right: 30px;
  margin-bottom: 20px;
  margin-left: 30px;
  /* 简写形式 */
  margin: 10px 30px 20px; /* 上 左右 下 */
}

盒模型类型

标准盒模型
IE盒模型

标准盒模型(默认):元素的 width/height 只包括内容区域,不包括 padding、border 和 margin。

.box {
  box-sizing: content-box; /* 默认值 */
  width: 300px; /* 只是内容区域的宽度 */
  padding: 20px;
  border: 10px solid black;
  /* 实际宽度 = 300px + 20px*2 + 10px*2 = 360px */
}
内容区域宽度: 300px
实际宽度: 360px

IE 盒模型:元素的 width/height 包括内容区域、padding 和 border,但不包括 margin。

.box {
  box-sizing: border-box;
  width: 300px; /* 包括内容区域、内边距和边框 */
  padding: 20px;
  border: 10px solid black;
  /* 实际宽度 = 300px(内容区域会自动调整为 240px) */
}
内容区域宽度: 240px
实际宽度: 300px

最佳实践

在实际开发中,推荐使用 IE 盒模型(box-sizing: border-box),这样更容易确定元素的实际大小。许多 CSS 框架(如 Bootstrap)默认使用这种盒模型。

* {
  box-sizing: border-box;
}

盒模型互动演示

200px
20px
5px
10px
内容
内容区域宽度: 200px
实际宽度: 290px

Flex 布局

Flexbox(弹性盒子)是一种一维布局模型,专为创建行或列的项目布局而设计。它使得在容器内的项目能够动态地改变其宽度/高度以填充可用空间,或者收缩以防止溢出。

Flexbox 基本概念

Flexbox 布局由两个主要组件组成:

  • Flex 容器(Flex Container):设置了display: flex的元素
  • Flex 项目(Flex Items):Flex 容器的直接子元素
<div class="container">  <!-- Flex 容器 -->
  <div class="item">1</div>  <!-- Flex 项目 -->
  <div class="item">2</div>  <!-- Flex 项目 -->
  <div class="item">3</div>  <!-- Flex 项目 -->
</div>

.container {
  display: flex;  /* 将元素设置为 flex 容器 */
}

Flex 布局示意图

Flex 容器
Flex 项目 1
1
Flex 项目 2
2
Flex 项目 3
3
主轴 (Main Axis)
交叉轴 (Cross Axis)

Flex 容器属性

flex-direction
justify-content
align-items
flex-wrap

flex-direction定义了主轴的方向,即项目的排列方向。

.container {
  flex-direction: row;  /* 默认值:水平方向,从左到右 */
  /* 或 */
  flex-direction: row-reverse;  /* 水平方向,从右到左 */
  /* 或 */
  flex-direction: column;  /* 垂直方向,从上到下 */
  /* 或 */
  flex-direction: column-reverse;  /* 垂直方向,从下到上 */
}
1
2
3

justify-content定义了项目在主轴上的对齐方式。

.container {
  justify-content: flex-start;  /* 默认值:左对齐 */
  /* 或 */
  justify-content: flex-end;  /* 右对齐 */
  /* 或 */
  justify-content: center;  /* 居中 */
  /* 或 */
  justify-content: space-between;  /* 两端对齐,项目之间的间隔相等 */
  /* 或 */
  justify-content: space-around;  /* 每个项目两侧的间隔相等 */
  /* 或 */
  justify-content: space-evenly;  /* 每个项目之间的间隔相等,包括到容器边缘的距离 */
}
1
2
3

align-items定义了项目在交叉轴上的对齐方式。

.container {
  align-items: stretch;  /* 默认值:如果项目未设置高度或设为auto,将占满整个容器的高度 */
  /* 或 */
  align-items: flex-start;  /* 交叉轴的起点对齐 */
  /* 或 */
  align-items: flex-end;  /* 交叉轴的终点对齐 */
  /* 或 */
  align-items: center;  /* 交叉轴的中点对齐 */
  /* 或 */
  align-items: baseline;  /* 项目的第一行文字的基线对齐 */
}
1
2
3

flex-wrap定义了如果一条轴线排不下,如何换行。

.container {
  flex-wrap: nowrap;  /* 默认值:不换行 */
  /* 或 */
  flex-wrap: wrap;  /* 换行,第一行在上方 */
  /* 或 */
  flex-wrap: wrap-reverse;  /* 换行,第一行在下方 */
}
1
2
3
4
5

Flex 项目属性

flex-grow
flex-shrink
flex-basis

flex-grow定义项目的放大比例,默认为 0(即如果存在剩余空间,也不放大)。

.item {
  flex-grow: 0;  /* 默认值:不放大 */
  /* 或 */
  flex-grow: 1;  /* 放大比例为1 */
}

调整每个项目的flex-grow值:

1
2
3

flex-shrink 定义了项目的缩小比例,默认为 1(即如果空间不足,该项目将缩小)。

.item {
  flex-shrink: 1;  /* 默认值:空间不足时缩小 */
  /* 或 */
  flex-shrink: 0;  /* 空间不足时不缩小 */
}

调整每个项目的flex-shrink值:

400px
1
2
3

flex-basis定义了在分配多余空间之前,项目占据的主轴空间。浏览器根据这个属性,计算主轴是否有多余空间。

.item {
  flex-basis: auto;  /* 默认值:项目的本来大小 */
  /* 或 */
  flex-basis: 0;  /* 项目将根据 flex-grow 的值分配空间 */
  /* 或 */
  flex-basis: 200px;  /* 项目将占据 200px 的主轴空间 */
}

调整每个项目的flex-basis值:

1
2
3

Flex 布局实战:居中对齐

使用 Flex 布局可以轻松实现水平和垂直居中对齐,这在传统 CSS 中是比较麻烦的。

.container {
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
  height: 300px;
  border: 2px dashed #ccc;
}

.item {
  width: 100px;
  height: 100px;
  background-color: #4F46E5;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
}
居中元素

Sass (CSS 扩展语言)

SCSS 是 Sass 的一种语法格式,SCSS 完全兼容 CSS 语法,同时添加了变量、嵌套、混合、继承等特性,使 CSS 更加强大和易于维护。

变量

变量是 SCSS 中最基本的功能,可以存储颜色、字体堆栈、数字等值,并在整个样式表中重复使用。

// 定义变量
$primary-color: #3498db;
$secondary-color: #2ecc71;
$base-font-size: 16px;
$spacing: 8px;

// 使用变量
body {
  font-size: $base-font-size;
  color: $primary-color;
  margin: $spacing * 2;
}

.button {
  background-color: $secondary-color;
  padding: $spacing $spacing * 2;
}

编译后的 CSS:

body {
  font-size: 16px;
  color: #3498db;
  margin: 16px;
}

.button {
  background-color: #2ecc71;
  padding: 8px 16px;
}
这是使用变量样式的文本

变量作用域:

$global-color: #333; // 全局变量

.container {
  $local-padding: 20px; // 局部变量
  padding: $local-padding;
  color: $global-color;
}

.other-element {
  // 这里可以使用 $global-color
  color: $global-color;
  
  // 但不能使用 $local-padding,会报错
  // padding: $local-padding; // 错误
}

编译后的 CSS:

.container {
  padding: 20px;
  color: #333;
}

.other-element {
  color: #333;
}
这是container元素,使用了局部变量$local-padding和全局变量$global-color
这是other-element元素,只能使用全局变量$global-color

嵌套

嵌套是 SCSS 的一个强大特性,它允许你按照 HTML 的层次结构组织 CSS 规则,使代码更加清晰和易于维护。

nav {
  background-color: #333;
  
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }
  
  li {
    display: inline-block;
  }
  
  a {
    display: block;
    padding: 10px 15px;
    color: white;
    text-decoration: none;
    
    &:hover {
      color: #ddd;
    }
  }
}

编译后的 CSS:

nav {
  background-color: #333;
}

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

nav li {
  display: inline-block;
}

nav a {
  display: block;
  padding: 10px 15px;
  color: white;
  text-decoration: none;
}

nav a:hover {
  color: #ddd;
}

& 符号:

& 符号表示父选择器,可以用于创建伪类、伪元素或修饰符。

.button {
  background-color: blue;
  color: white;
  
  &:hover {
    background-color: darkblue;
  }
  
  &:active {
    background-color: navy;
  }
  
  &.large {
    font-size: 18px;
  }
  
  &--primary {
    background-color: green;
  }
  
  &::before {
    content: "→";
    margin-right: 5px;
  }
}

编译后的 CSS:

.button {
  background-color: blue;
  color: white;
}

.button:hover {
  background-color: darkblue;
}

.button:active {
  background-color: navy;
}

.button.large {
  font-size: 18px;
}

.button--primary {
  background-color: green;
}

.button::before {
  content: "→";
  margin-right: 5px;
}
悬停、点击按钮查看效果

混合 (Mixins)

混合(Mixins)是 SCSS 中一种重用代码块的方式,类似于函数。它们可以包含任何 SCSS 代码,并且可以接受参数。

@mixin center-flex {
  display: flex;
  justify-content: center;
  align-items: center;
}

.container {
  @include center-flex();
  height: 100vh;
}

.card {
  @include center-flex();
}

编译后的 CSS:

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.card {
  display: flex;
  justify-content: center;
  align-items: center;
}
卡片

带参数的混合:

@mixin button($bg-color, $text-color) {
  background-color: $bg-color;
  color: $text-color;
  padding: 10px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  
  &:hover {
    background-color: darken($bg-color, 10%);
  }
}

.primary-button {
  @include button(#3498db, white);
}

.success-button {
  @include button(#2ecc71, white);
}

.danger-button {
  @include button(#e74c3c, white);
}

编译后的 CSS:

.primary-button {
  background-color: #3498db;
  color: white;
  padding: 10px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.primary-button:hover {
  background-color: #217dbb;
}

.success-button {
  background-color: #2ecc71;
  color: white;
  padding: 10px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.success-button:hover {
  background-color: #25a25a;
}

.danger-button {
  background-color: #e74c3c;
  color: white;
  padding: 10px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.danger-button:hover {
  background-color: #d62c1a;
}

Sass 的优势

  • 提高代码可维护性:通过变量、嵌套和混合等特性,使 CSS 代码更加模块化和易于维护。
  • 减少重复代码:使用变量和混合可以减少重复代码,提高开发效率。
  • 更好的组织结构:嵌套规则使 CSS 结构更加清晰,反映 HTML 的层次结构。
  • 增强功能:Sass 提供了条件语句、循环、函数等编程特性,使 CSS 更加强大。