CSS基础知识概览

37 阅读18分钟

HTML+CSS知识体系

CSS

CSS层叠性:后来居上,应用于同一个DOM元素的相同优先级的样式,后面写的会覆盖前面写的。

CSS优先级:书写CSS样式时,经常出现多个冲突样式渲染至同一个DOM元素,所以CSS按照优先级渲染。每种选择器的权重按下表计算:

选择器格式优先级权重
!important!important∞ 无穷大
行内样式style=""1000
id选择器#id100
类选择器.classname10
属性选择器a[ref=“eee”]10
伪类选择器li:last-child 或 a:hover10
标签选择器div1
伪元素选择器li::after1
相邻兄弟选择器h1+p0
子选择器ul>li0
后代选择器li a0
通配符选择器*0

盒模型

​ CSS中,每一个DOM元素都会被看作一个盒模型:

​ 每个盒模型由四部分组成:内容(content),内边距(padding),边框(border),外边距(margin)。

1. 盒模型大小

CSS:box-sizing

通过修改CSS的 box-sizing 属性,改变盒子模型计算总宽度和总高度的公式。

  • { box-sizing: content-box, width = 200px}:width = 200px = content的宽度
  • { box-sizing: border-box, width = 200px}:width = 200px = border + padding + content的宽度

JS:获取盒子大小

​ JavaScript 中也有直接获取盒模型大小的属性:

clientXoffsetXscrollX
clientWidthoffsetWidthscrollWidth
clientHeightoffsetHeightscrollHeight
  • clientX:客户区大小,clientWidth = content的宽度 + padding ​ 注意:如果有滚动条的话,滚动条占据原有content空间,content会在原有基础上缩小。在windows操作系统下 clientWidth = 缩小后content的宽度 + padding ,在IOS操作系统下 clientWidth = 缩小后content的宽度 + padding + 垂直滚动条宽度。
  • offsetX:偏移量大小,offsetWidth = content的宽度 + padding + border ​ 注意:如果有滚动条的话,滚动条占据原有content位置,content会在原有基础上缩小。此时:offsetX = 缩小后content的宽度 + padding + border + 垂直滚动条宽度。
  • scrollX:滚动区大小,如果盒子内的内容能被盒子容纳下,scrollWidth = clientWidth ;反之,scrollWidth = 盒子内内容的宽度。

参考:正确获取DOM元素的大小

2. margin

margin塌陷

​ 上下两个块级元素,上元素有 margin-bottom 下元素有 margin-top,它们之间垂直间距不是 margin-bottom + margin-top,而是取两个值中较大者

​ 嵌套关系的两个块级元素,父元素有 margin-top,子元素也有 margin-top ,它们之间垂直间距不是两者之和,而是取两个中的较大者

margin负值

  • 负的 margin-topmargin-left:元素向上,向左移动。
  • 负的 margin-bottommargin-right:下邻居元素向上移动,右邻居元素向左移动。
3. 盒子布局容器BFC

​ BFC(Block Formatting Context),即块级格式化上下文。盒子是浏览器对页面进行布局的最小单位,一个BFC可以理解为一个布局容器,容器内的元素必须满足BFC规定的特性,BFC有三层:普通流,浮动流和定位。

  • 普通流: 普通流(又称标准流)内的盒子,一个接着一个排列,块级盒子竖着排列,行内级盒子横着排列。此外,position:static / relative 采用 静态定位相对定位 的盒子会被放在这一层。
  • 浮动流:凌驾于普通流,采用 float: left / right 使盒子脱离普通流,使得普通流中的下一个相邻盒子会占据浮动盒子的原位置,浮动盒子会覆盖挤上来的盒子。浮动流的盒子横着排列。但浮动流和普通流并不是完全隔离的两个层,浮动起来的元素只是位于当前行 进行排列,而不是位于页面左上角进行排列。
  • 定位:凌驾于普通流,采用 position:absolute / fixed 使盒子脱离普通流,absolute 的参考物为最近的一个具有 position 属性的元素,直到追溯至<body></body> 。fixed 的参考物为浏览器窗口。

BFC的作用范围

​ BFC作用范围是:创建该BFC元素的所有子元素,但是不包括创建了新的BFC的子元素的内部元素。

<div id='div_1' class='BFC'>
    <div id='div_2'>
        <div id='div_3'></div>
        <div id='div_4'></div>
    </div>
    <div id='div_5' class='BFC'>
        <div id='div_6'></div>
        <div id='div_7'></div>
    </div>
