前端八股文——CSS基础

125 阅读9分钟

CSS 是用来指定文档如何展示给用户的一门语言

浏览器加载网页的步骤

  1. 浏览器加载HTML文件。
  2. 根据HTML文件构建DOM。
  3. 获取相关的资源,比如CSS样式。
  4. 解析CSS,根据不同的选择器分到不同的桶中。浏览器基于此将找到的不同选择器对应的不同样式添加到对应的DOM节点中。(构建渲染树)
  5. 根据渲染树布局。
  6. 显示在页面中

image.png

CSS 语法

由一个选择器起头,接着输入一对大括号。冒号前面是属性,后面是值。

h1 {
    color: red;
    font-size: 5em;
}

为HTML添加CSS

  1. 外部样式表
link rel="stylesheet" href="styles/style.css">
  1. 内部样式表,head标签里添加style标签
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>CSS</title>
    <style>
      h1 {
        color: blue;
        background-color: yellow;
        border: 1px solid black;
      }

      p {
        color: red;
      }
    </style>
  </head>
  <body>
    <h1>Hello World!</h1>
    <p>css</p>
  </body>
</html>
  1. 内联样式
<p style="color:red;">CSS</p>

层叠与继承

选择器优先级

选择器选择范围越具体,优先级越高。

  1. !important
  2. 内联样式
  3. id选择器
  4. class选择器
  5. 标签选择器
  6. 通配符选择器(*)
  7. 浏览器自定义或继承
继承

CSS 为控制继承提供了五个特殊的通用属性值。每个 CSS 属性都接收这些值。

  1. inherit 开启继承,使用与父元素相同的值
  2. initial 使用初始值
  3. revert 使用浏览器默认样式
  4. revert-layer 使用上一个层叠层的值
  5. unset

盒模型

  1. 标准盒模型:width = content
box-sizing: content-box;
  1. 替代盒模型:width = content + padding + border
box-sizing: border-box;

image.png

内联盒子和块级盒子

块级盒子:

  1. 盒子会在内联的方向上扩展并占据父容器在该方向上的所有可用空间,在绝大数情况下意味着盒子会和父容器一样宽
  2. 每个盒子都会换行
  3. 有width/height属性
  4. margin、padding、border会将周围的盒子推开

内联盒子:

  1. 盒子不会换行
  2. 没有width/height
  3. 垂直方向,margin、padding、border会被应用,但是不会把其他内联元素推开
  4. 水平方向,margin、padding、border会被应用,会把其他内联元素推开

行内块级元素:display: inline-block;

  1. 相对内联元素,拥有width/height,且margin、padding、border会推开其他元素。
  2. 相对块级元素,不会换行。默认宽度为内容撑开宽度。

布局

标准流布局

不对布局进行操作时,浏览器默认的布局方式。

首先,取得元素的内容来放在一个独立的元素盒子中,然后在其周边加上内边距、边框和外边距 --- 就是我们之前看到的盒子模型。

默认的,一个块级元素的内容宽度是其父元素的 100%,其高度与其内容高度一致。内联元素的 height width 与内容一致。你无法设置内联元素的 height width --- 它们就那样置于块级元素的内容里。如果你想控制内联元素的尺寸,你需要为元素设置display: block; (或者,display: inline-block; inline-block 混合了 inline 和 block 的特性。)

这样解释了独立元素的布局,但是元素之间又是如何相互影响的呢?正常布局流(在布局介绍里提到过)是一套在浏览器视口内放置、组织元素的系统。默认的,块级元素按照基于其父元素的书写顺序(默认值:  horizontal-tb) 的*块流动方向 (block flow direction)*放置 --- 每个块级元素会在上一个元素下面另起一行,它们会被设置好的 margin 分隔。在英语,或者其他水平书写、自上而下模式里,块级元素是垂直组织的。

内联元素的表现有所不同 --- 它们不会另起一行;只要在其父级块级元素的宽度内有足够的空间,它们与其他内联元素、相邻的文本内容(或者被包裹的)被安排在同一行。如果空间不够,溢出的文本或元素将移到新的一行。

如果两个相邻的元素都设置了 margin 并且两个 margin 有重叠,那么更大的设置会被保留,小的则会消失 --- 这被称为外边距叠加

弹性布局 display: flex; display: inline-flex;

采用 Flex 布局的元素,称为 Flex 容器flex container,简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目flex item,简称"项目"。

容器默认存在两根轴:水平的主轴main axis和垂直的交叉轴cross axis。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size

image.png

容器上的属性:

  1. flex-derection 决定主轴的方向
flex-derection: row | row-reverse | column | column-reverse;

// row: 默认值 水平方向 从左至右
// row-reverse: 水平方向 从右至左
// column: 垂直方向 从上至下
// column-reverse: 垂直方向 从下至上
  1. flex-wrap 一行放不下时,如何换行
flex-wrap: nowrap | wrap | wrap-reverse;

// nowrap: 默认值 不换行
// wrap: 换行,第一行在最上面
// wrap: 换行,第一行在最下面
  1. flex-flowflex-derectionflex-wrap的组合简写
flex-flow: [flex-derection] [flex-wrap];
  1. justify-content 项目在主轴上的对齐方式。
justify-content: flex-start | flex-end | center | space-between | space-around;

