Skip to main content

理解 CSS

什么是 CSS

CSS 是 Cascading Style Sheets(层叠样式表)的缩写,它是一种用来表现 HTML(标准通用标记语言下的一个应用)或 XML(标准通用标记语言下的一个子集)等文件样式的计算机语言。

CSS 语法

CSS 语法由两个主要的部分组成:选择器和声明。选择器指定要应用样式的 HTML 元素,声明则指定要应用的样式。

selector {
property: value;
}

使用 CSS

内联样式

<p style="color: red;">This is a paragraph.</p>

内部样式表

<head>
<style>
p {
color: red;
}
</style>
</head>
<body>
<p>This is a paragraph.</p>
</body>

外部样式表

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

CSS 的工作原理

CSS 由浏览器解析,然后浏览器将样式应用到文档中的 HTML 元素上。浏览器解析 CSS 时,会根据 CSS 规则将样式应用到文档中的 HTML 元素上。最终展示出来的效果就是 CSS 的作用。

CSS 选择器

元素选择器

p {
color: red;
}

常见的元素如 pdivspan 等。对元素进行样式设置时,需要注意元素的层级关系,如 div p 表示 div 元素下的所有 p 元素。

类选择器

.red {
color: red;
}

类选择器以 . 开头,可以在 HTML 元素中添加 class 属性,然后在 CSS 中使用类选择器来设置样式。

属性选择器

a[target] {
color: red;
}

或者 input 有一个属性叫 disabled,可以使用 [disabled] 来设置样式。示例如下:

[disabled] {    // 所有 disabled 属性的元素的字体都会被设置为红色
color: red;
}

input[disabled] {
color: red;
}

另外还可以匹配值:

a[target=_blank] {
color: red;
}

a[href^="#"] {
color: red;
}

id 选择器

#red {
color: red;
}

id 选择器以 # 开头,可以在 HTML 元素中添加 id 属性,然后在 CSS 中使用 id 选择器来设置样式。

伪类选择器

当元素处于某种状态时,可以使用伪类选择器来设置样式。

a:link {    // 未访问的链接
color: red;
}

a:visited { // 已访问的链接
color: green;
}

a:hover { // 鼠标悬停在链接上
color: blue;
}

a:active { // 鼠标点击链接
color: yellow;
}

此外还有结构的伪类选择器,如 :first-child:last-child:nth-child() 等。表示元素的第一个、最后一个、第 n 个子元素。

p:first-child {
color: red;
}

p:last-child {
color: red;
}

p:nth-child(2) {
color: red;
}

组合

有多种组合方式,如直接组合、后代组合、子元素组合、相邻兄弟组合、一般兄弟组合等。

p.red {   // 类选择器和元素选择器组合
color: red;
}

div p { // 后代组合
color: red;
}

div > p { // 子元素组合
color: red;
}

h2 + p { // 相邻兄弟组合
color: red;
}

h2 ~ p { // 一般兄弟组合
color: red;
}

举一个例子:

<div>
<p>这是一个段落。</p>
<p>这是另一个段落。</p>
<h2>这是一个标题 </h2>
</div>
div p {   // 后代组合
color: red;
}

div > p { // 子元素组合
color: red;
}

h2 + p { // 相邻兄弟组合
color: red;
}

选择器组

p, div, span {
color: red;
}

优先级

优先级是指当多个选择器作用于同一个元素时,哪个选择器的优先级高,就会使用哪个选择器的样式。优先级的计算方式:

  1. 内联样式的优先级最高,其次是 id 选择器,然后是类选择器、属性选择器、伪类选择器,最后是元素选择器、伪元素选择器。

  2. 优先级相同的情况下,后面的选择器优先级高。

颜色

RGB

RGB 是一种颜色模式,它是通过红、绿、蓝三种颜色的不同组合来得到各种颜色的。

p {
color: rgb(255, 0, 0);
}

也可以用十六进制来表示:

p {
color: #ff0000;
}

HSL

HSL 是一种颜色模式,它是通过色相、饱和度、亮度三种颜色的不同组合来得到各种颜色的。

p {
color: hsl(0, 100%, 50%);
}

透明度

透明度是 Alpha 通道的缩写,它是一个 0 到 1 之间的小数,0 表示完全透明,1 表示完全不透明。

p {
color: rgba(255, 0, 0, 0.5);
}