</div>

​ 如上面这段代码,#div_1 创建了一个 BFC,这个BFC的作用范围为:#div_2, #div_3, #div_4, #div_5。而 #div_6, #div_7 则不存在于 #div_1 的BFC中,它们存在于 #div_5 新建的BFC中。

BFC的创建方式

  • overflow 值不为 visible 的元素,比如:overflow: hidden
  • float 值不为 none 的元素,比如 float: left / right
  • position 值为绝对定位的元素,比如 position: absolute / fixed
  • display 值为 *flex / inline-block / *flow-root 的元素
  • 根元素启动开启BFC,即 ** 元素本身就是一个 BFC 布局容器**

BFC的特性

  • 内部盒子在垂直方向,一个个地放置
  • 计算BFC容器的高度是,考虑BFC包含的所有元素(除了绝对定位元素),浮动元素也参与计算。解决子盒浮动导致的父盒高度坍塌问题
  • BFC内子元素布局不会影响到外面元素。解决父盒子与子盒子margin塌陷问题
  • BFC内浮动流层的盒子不会覆盖至其他BFC上。一般BFC内浮动流盒子会覆盖位于同一个BFC普通流上的盒子,可以开启普通流盒子的BFC,使得其不会被浮动流盒子覆盖。解决浮动流覆盖普通流问题

参考:学习 BFC (Block Formatting Context)

IFC(Inline Formatting Context)即行内格式化上下文,一个IFC可以理解为一个行内盒子容器,容器内的元素必须满足IFC规定的特性。

IFC的创建方式

  • display值为 inline-block

IFC的特性

  • 内部盒子在水平方向,一个个的放置(不建议在一个IFC内插入块级盒子)
  • IFC的高度是其包含的行内元素中最高的高度(不受到垂直方向的 padding/margin 的影响)

IFC的应用

  • 水平居中:将一个块级盒子display设为inline-block在其外层产生IFC,在其父盒子内设置tex-algin: center使其水平居中
  • 垂直居中:父盒子创建一个IFC,其中每个行内元素设置vertical-algin: middle,所有行内元素可以在此父盒子下垂直居中

布局

1. float

实现一个三栏布局:两侧内容固定,中间内容(最先加载和渲染)随宽度自适应。

圣杯布局

圣杯布局的DOM结构:

<header>页首</header>
<div class="container">
  <div class="middle">中间弹性区</div>
  <div class="left">左边栏</div>
  <div class="right">右边栏</div>
</div>
<footer>页尾</footer>

DOM书写上middle写在left和right前面,实现中间盒子被优先渲染。

  1. 首先让 left, middle, right 向左浮动,启动container容器的BFC使得其高度不会塌陷,给middle宽度为100%使得其宽度自适应。
  • .container{ overfliow:hidden }
  • .middle{ width: 100%; float:left; }
  • .left{ width: 200px; height: 200px; float:left; }
  • .right{ width: 200px; height: 200px; float:left; }
  1. 利用 负的margin-left 使得 left,rightmiddle 同一行并覆盖它。
.container{ overflow:hidden }
.middle{ width: 100%;  float:left; }
.left{ width: 200px; height: 200px; float:left; **margin-left: -100%;** }
.right{ width: 200px; height: 200px;  float:left; **margin-left: 200px;** }
  1. container 中设置 padding,挤出 leftright 的宽度。
.container{ overfliow:hidden; **padding-left: 200px; padding-right: 200px;** }
.middle{ width: 100%;  float:left; }
.left{ width: 200px; height: 200px; float:left; margin-left: -100%; }
.right{ width: 200px; height: 200px;  float:left; margin-left: 200px; }
  1. 最后利用 相对定位leftrightmiddle 上面移开,实现圣杯布局。
.container{ overfliow:hidden; padding-left: 200px; padding-right: 200px; }
.middle{ width: 100%;  float:left; }
.left{ width: 200px; height: 200px; float:left; margin-left: -100%; **position: relative; left: -200px;** }
.right{ width: 200px; height: 200px;  float:left; margin-left: 200px;  **position: relative; right: -200px;** }

参考:圣杯布局

双飞翼布局

双飞翼布局的DOM结构

<header>Header内容区</header>
<div class="middle">
    <div class="middle-inner">中间弹性区</div>
</div>
<div class="left">左边栏</div>
<div class="right">右边栏</div>
<footer>Footer内容区</footer>

