CSS全解(前端面试重难点)

1,405 阅读10分钟

文章的行文思路都是按照博主个人对相关知识的理解做编写,综合了权威书籍和诸多贴文的解释,最后编写为方便自己个人理解的版本。

选择器权重

1000    行内样式 如 style=""
0100    id选择器  如 #id=""
0010    class 伪类 属性选择器 如 .class | :hover,:link,:target | [type]
0001    标签  伪元素  如 p | ::after, ::before, ::fist-inline, ::selection
0000    通配符选择器(*),  子选择器(>), 相邻同胞选择器(+)等选择器
继承的样式没有权值

三栏布局

圣杯布局

圣杯布局及原理详解之浮动,负margin,百分比_Sallywa的博客-CSDN博客_圣杯布局原理

.container{
            
            margin-left: 200px;
            margin-right: 200px;
        }
        .main {
            float: left;
            width: 100%;        
            height: 200px;    
            background-color: bisque;
        }
        .left {
            float: left;
            position: relative;
            right: 200px;
            width: 200px;
            height: 200px;
            margin-left: -100%;
            /* position: relative; */
            background-color: blue;
        }
        .right {
            float: left;
            position: relative;
            left: 200px;
            width: 200px;
            height: 200px;
            margin-left: -200px;
            background-color: cadetblue;
        }
<!-- 圣杯 -->
    <div class="container">
        <div class="main"></div>
        <div class="left"></div>
        <div class="right"></div>
    </div>

双飞翼布局

.box {
            float: left;
            width: 100%;
        }
        .mid {
            margin-left: 200px;
            margin-right: 200px;
            height: 200px;
            background-color: #456212;
        }
        .l{
            float: left;
            width: 200px;
            height: 200px;
            margin-left: -100%;
            background-color: chartreuse;
        }
        .r {
            float: left;
            width: 200px;
            height: 200px;
            margin-left: -200px;
            background-color: coral;
        }
<div class="box">
        <div class="mid"></div>
    </div>
    <div class="l"></div>
    <div class="r"></div>

Flex布局

.hezi {
            width: 100%;
            display: flex;
        }
        .zuo {
            width: 200px;
            height: 200px;
            background-color: deeppink;
        }
        .you {
            width: 200px;
            height: 200px;
            background-color: darkmagenta;
        }
        .zhong {
            flex:1;
            height: 200px;
            background-color: darkcyan;
        }
<div class="hezi">
        <div class="zuo"></div>
        <div class="zhong"></div>
        <div class="you"></div>
    </div>

流体布局 (float+margin)

.l {
            float: left;
            width: 200px;   
            height: 200px;
            background-color: #d23120;

        }
        .r {
            float: right;
            width: 200px;   
            height: 200px;
            background-color: #999921;
        }
        .m {
            margin-left: 210px;
            margin-right: 210px;
            height: 200px;
            background-color: #7722aa;
        } 

绝对定位布局

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      body > * {
        min-height: 100px;
      }
      
      .left {
        position: absolute;
        left: 0;
        width: 300px;
        background: red;
      }
      .right {
        position: absolute;
        right: 0px;
        width: 300px;
        background: yellow;
      }
      
      .content {
        background: green;
        position: absolute;
        left: 300px;
        right: 300px;
      }
      
    </style>
  </head>
  <body>
    <section class="left"></section>
    <section class="right"></section>
    <section class="content"></section>
  </body>
</html>

双栏布局