或者可以在十六进制颜色值后面加上两位十六进制数来表示透明度。他的范围是 00 到 ff,00 表示完全透明,ff 表示完全不透明。

p {
color: #ff000080;
}

字体

字体族

p {
font-family: Arial, Helvetica, sans-serif;
}

指定多个字体族,浏览器会按照从左到右的顺序依次选择字体,直到找到第一个可用的字体。

常见字体族

  • serif:衬线字体,如宋体、楷体、新宋体等。
  • sans-serif:无衬线字体,如 Arial、Helvetica、Verdana 等。
  • cursive:草书字体,如华文行楷、华文彩云等。
  • fantasy:装饰性字体,如幼圆、华文隶书等。
  • monospace:等宽字体,如 Courier New、Consolas 等。程序员常用。

在上面的 css 代码钟,最后写了一个 sans-serif,这是因为如果前面的字体族都不可用,浏览器会使用 sans-serif 字体族中的字体。

自定义字体族

@font-face {
font-family: 'MyWebFont';
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff');
}

p {
font-family: 'MyWebFont', sans-serif;
}

字体大小

p {
font-size: 12px;
}

也有 smallmediumlargex-largexx-largexxx-largelargersmaller 这些关键字。

p {
font-size: large;
}

字体大小的单位有:px、em、rem、%、pt、pc、in、cm、mm。

  • px:像素,相对长度单位。像素 px 是相对于显示器屏幕分辨率而言的。
  • em:相对长度单位。相对于当前对象内文本的字体尺寸。
  • rem:相对长度单位。相对于根元素。
  • %:百分比,相对长度单位。相对于父元素的字体尺寸。
  • pt:磅,绝对长度单位。1pt=1/72in,一般用于印刷排版。
  • pc:派卡,绝对长度单位。1pc=12pt。
  • in:英寸,绝对长度单位。1in=2.54cm=96px=72pt。
  • cm:厘米,绝对长度单位。1cm=96px/2.54。
  • mm:毫米,绝对长度单位。1mm=1/10cm。

在微信小程序中,字体大小还可以使用 rpx 单位,rpx 是相对于屏幕宽度的,它的值是屏幕宽度除以 750。

字体粗细

p {
font-weight: bold;
}

可用的值有:normal、bold、bolder、lighter、100、200、300、400、500、600、700、800、900。这需要字体本身支持。

行高

p {
line-height: 1.5;
}

行高是指行与行之间的距离,可以使用数值、百分比、长度单位、normal。数值表示倍数,1 表示行高等于字体大小。

字体样式

p {
font-style: italic;
}

可用的值有:normal、italic、oblique。分别表示正常、斜体、倾斜。

空白符

p {
white-space: nowrap;
}

可用的值有:normal、nowrap、pre、pre-wrap、pre-line、break-spaces。分别表示正常、不换行、保留空白符序列、保留换行符、合并空白符序列、合并换行符。正常情况下,浏览器会把多个空白符合并成一个空格。

继承

CSS 中的属性有些是继承的,有些是不继承的。继承的属性会从父元素继承到子元素,不继承的属性不会从父元素继承到子元素。

可以继承的属性有:colorfontfont-familyfont-sizefont-stylefont-variantfont-weightletter-spacingline-heighttext-aligntext-indenttext-transformword-spacingdirectionunicode-bidivisibilitycursorlist-stylelist-style-imagelist-style-positionlist-style-typequotesvoice-familyborder-collapseborder-spacingcaption-sideempty-cellstable-layoutcounter-resetcounter-incrementspeak-headerspeak-numeralspeak-punctuationspeakpage-break-afterpage-break-beforepage-break-insideorphanswidowszoommax-zoommin-zoomuser-zoomorientationfillfill-opacityfill-ruleclip-rulestrokestroke-dasharraystroke-dashoffsetstroke-linecapstroke-linejoinstroke-miterlimitstroke-opacitystroke-widthalignment-baselinebaseline-shiftdominant-baselinetext-anchorwriting-modeclipcolor-interpolationcolor-interpolation-filterscolor-profilecolor-renderingfillfill-opacityfill-ruleimage-renderingmarkermarker-endmarker-midmarker-startshape-renderingstop-colorstop-opacitystrokestroke-dasharraystroke-dashoffsetstroke-linecapstroke-linejoinstroke-miterlimitstroke-opacitystroke-widthtext-renderingenable-backgroundvector-effectviewBoxmaskopacityoverflowpointer-eventsshape-renderingtext 等。