DOM书写上middle写在left和right前面,实现中间盒子被优先渲染。

  1. 首先让 left, middle, right 向左浮动,由于没有了 container 使用另外一种方式即给 footer 一个 clear: both 清除浮动防止高度塌陷,给 middle 宽度为100%使得其宽度自适应。
.footer{ **clear: both** }
.middle{ **width: 100%;  float: left;** }
.left{ width: 200px; height: 200px; **float: left;** }
.right{ width: 200px; height: 200px;  **float: left;** }
  1. 使用 负的 margin-left 使得 left, rightmiddle 同处一行,并覆盖它。
.middle{ width: 100%;  float: left; }
.left{ width: 200px; height: 200px; float: left; **margin-left: -100%;**}
.right{ width: 200px; height: 200px;  float: left; **margin-left: -200px;**}
  1. middle-inner 中设置 paddingmiddle 中的内容往中间挤出,防止 left, right 将其覆盖。实现双飞翼布局。
.middle-inner{ **padding: 0 200px 0 200px;** }

圣杯布局与双飞翼布局的异同: 同:两者都使用了 float: left 和 负的 margin-left 使得三栏同处一行 异:而解决 left, right 覆盖 middle 的方式不同。圣杯布局利用 container 包裹住 left, middle, right ,给container 设置 padding 来挤出 left, right 的摆放位置,再利用 相对定位left, right 移至挤出的位置;双飞翼布局在 middle 内部放入一个 middle-inner,给 middle-inner 设置 padding 将middle的内容挤出,导致其不被 left, right 覆盖。总之,双飞翼布局比圣杯布局少用了相对定位

参考:双飞翼布局

清除浮动

​ 清除浮动主要是为了解决父盒子因为子盒子浮动引起导致其高度为0的问题。下面有几种清除浮动的方法:

  • 浮动元素末尾添加一个空标签,设置clear: both;
 <div style="clear: both"> < /div>
  • 父盒子伪元素设置 clear: both,这种是方式1的优化,不用添加一个空标签;
.clearfix:after{ 
    content: ' '; 
    display: block; 
    clear: both 
}
  • 父盒子启动BFC。
overflow: hidden;
2. position

​ 定位是CSS用于布局的除浮动外的另一种方式,通过 position 属性设置,它有以下取值:

  • static:静态定位,不移动位置但占据文本流。
  • relative:相对定位,相对于自己原来在标准流中的位置移动,原来size在标准流继续占有
  • absolute:绝对定位,参考最近具有 position 属性(取值为除static外的所有属性)的元素的位置进行移动,原来size脱离标准流
  • fixed:固定定位,特殊的绝对定位,参考浏览器窗口的位置进行移动,原来size脱离标准流
  • sticky:粘性定位,适用于具有滚动条的长页面。如果元素位置在视口中,其相当于relative;如果用户滚动页面,导致元素位置在视口外,其相当于fixed。

常用的定位组合:子绝父相,父盒设置 relative 但不移动,作为参照物;子盒设置 absolute 以父盒位置为参照进行移动。

3.flex

​ flex(Flexible Box)弹性布局。布局样式为一个垂直交叉轴,默认主轴为从左至右的X轴,侧轴为从上至下的Y轴。盒子首先沿主轴方向排列,放满后按侧轴方向换行,再继续沿主轴方向排列。{ display: flex }开启布局。flex有以下几个常用属性,加粗为默认值:

容器属性

  • flex-direction:设置主轴方向,row 为X轴,column 为Y轴。
  • flex-wrap:设置是否换行,nowrap 不换行盒子排在一条线上,wrap 换行。
  • justify-content:设置盒子在主轴方向的对齐方式,flex-start 从起点至终点排列,flex-end 从终点至起点排列,center 从中点至两边扩散,space-between 两端对齐(起点终点紧贴边框)中间均匀分布。
  • algin-items:设置盒子在侧轴方向的对齐方式,flex-start 从起点至终点排列,flex-end 从终点至起点排列,center 从中点至两边扩散,stretch 如果盒子未设置高度那么盒子高度将占满整个容器。

项目属性

  • algin-self:设置在盒子上的 algin-items,为盒子设置侧轴的对齐方式。auto 表示继承容器的 algin-items 值,其余取值与 algin-items 一致:flex-start, flex-end, center, stretch

flex样式的三个值