<style>
        /*1 BFC 双栏布局  */
    .left{
        float: left;
        width: 200px;
        height: 200px;
        background-color: aqua;
    }
    .right {
        overflow: hidden;
        text-align: right;
        height: 200px;
        background-color: aquamarine;
    }
    .main {
        width: 100%;
    }

    /* 2 flex布局 */
    .left{
        width: 200px;
        height: 200px;
        background-color: aqua;
    }
    .right {
        flex: 1;
        
        height: 200px;
        background-color: aquamarine;
    }
    .main {
        display: flex;
    }

    /* 3 float margin-left */
    .left{
        visibility: hidden;
        float: left;
        width: 200px;
        height: 200px;
        background-color: aqua;
    }
    .right {
        margin-left: 200px;
        height: 200px;
        background-color: aquamarine;
    }
    .main {
     
    } 

    /*4  绝对定位脱离文档流 */
    .left{
        width: 200px;
        height: 200px;
        background-color: aqua;
    }
    .right {
        position: absolute;
        top: 0;
        left: 200px;
        right: 0;
        height: 200px;
        background-color: aquamarine;
    }
    .main {
        position: relative;
    } 
    
    /*5 table-cell布局 */
    .left{
        width: 200px;
        display: table-cell;
        height: 200px;
        background-color: aqua;
    }
    .right {
        display: table-cell;
        height: 200px;
        background-color: aquamarine;
    }
    .main {
        display: table;
        /* 需要明确指定宽度 */
        width: 100%;

    }

    </style>
<div class="main">
        <div class="left">ss2</div>
        <div class="right">ssss</div>
    </div>

BFC

概念

Block-Formatting-context 块级格式化上下文

​ 格式化上下问的意思是:在浏览器的某一块区域里面有一套自己的渲染规则,不影响外部

​ BFC内部元素不影响外部元素。

作用

  1. 垂直方向上margin重叠 ,若不想重叠可以放在两个不同的BFC里面

  2. 利用浮动元素不覆盖BFC的特点做双栏布局

  3. 可让仅包含浮动元素的div自适应高度

  4. BFC清除浮动

BFC可以解决的问题

​ 1.(BFC与margin)同一个父级块框下,兄弟元素和父子元素的margin会发生重叠问题

​ 2.(BFC与float)父元素高度塌陷问题、兄弟元素覆盖问题

BFC触发条件

  1. float 不为none (浮动元素)
  2. overflow 不为 visible
  3. display 为 flex ,inline-flex,inline-block,table-cell,table-caption
  4. position为 absolute , fixed (绝对定位元素)
  5. 根元素

浮动问题

  • 空标签clear:both
  • 在父类中触发BFC,从而不让父类后续的div收到影响
    • 父类添加overflow
    • 父类after伪元素(做BFC)和zoom属性
    • 父级定义height

常用方案:

<div class="big">
    <div class="d">

    </div>
    <div class="d">

    </div>
</div>
    
    <div class="d1"></div>
.d{
            
            float: left;
            width: 200px;
            height: 200px;
            background-color: deepskyblue;
        
        }
        .d1{
            width: 200px;
            height: 200px;
            background-color: deepskyblue;
            
        }
        .big {
            background-color: dimgray;
            /* overflow: hidden; */
            *zoom: 1;
        }
        .big::after{
            content: "";
            clear: both;
            display: block;
            visibility: hidden;
            height: 0;
        }

盒子模型

  • IE盒模型
    • 盒子的宽高计算是包含 content,padding , border三部分
    • box-sizing:border-box;
  • W3C标准盒模型
    • 盒子的宽高计算是仅包含 content部分
    • box-sizing:content-box;

定位 Position

  • static 默认属性值,即没有定位,遵循正常的文档流对象。
  • relative 相对于在文档流中的位置做定位
  • absolute 脱离文档流,相对于最近的已定位父元素做定位,如果元素没有已定位的父元素,那么它的位置相对于:
  • fixed 脱离文档流,相对于可视窗口做定位。(元素的位置相对于浏览器窗口是固定位置。)
  • sticky 基于用户的滚动位置来定位。在 position:relativeposition:fixed 定位之间切换。
    • 切换的时机根据其top,left等的设置值进行判断
    • top:50px; 即为当页面滚动到该元素到可视区域顶部距离==50px时,切换position的定位方式

水平垂直居中

概括

            行内元素 line-height: 所在块的高度;   text-align:center;

            display: table-cell vertical-align:midde; (仅垂直)
                     flex  justify-content:center; (水平) align-items:center;(垂直)
                     inline-block vertical-align:midde; (仅垂直)

            position:absolute;
                transform: translat(-50%,-50%); top:50%; left:50%;
                margin: auto;  top:0; left:0; right :0; bottom:0;
                margin-left:-1/2*width; margin-top:-1/2*width;  top:50%; left:50%; (需知道宽高)