我们可以显式地设置某个属性的值为 inherit,这样这个属性就会从父元素继承到子元素。

p {
color: inherit;
}

布局

常规流

常规流是指文档的默认布局方式,也是我们最常用的布局方式。常规流中,元素会从上到下,从左到右依次排列。常规流中,元素的宽度由内容决定,高度由内容和内边距决定。常规流中,元素的外边距会影响相邻元素的位置。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>常规流</title>
<style>
div {
width: 100px;
height: 100px;
background-color: red;
margin: 10px;
}
</style>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>

浮动

浮动是指元素脱离常规流,向左或向右浮动。浮动元素的宽度由内容决定,高度由内容和内边距决定。浮动元素的外边距不会影响相邻元素的位置。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>浮动</title>
<style>
div {
width: 100px;
height: 100px;
background-color: red;
margin: 10px;
}
.float-left {
float: left;
}
.float-right {
float: right;
}
</style>
</head>
<body>
<div class="float-left"></div>
<div class="float-left"></div>
<div class="float-left"></div>
<div class="float-right"></div>
</body>
</html>

### 绝对定位

绝对定位是指元素脱离常规流,相对于最近的非 static 定位的祖先元素进行定位。绝对定位元素的宽度由内容决定,高度由内容和内边距决定。绝对定位元素的外边距不会影响相邻元素的位置。

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>绝对定位</title>
<style>
div {
width: 100px;
height: 100px;
background-color: red;
margin: 10px;
}
.absolute {
position: absolute;
}
</style>
</head>
<body>
<div class="absolute"></div>
<div class="absolute"></div>
<div class="absolute"></div>
</body>
</html>

高宽

高宽可以使用的属性有 width、height、min-width、max-width、min-height、max-height。单位和参数有 px、em、rem、%、auto。

width

width 属性用于设置元素的宽度。

div {
width: 100px;
}

height

height 属性用于设置元素的高度。

div {
height: 100px;
}

边距

边距分为内边距和外边距。内边距是指元素内容和边框之间的距离,外边距是指元素边框和相邻元素之间的距离。

内边距

内边距可以使用的属性有 padding、padding-top、padding-right、padding-bottom、padding-left。单位和参数有 px、em、rem、%。

div {
padding: 10px;
}

外边距

外边距可以使用的属性有 margin、margin-top、margin-right、margin-bottom、margin-left。单位和参数有 px、em、rem、%。

div {
margin: 10px;
}

边框

边框可以使用的属性有 border、border-top、border-right、border-bottom、border-left。单位和参数有 px、em、rem、%。

div {
border: 1px solid red;
}

边框还有一些属性,比如 border-style、border-width、border-color、border-radius。

div {
border-style: solid;
border-width: 1px;
border-color: red;
border-radius: 5px;
}

块级和行内元素

块级元素是指独占一行的元素,行内元素是指不独占一行的元素。常见的块级元素有 div、p、h1~h6、ul、ol、li、table、form、hr、pre、address、blockquote、dl、dt、dd、fieldset、legend、noscript、script、style、title、head、body、html、article、aside、footer、header、hgroup、nav、section、video、audio、canvas、figure、figcaption、details、menu、menuitem、summary、time、mark、meter、progress、output、ruby、rt、rp、bdi、bdo、command、datalist、keygen、source、track、wbr。常见的行内元素有 span、a、abbr、acronym、b、big、cite、code、del、dfn、em、font、i、ins、kbd、q、s、samp、small、strike、strong、sub、sup、tt、u、var、bdo、br、img、input、label、map、object、select、textarea。

display 属性

display 属性用于设置元素的显示方式。

div {
display: block;
}

display 还有一些参数 blockinlineinline-blocknonetabletable-celltable-rowtable-row-grouptable-header-grouptable-footer-grouptable-columntable-column-grouptable-captionflexinline-flexgridinline-gridrubyruby-baseruby-textruby-base-containerruby-text-containercontentslist-itemrun-incompactmarkertable-rowtable-row-grouptable-header-grouptable-footer-grouptable-columntable-column-grouptable-captiontable-celltableinline-tableinheritinitialrevertunset

IFC 和 BFC

IFC

IFC 是 inline formatting context 的缩写,是指行内格式化上下文。具体来说,IFC 是一个矩形区域,它包含了一行或多行内联盒子。