// 具体对齐和主轴的方向相关。
// space-between: 两端对齐。项目之间距离一致
// space-around: 每个项目两边留白一致,项目间距是项目和边框距离的两倍。
  1. align-item 项目在交叉轴的对齐方式
align-items: flex-start | flex-end | center | baseline | stretch;

// baseline: 项目的第一行文字基线对齐
// stretch: 默认值,如果没有设置高度,则高度占满整个容器。
  1. align-content 当容器内的项目不止一行时生效。将每一行当作一个整体,定义其大对齐方式。
align-content: flex-start | flex-end | center | space-between | space-around | stretch;

项目上的属性:

  1. order 定义项目的排序,数值越小越靠前,默认0
order: <int>;
  1. flex-grow 项目的放大比例,相对其他项目。默认0,即还有空间也不放大。
flex-grow: <number>;
  1. flex-shrink 项目的缩小比例,相对其他项目。默认1,即空间不足缩小。设为0,则空间不足也不缩小
flex-shrink: <number>;
  1. flex-basic 定义项目缩放前的大小。默认auto,即项目本身的大小。根据此计算主轴空间确定是否需要缩放。
flex-basic: <length> | auto;
  1. flexflex-growflex-shrinkflex-basic三者的组合简写。
flex: [flex-grow] [flex-shrink] [flex-basic]

// 有两个快捷值 auto(1 1 auto)和 none(0 0 auto)
  1. align-self 单独定义某个项目的对齐方式,覆盖容器的align-item
align-self: auto | flex-start | flex-end | center | baseline | stretch;
网格布局 display: grid;

指定一个容器为网格布局,容器内的元素为项目。

容器上的属性:

  1. grid-template-columns grid-template-rows 设置行列
// 设置三行三列
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 200px 300px;

// fr关键字 可以按比例分配行列大小
grid-template-columns: 1fr 1fr 2fr;
grid-template-rows: 1fr 2fr 1fr;

// repect()函数,可以重复设置相同的行列
grid-template-columns: repeat(3, 200px); // 重复设置三列
grid-template-columns: repeat(3, 100px 200px 300px); // 重复设置三组(100px 200px 300px)

// auto-fill关键字。当单元格大小固定,但是容器大小不确定时使用。自动填充尽可能多的单元格。
grid-template-columns: repeat(auto-fill, 100px); 

// minmax()函数 产生一个大小范围。自适应。
grid-auto-rows: minmax(100px, auto); // 一行最小高度100px,最大自适应。

// auto关键字
grid-template-columns: 100px auto 300px; // 第二列宽度自适应。

// 给网格分界线命名
// 行列指定后,行和列之间的分割线。在给单元格放入元素时用于定位。
// 也可以不单独命名,默认1234567.....
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
  1. grid-gap grid-cloumn-gap grid-row-gap 设置单元格的间距
// grid-gap 是 grid-cloumn-gap 和 grid-row-gap 的组合简写。
grid-gap: [grid-row-gap] [grid-cloumn-gap];
grid-gap: 20px 10px;
  1. grid-template-area 定义区域,放入元素时定位使用。
// 定义三行三列,第一行为区域a,第二行第一个单元格和第三行第一个单元格组成区域bgrid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a a a'
                     'b c d'
                     'b e f';
  1. grid-auto-flow 决定元素排列顺序
grid-auto-flow: row; // 默认值,先行后列
grid-auto-flow: column; // 先列后行

// 加上dense,表示尽量紧凑不出现空格,排列表现可能会有变化。
grid-auto-flow: row dense; // 先行后列
grid-auto-flow: column dense; // 先列后行
  1. justify-items align-items 单元格内容的对齐方式
// stretch表示撑满(默认值)
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
  1. grid-auto-rows grid-auto-cloumn 当项目数量多于显式定义的网格时,会自动增加隐式网格。定义自动增加的隐式网格的行列大小。不设置默认根据内容自适应。
// 默认值 auto 自适应
grid-auto-rows: 100px; // 隐式网格行高100px
grid-auto-cloumn: 100px; // 隐式网格列宽100px

项目上的属性:

  1. grid-cloumn grid-row grid-cloumn-start grid-row-start grid-cloumn-end grid-row-end 根据网格线放入对应的项目。
// grid-column是grid-cloumn-start和grid-cloumn-end的组合简写,grid-row同理。
grid-row: [grid-row-start] / [grid-row-end];
grid-cloumn: [grid-cloumn-start] / [grid-cloumn-end];

grid-column: 1 / 4; // 表示这个项目放在第一条网格线到第四条网格线之间(第一列到第三列)

// 也可以使用之前给网格线定义的别名
grid-column: c1 / c4;
  1. grid-area 根据定义的区域放入项目。
.warp {
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas: 'a a a'
                         'b c d'
                         'b e f';
}

// item1 放在区域a 也就是第一行
.item1 {
    grid-area: a;
}

// grid-area也可以是grid-cloumn-start、grid-row-start、grid-cloumn-end、grid-row-end的组合
grid-area: [row-start] / [column-start] / [row-end] / [column-end];
  1. justity-self align-self 单元格内容的对齐方式。和justify-items align-items用法一致,只是作用于单个单元格。 place-selfjustity-selfalign-self的组合简写。
place-self: [align-self] [justify-self];