flexalgin-self 一样是用来设置在盒子上的样式,它是三个属性的缩写:

  • flex-grow:当主轴未被盒子占满,按比例划分主轴上剩余空间。0 盒子宽度不变,不划分剩余空间。如果主轴上所有盒子该值为 1 则它们等分剩余空间;如果有一个盒子该值为 2 其他盒子都为 1,则前者占据剩余空间比其他项多一倍。
  • flex-shrink:当盒子总宽度超过容器宽度,主轴被占满,按比例缩放盒子宽度。1 所有盒子默认该值为 1,当主轴空间不足时,都将等比例缩小。如果一个盒子该值为 0 其他盒子都为 1 ,则主轴空间不足时,前者不缩小。
  • flex-basis:在分配多余空间前,给盒子在容器中一个固定宽度。浏览器根据这个属性,计算主轴是否有剩余空间。auto 盒子宽度为其原本的大小,一个...px值,盒子占主轴固定空间。

flexflex-growflex-shrinkflex-basis. 默认值为 0 1 auto.

参考:
Flex 布局教程:语法篇
一个测试flexbox工具

4. grid

​ Grid 网格布局,是继 flex 布局之后推出的更强大的布局方案。布局分为容器和项目,容器 即是最外层的盒子,项目 是容器的亲儿子盒子,不包括孙子盒子后面几代盒子。Grid只对项目生效。

​ Grid 布局的属性分为 容器属性项目属性。{ display: grid }开启 Grid 布局。

容器属性

  • grid-template-columns / grid-template-rows:指定每一 列 / 行 的大小。可以的取值为:px(数值) / %(百分比) / 1fr(比例) / auto(自适应) .

​ 比如实现一个三栏布局:两边固定中间自适应{ display: grid; grid-template-colums: 200px auto 200px }. 注意这里给的是单元格的size,不是项目的size

  • column-gap / column-gap:列 / 行间隔。可以缩写成 gap:20px(列间间隔) 30px(行间间隔).
  • grid-auto-flow:项目摆放顺序。row 先行后列,column 先列后行。
  • grid-template-areas:将单元格进行分区与合并。

​比如 { display : grid; grid-template-colunms: 100px 100px 100px; grid-template-rows: 100px 100px 100px; }

grid-template-areas: 'header header header' 
                     'main main siderbar' 
                     'footer footer footer'

​ 上面代码中,顶部是页眉区域 header,底部是页脚区域 footer,中间为 mainsider

  • justify-items / algin-items:一个单元格中只能放一个项目,当项目的size小于单元格的size时,用 justify-items 调整项目在单元格内的水平位置,algin-items 调整在单元格的垂直位置。stretch 项目将单元格在水平/ 垂直方向填满,start 项目对齐单元格的起始边缘,end 对齐单元格的结束边缘,center 在单元格内居中。place-itemsjustify-items algin-items 是两者的缩写。

    比如: { place-items: start start } 项目位于单元格左上角; ​ { place-items: center center } 项目位于单元格水平居中和垂直居中; ​ { place-items: end end } 项目位于单元格右下角; { place-items: stretch stretch } 项目将单元格填满;

  • justify-content / align-content:当所有单元格size小于容器的size时,用 justify-content 调整所有单元格在容器内的水平位置,align-content 调整在容器内的垂直位置。

项目属性

  • grid-column-start / grid-column-end / grid-row-start / grid-row-end:设置项目在单元格的摆放位置。网格线从 1 开始编号
    比如:{ grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 4 }设置该项目占 第2,3两行,第1,2两列交叉组成的4个单元格。
    grid-column-start / grid-column-end 可以缩写成 grid-column: < start-line> /
    ;
    grid-row-start / grid-row-end 可以缩写成 grid-row: < start-line> / < end-line>;
    ​ 比如:上面例子可以缩写为{ grid-colum: 1 / 3; grid-row: 2 / 4 }。

  • justify-self / algin-self:用法与 justify-items / algin-items 一致,都是设置容器在单元格内的水平 / 垂直方向的布局。前者是作用于容器中所有项目,后者作用于具体某一个项目。取值都为 start, end, center, stretchplace-selfjustify-self algin-self 是两者的缩写。

参考:
(1)CSS Grid 网格布局教程
(2)Grid_常用属性总结

flex 布局与 Grid 布局的不同:
flex 布局将容器划分坐标系的 交叉轴,相当于在一个单元格内指定项目的摆放位置,属于一维布局Grid 布局将容器划分为多个单元格,相当于在多个单元格内指定项目的摆放位置,同时一个项目可以占据多个单元格,属于二维布局