absolute + 负margin

<style>
  .outer {
    position: relative;
    width: 300px;
    height: 300px;
    background: red;
  }
  
  .inner {
    position: absolute;
    width: 100px;
    height: 100px;
    background: yellow;
    left: 50%;
    top: 50%;
    margin-left: -50px;
    margin-top: -50px;
  }
</style>
<div class="outer">
  <div class="inner">
    12345
  </div>
</div>

优点:

  • 兼容性好
  • 易于理解

缺点:

  • 需要知道子元素的宽高

absolute + auto margin

<style>
		.outer {
			position: relative;
			width: 300px;
			height: 300px;
			background: red;
		}

		.inner {
			position: absolute;
			width: 200px;
			height: 200px;
			background: yellow;
			left: 0;
			right: 0;
			top: 0;
			bottom: 0;
			margin: auto;
  }
</style>
<div class="outer">
		<div class="inner">
			12345
		</div>
</div>

优点:

  • 易于理解
  • 兼容性好

缺点:

  • 需要知道子元素的宽高

absolute + calc

.outer {
  position: relative;
  width: 300px;
  height: 300px;
  background: red;
}

.inner {
  position: absolute;
  width: 200px;
  height: 200px;
  background: yellow;
  left: calc(50% - 100px);
  right: calc(50% - 100px);
}

优点:

  • 易于理解

缺点:

  • 兼容性依赖于 calc,只支持 IE9及以上
  • 需要知道子元素宽高

absolute + transform

.outer {
  position: relative;
  width: 300px;
  height: 300px;
  background: red;
}

.inner {
  position: absolute;
  width: 200px;
  height: 200px;
  background: yellow;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
}

优点:

  • 易于理解
  • 实现简单
  • 无需知道子元素宽高

缺点:

  • 兼容性依赖于 transform,只支持 IE9 及以上

table-cell

.outer {
  width: 300px;
  height: 300px;
  background: red;
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}
.inner {
  display: inline-block;
  width: 200px;
  height: 200px;
  background: yellow;
}

优点:

  • 兼容性好
  • 易于实现
  • 不需要知道子元素宽高
  • 可读性强

flex

.outer {
  display: flex;
  width: 300px;
  height: 300px;
  justify-content: center;
  align-items: center;
  background: red;
}

.inner {
  width: 100px;
  height: 100px;
  background: yellow;
}

优点:

  • 实现简单

缺点:

  • 兼容性依赖于 flex

grid

// 父元素指定子元素对齐方式
.outer {
  display: grid;
  align-content: center;
  justify-content: center;
  width: 300px;
  height: 300px;
  background: red;
}
.inner {
  width: 200px;
  height: 200px;
  background: yellow;
}

// 子元素自己指定对齐方式
.outer {
  display: grid;
  width: 300px;
  height: 300px;
  background: red;
}
.inner {
  width: 200px;
  height: 200px;
  align-self: center;
  justify-self: center;
  background: yellow;
}

优点:

  • 实现简单

缺点:

  • 兼容性依赖于 grid

link和@import的区别

  • link 是从 html 引入的,@import 是从 css 引入的
  • link 会在浏览器加载页面是同步加载 css;页面加载完成后再加载 @import 的 css
  • 优先级 link > @import
  • @import 是 css2.1 加入的语法,只有 IE5+ 才可识别,link 无兼容问题

三角形 扇形

三角形

div {
  width: 0;
  height: 0;
  border: 100px solid transparent;
  border-left-color: red;
}
//自制版本
 div {
            width: 0;
            height: 0;
            border: 20px solid transparent;
            border-bottom: 20px solid red;
        }

扇形

div {
  height: 0;
  width: 0;
  border: 100px solid transparent;
  border-radius: 50%;
  border-left-color: red;
}

JS、CSS动画

JS动画

核心是定时器

HTML5标准规定,setTimeout的最短时间间隔是4毫秒;setInterval的最短间隔时间是10毫秒