下面是 IFC 的一些特性:

  • 内部的 Box 会在水平方向,一个接一个地放置。
  • Box 之间的水平间距由 margin 决定。属于同一个 IFC 的两个相邻 Box 的 margin 会发生重叠。
  • 每个元素的 margin box 的左边,与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • IFC 的高度由它包含的行盒子的高度决定。
  • IFC 的行盒子的高度由最高的内联盒子决定。
  • 文字和内联盒子的基线对齐。

BFC

BFC 是 block formatting context 的缩写,是指块级格式化上下文。具体来说,BFC 是一个矩形区域,它包含了一行或多行块级盒子。

下面是 BFC 的一些特性:

  • 内部的 Box 会在垂直方向,一个接一个地放置。
  • Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。
  • 每个元素的 margin box 的左边,与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC 的区域不会与 float box 重叠。
  • BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
  • 计算 BFC 的高度时,浮动元素也参与计算。

轴布局

flex 布局

flex 布局是一种布局方式,它可以让元素在容器中自由地排列。

flex 布局的属性有:justify-contentalign-itemsflex-directionflex-wrapflex-floworderflex-growflex-shrinkflex-basisflexalign-selfalign-content

主轴和侧轴

主轴是指 flex 布局中的主方向,侧轴是指 flex 布局中的副方向。分别为水平方向和垂直方向。

justify-content

justify-content 属性定义了 flex 元素在主轴上的对齐方式。

  • flex-start:元素位于主轴的起点。
  • flex-end:元素位于主轴的终点。
  • center:元素位于主轴的中点。
  • space-between:元素位于主轴的两端,元素之间的间距相等。
  • space-around:元素位于主轴的两端,元素之间的间距相等,且元素与容器的间距相等。
  • space-evenly:元素位于主轴的两端,元素之间的间距相等,且元素与容器的间距相等。

align-items

align-items 属性定义了 flex 元素在侧轴上的对齐方式。

  • flex-start:元素位于侧轴的起点。
  • flex-end:元素位于侧轴的终点。
  • center:元素位于侧轴的中点。
  • baseline:元素位于侧轴的基线。
  • stretch:元素被拉伸以适应容器。

Flexibility

flexibility 是 flex 布局中的一个重要概念,它指的是 flex 元素在主轴上的伸缩性。

flexibility 的属性有:flex-directionflex-wrapflex-floworderflex-growflex-shrinkflex-basisflexalign-selfalign-content

flex-direction

flex-direction 属性定义了 flex 元素的主轴方向。

  • row:主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。

flex-wrap

flex-wrap 属性定义了 flex 元素是否换行。

  • nowrap:不换行。
  • wrap:换行,第一行在上方。
  • wrap-reverse:换行,第一行在下方。

flex-flow

flex-flow 属性是 flex-direction 和 flex-wrap 的简写形式。

order

order 属性定义了 flex 元素的排列顺序。数值越小,排列越靠前,默认为 0。

flex-grow

flex-grow 属性定义了 flex 元素的放大比例,默认为 0,即如果存在剩余空间,也不放大。

flex-shrink

flex-shrink 属性定义了 flex 元素的缩小比例,默认为 1,即如果空间不足,该元素将缩小。

flex-basis

flex-basis 属性定义了 flex 元素在分配多余空间之前,占据的主轴空间(main size)。

flex

flex 属性是 flex-grow、flex-shrink 和 flex-basis 的简写形式,默认值为 0 1 auto。后两个属性可选。

Grid

Grid 布局是一种二维布局方式,它将容器分为行和列,可以很方便地控制元素的位置和占据的空间。

Grid Container

Grid 容器是指使用了 display: grid 的元素。

display

display 属性定义了元素的类型,常用的有:blockinlineinline-blockflexgridnone

grid-template-columns

grid-template-columns 属性定义了网格的列数和列宽。示例:

.container {
display: grid;
grid-template-columns: 100px 100px 100px;
}

grid-template-rows

grid-template-rows 属性定义了网格的行数和行高。示例:

.container {
display: grid;
grid-template-rows: 100px 100px 100px;
}

grid-template-areas

grid-template-areas 属性定义了网格区域的名称,以及它们的排列布局。示例:

.container {
display: grid;
grid-template-areas:
"header header header"
"main main sidebar"
"footer footer footer";
}