图文样式

1. line-height

​ 表示文本盒子的高度,原本文本盒子的高度等于文本的font-size的大小,如果指定高度文本盒子等于指定的高度,同时文本会在盒子内垂直居中。

响应式

计量单位

​ 通常,我们给定盒子大小的时候会用 px 直接指定值,然而这样一个值是 绝对单位,它不会随着窗口 size的变化而变化;如果需要响应式布局,需要给定一个相对值,而这个值的单位为 相对单位。CSS中有以下相对单位:

单位相对于
em当前元素的 font-size,1em = 1 * font-size
remhtml元素的 font-size,1rem = 1 * html **font-size
vw浏览器可视窗口宽度的 1%
vh浏览器可视窗口高度的 1%

媒体查询

​ 媒体查询的语法如下:

@media mediatype and|not|only (media feature){ }
  • mediatype:媒体类型,一般取值为 scree 用于电脑屏幕,平板电脑,智能手机等。
  • 关键字:多个查询条件进行连接,and 与、not 非、only 指定特定类型。
  • media feature:媒体特性,筛选条件 min-width 可视窗口最小宽度, max-width 可视窗口最大宽度。

利用媒体查询 -> 根据可视窗口宽度,调整 html 元素 的 font-size -> 利用 rem 调整DOM元素大小

@media screen and (min-width: 374px) {
    html {
        font-size: 86px;
    }
}

@media screen and (min-width: 375px) and (max-width: 413px) {
    html {
        font-size: 100px;
    }
}

@media screen and (min-width: 414px) {
    html {
        font-size: 110px;
    }
}

body{
  font-size: 0.16rem;
}

CSS3

动画

​ 动画是规定一个样式序列,例如:0%css1,25%css2,50%css3,75%css4,100%css5,动画就是在规定时间内将css1~5在某个DOM元素上循序渐进地改变。动画的基本使用:定义 + 调用。

基本使用

​ 使用关键字 @keyframes + 动画名称 定义一个动画,其中每个%对应的样式被称为关键帧。使用{ animation-name:动画名称;animation-duration:动画时长;} 调用动画。

/* 1.定义动画 */

@keyframes move {
    0% {
        transform: translate(0, 0);
    }
    /* 第一个状态 */
    25% {
        transform: translate(1000px, 0);
    }
    /* 第二个状态 */
    50% {
        transform: translate(1000px, 500px);
    }
    /* 第三个状态 */
    75% {
        transform: translate(0, 500px);
    }
    /* 最终态 */
    100% {
        transform: translate(0, 0);
    }
}

div {
    width: 200px;
    height: 200px;
    background: pink;
    /* 2.调用动画 */
    animation-name: move;
    animation-duration: 20s;
}

<body>
    <div></div>
</body>

以上代码实现了一个 div 利用 平移+动画 旋转一圈。

常见属性

  • animation-timing-function:指定动画的播放速度曲线。ease 低速开始,然后加快,在结束前变慢;linear 匀速;steps(n) 将动画每个关键帧的切换分n段执行,每段之间不存在曲线过度而是直接切换。参考:steps介绍
  • animation-delay:指定动画延迟播放时间,从渲染好页面开始计时。0 表示立即播放。
  • animation-iteration-count:指定动画播放次数。1 表示只播放一次;infinite 表示循环播放。
  • animation-fill-mode:指定动画播放完成后保持的状态。backwards 表示播放完回到 0% 的关键帧; forwards 表示回到 100% 的关键帧。
  • animation-play-state:指定动画播放与否。running 表示播放;paused表示停止。通常配合伪类:hover使用。
  • animation-direction:指定动画在下一个播放周期的播放顺序。normal 表示动画与上一个周期播放顺序一致;alternate 表示与上一个周期播放顺序相反。
div {
  width: 100px;
  height: 100px;
  background-color: aquamarine;
  /* 动画名称 */
  animation-name: move;
  /* 动画花费时长 */
  animation-duration: 2s;
  /* 动画速度曲线 */
  animation-timing-function: ease-in-out;
  /* 动画等待多长时间执行 */
  animation-delay: 2s;
  /* 规定动画播放次数 infinite: 无限循环 */
  animation-iteration-count: infinite;
  /* 是否逆行播放 */
  animation-direction: alternate;
  /* 动画结束之后的状态 */
  animation-fill-mode: forwards;
}

div:hover {
  /* 规定动画是否暂停或者播放 */
  animation-play-state: paused;
}