大多数电脑显示器的刷新频率是60HZ,大概相当于每秒钟重绘60次。因此,最平滑的动画效的最佳循环间隔是1000ms/60,约等于16.6ms

传统的 JavaScript 动画是通过 setTimeout 或者 setInterval 实现的,但是定时器动画一直存在两个问题:

  • 动画的循环间隔不好控制,设置长了动画显得不够平滑流畅,设置短了浏览器的重绘频率会达到瓶颈,推荐的最佳循环间隔是 17ms(大多数电脑的显示器刷新频率是 60Hz,1000ms/60)
  • 定时器第二个参数只是指定了多久后将动画任务添加到浏览器的 UI 线程队列中,如果 UI 线程处于忙碌状态,那么动画不会立刻执行。

为了解决这些问题,H5 中加入了 requestAnimationFramerequestIdleCallback

requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率

在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然意味着更少的 CPU、GPU 和内存使用量

requestAnimationFrame 是浏览器专门为动画提供的 API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下,动画会自动暂停,有效节省了 CPU 开销

CSS动画

  1. css3的 animation 是css3新增的动画属性,这个css3动画的每⼀帧是通过 @keyframes 来声明的,
  2. keyframes 声明了动画的名称,
  3. 通过 from 、 to 或者是百分⽐来定义 每⼀帧动画元素的状态,
  4. 通过 animation-name 来引⽤这个动画,
  5. 这些相关的动画⼦属性有:
    1. animation-name 定义动画名、
    2. animation-duration 定义 动画播放的时⻓、
    3. animation-delay 定义动画延迟播放的时间、
    4. animationdirection 定义 动画的播放⽅向、
    5. animation-iteration-count 定义播放次数、
    6. animation-fill-mode 定义动画播放之后的状态、
    7. animation-play-state 定义播放状态,如暂停运⾏等、
    8. animation-timing-function 定义播放的⽅式,如恒速播放、艰涩播放等

两者各自的优点:

  • CSS动画

    • 动画流畅
    • 编写简单
    • 性能表现好
  • JS动画

    • 可控性更强

    • 动画效果更丰富

    • JS不存在兼容性问题

Flex 相关知识

Flex 布局教程:语法篇 - 阮一峰的网络日志 (ruanyifeng.com)

  • 容器属性
    • flex-wrap
      • 是否换行
      • wrap
      • nowrap
      • wrap-reverse
    • flex-direction
      • flex-direction属性决定主轴的方向(即项目的排列方向)。
      • row
      • row-reverse
      • column
      • column-reverse
    • flex-flow
      • flex-flow属性是flex-direction属性和flex-wrap属性的简写形式
      • 默认值 row nowrap
    • align-items
      • align-items属性定义项目在交叉轴上如何对齐。
      • flex-start
      • flex-end
      • center
      • baseline
      • stretch
    • justify-content
      • justify-content属性定义了项目在主轴上的对齐方式。
      • flex-start
      • flex-end
      • center
      • space-between
      • space-around
    • align-content
      • align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
      • flex-start
      • flex-end
      • center
      • space-between
      • space-around
      • stretch
  • 项目属性
    • order
      • order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
    • flex-grow
      • flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
    • flex-shrink
      • flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
    • flex-basis
      • flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
    • flex
      • flex属性是flex-grow, flex-shrinkflex-basis的简写,默认值为0 1 auto。后两个属性可选。
    • align-self
      • align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch

伪类和伪元素

  • 伪类:

    • 伪类用于当已有元素处于某种状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。
    • ::hover,::visited , ::link
  • 伪元素

    • 伪元素用于创建一些不在文档树中的元素,并为其添加样式
    • :before 来为一个元素前增加一些文本,并为这些文本增加样式。用户虽然可以看到这些文本,但是这些文本实际并不在文档树中。
  • 区别:

    • 伪类的操作对象时文档树中已有的元素,而伪元素则创建一个文档树以外的元素。
    • 因此他们之间的区别在于:有没有创建一个文档树之外的元素
  • CSS3 规范中要求使用双冒号(::) 表示伪元素,单冒号(:) 表示伪类

scroll offset client

滚动偏移

偏移量

客户区大小