CSS知识点(必知必会)

883 阅读28分钟

1,什么是伪类、伪元素及二者区别

  • 伪类:伪类是一种css选择器的关键字,符合当前伪类对应状态元素将会应用其对应的样式,比如:hover命中当前鼠标悬停的元素,:link 命中尚未访问的链接,div:first-child命中所有div中第一个孩子结点。

    例如#p2:hover { color : red },当我们鼠标悬停在id为#p2的标签上,该标签将会触发{color : red}的css样式

  • 伪元素:伪元素是一个附加到选择器末尾的关键词p::first-line { color : red },允许对伪元素选中的特定部分修改其样式(注意这里是特定部分,这也是与伪类最大区别)。

    例如p::first-line { color : red }命中的是所有p标签的第一行元素,将会被应用到{ color: red }的样式,如果p标签内有多行,则除了第一行其他行不会被命中。相比较伪类选中的是整个dom元素,而伪元素命中的是某个dom元素的一部分。 再举个例子,p::after { content : 'Hello' }命中的是所有p标签实际内容后的区域,而{ content : 'Hello' }则是在该区域添加一个行内元素内容为Hello,需要注意的是插入的元素并不在实际dom树中。

  • 区别

    • 伪类和伪元素的根本区别在于:它们是否创造了新的元素,伪类没有创建新元素,伪元素创建新元素,但不存在dom结构中
    • 伪类单冒号p:hover,伪元素双冒号p::after
    • 伪类命中是某个完整dom元素,伪元素命中是某个dom元素的一部分
    • 伪类不能插入元素,伪元素可以,但插入元素不在dom树中

2,两种盒模型

  • 标准盒模型box-sizing : content-box:width = 内容宽度 (默认我们使用的是标准盒模型)
  • IE盒模型box-sizing : boder-box:width = 内容+padding+border

3,相对定位与绝对定位

  • 相对定位position: relative:不脱离文档流,参考自身初始位置使用top,left等进行定位,初始位置保持占位,可以使用z-index进行分层。
  • 绝对定位position: absolute:脱离文档流,参考最近一层设有定位属性的父级进行定位,如果父级无定位,则参照body原点定位,可以使用z-index分层。

4,CSS选择器及优先级

优先级

  • 1,!important
  • 2,内联样式
  • 3,ID选择器#el
  • 4,类选择器.el, 属性选择器[type='radio'], 伪类选择器div:hover
  • 5,标签选择器div, 伪元素选择器p::before 全选器与关系选择器对优先级不造成影响(MDN说的)
  • 全选器*
  • 后代选择器div p {}:选中div标签下所有p标签元素
  • 子选择器div>p {}:选中div标签下第一层子元素所有p标签
  • 相邻选择器div+p{}:选中与div同级往后第一个p元素,不是p元素不选中

5,实现自适应浏览器宽高正方形

  • 使用vh/vw:100vw = 当前窗口宽度(html根元素宽度),相当于将窗口宽度分成100份。所以只需要将正方形宽高设置相同的vw即可
    .square { width: 50vw; height: 50vw }
    
  • 使用padding:当前元素padding的百分比是按照其父元素宽度计算,所以只需要设置当前元素宽度百分比与padding-top/padding-bottom相同即可(当前元素height最好设置成0,防止内容填充引起高度变化)
    .square { width: 50%; padding-top: 50%; height:0 }
    
  • 使用伪元素:使用::after在当前元素后添加伪元素,伪元素设置为块级元素,设置其padding-top高度100%(伪元素padding百分比按照当前元素宽度计算),使用伪元素撑开当前元素高度。
    .square { width: 50% }
    .square::after { content:'';display: block; padding-top: 100% }
    

6,ul除了最后一个li其他设置有边框效果

  • 使用:last-child:先设置所有li边框,在使用:last-child选中最后一个li设置无边框
    ul li { border-right: 100px solid red }
    ul li:last-child { border-right: none }
    
  • 使用伪元素嵌套 ul:not(:last-child)
    ul:not(:last-child) { border-right: 100px solid red }
    

7,flex:1完整写法

  • 这个问题仔细看会很复杂,为了节省时间先更新其他的。

8,link与@import区别

  • link<link rel="stylesheet" type="text/css" href="main.css"
  • @import<style>@import(main.css)</style>
  • 区别
    • :link标签除了可以导入css文件还可以导入其他文件比如js脚本。@import 只可以导入css文件
    • link标签在页面加载的时候同时加载css,而@import则在页面加载完成之后加载css
    • link标签在head标签内,而@import在style标签内或者css样式中

9,实现该CSS样式(不是很复杂,建议看完)

  • 需求: 屏幕中间有个A元素,A元素中间有个文字A,随着屏幕变化使得样式始终满足下面要求

    • A元素垂直居中屏幕中央

    • A元素距离屏幕左右边距各100px

    • A元素中间文字A大小20px,水平垂直居中

    • A元素高度始终为其宽度50%

  • 实现:实现方式在下面html注释中,按照注释标的序号看。

    
    <!DOCTYPE html>
    
    <head>
        <style>
            .A {
                /*  background-color设置方便查看 */
                background-color: red;
    
                /* 1,使得A元素垂直居中屏幕中央,利用定位top:50%+translateY(-50%)实现 */
                position: absolute;
                top: 50%;
                transform: translateY(-50%);
                /* 2,A元素左右距离屏幕各100px,使用left,reght拉升 */
                left: 100px;
                right: 100px;
                /* 6,
                    6.1,A元素高度始终是其宽度50%,使用paddingTop:(A元素宽度*50%)+height:0撑起元素高度。
                    6.2,A元素宽度 = A元素父元素宽度(100%) - 100px*2 
                    6.3,这里我们使用calc计算padding-top, padding-top: calc((100% - 200px) * 0.5);
                 */
                padding-top: calc((100% - 200px) * 0.5);
                height: 0;
    
            }
    
            .textA {
                /*  background-color设置方便查看 */
                background-color: rosybrown;
    
                /* 3,A元素中的A文字需要fontsize为20px*/
                font-size: 20px;
                /* 4,A元素中的A文字需要水平垂直居中,水平居中使用text-align,*/
                width: 100%;
                text-align: center;
                /* 5,垂直居中使用定位top:50%+translateY(-50%)实现  */
                position: absolute;
                top: 50%;
                transform: translateY(-50%);
            }
        </style>
    </head>
    
    <body>
        <div class="A">
            <div class="textA">A</div>
        </div>
    </body>
    
    </html>
    

10,常用的css单位有哪些

  • px:像素,不同分辨率px个数不一样,比如分辨率100*100则横着100个像素竖着100个像素。
  • em:相对于使用em的dom元素它的父元素字体大小计算,比如<div style="font-size : 10px"><p style="font-size: 2em"></p><div>,父元素div字体大小为10px,那么1r=em就为10px,所以p元素字体大小2em实际为20px。
  • rem:相对于使用em的dom元素它的根元素(html)字体大小计算,比如<html style="font-size : 10px"><p style="font-size: 2em"></p><html>,html根元素字体大小为10px,那么1r=em就为10px,所以p元素字体大小2em实际为20px。
  • vh:1vh为视口高度(审查元素里面的html高度)1%
  • vw:1vw为视口宽度(审查元素里面的html宽度)1%

11,css选择器优先级

!important>内联样式>id选择器>类选择器/伪类选择器>标签选择器

12,实现动画几种方式

  • 使用伪类:hover:该方式无过渡
.app {
    background-color: red;
    width: 100px;
}

.app:hover {
    width: 200px;
    background-color: blue;
}
  • 使用transition:该方式一般配合:hover、:active等伪类使用,它由四个合成属性组成,可以控制需要动画的属性,控制动画的过渡时间,控制动画的过度方式(匀速,先快后慢等),控制动画延迟时间。
    • transition-property:控制需要动画的属性
      • transition-property:all:所有可以动画的属性都进行动画
      • transition-property:none:无动画效果
      • transition-property:width,height...:自定义需要进行动画的属性
    • transition-duration:控制动画的过渡时间
      • transition-duration: 1s:动画在1s内过度完成
      • transition-duration: 1s,2s,3s:按照顺序对应transition-property三个属性分别的动画过渡时间
    • transition-timing-function:控制动画的过渡方式
      • transition-timing-function:linear:动画匀速过渡
      • transition-timing-function:ease:默认值,慢速开始,中间变快,慢速结束
      • 还有很多...
    • transition-delay:控制动画延迟开始的时间 * transition-delay:3s:等三秒,动画开始
.app {
    background-color: red;
    width: 100px;
    transition: all 1s linear 3s
}

.app:hover {
    width: 200px;
    background-color: blue;
    transition: all 1s linear 3s
}

13,css实现半圆与三角形及简单扇形

  • 半圆
.circle {
  width: 100px;
  height: 50px;
  border-radius: 50px 50px 0 0;
}
  • 三角形
 .triangle {
  width: 0;
  border: 100px solid red;
  border-left-color: transparent;
  border-bottom-color: transparent;
  border-right-color: transparent;
}
  • 扇形
.fan{
	width:100px;
    height:100px;
    border-radius:100% 0 0 0 ;
}

14,移动端1px问题及解决方案

  • 1px问题:我们PC端的dpr为1,不会出现1px问题,dpr = 物理像素/css像素,dpr为1意味着1个物理像素(物理像素就是实际屏幕发光的小点)对应着1个css像素(css像素就是常设置的1px),但是移动端可不会这么乖,移动端dpr可能是1,2,或者3,屏幕越高清,dpr越高,这就意味着移动端dpr为2时,设置1px在移动端将对应2个物理像素(或者说2个屏幕发光点),所以移动端设置1px将会发现变粗了(因为对应2个物理像素在发光)。
  • 解决方案:
    • 直接使用0.5px:假设当前移动端设备dpr为2,意味着设置1px将对应2个物理像素,那我们希望实现1个物理像素,可以设置0.5px,就是对应1物理像素,但是0.5px方法兼容性并不好,谷歌火狐浏览器都会将0.5px转换成1px再进行换算物理像素。

    • 使用伪元素+绝对定位+缩放:比如原先我们设置border-top:1px solid black,现在我们要做的是取消border设置,加入伪元素高度1px,然后进行绝对定位放置在border-top位置,同时使用scaleY(0.5)将伪元素垂直方向缩放原来的0.5,就可以使得1px变成0.5px。如下,分别是一条0.5pxborder,与四条0.5pxborder。(注意,其父元素需要设置定位,否则伪元素相对定位就相对其他元素了。)

                   /* 一条0.5px border */
      .app {
          background-color: pink;
          width: 100px;
          height: 100px;
          position: relative;
      }
      
      .app::after {
          content: '';
          width: 100%;
          height: 1px;
          transform: scaleY(0.5);
          background-color: black;
          position: absolute;
          top: 0px;
          left: 0;
      }
      

      image.png

              /* 四条0.5px border */
      .app {
          background-color: pink;
          width: 100px;
          height: 100px;
          position: relative;
      }
      
      
      .app::after {
          content: " ";
          position: absolute;
          top: 0;
          left: 0;
          width: 200%;
          height: 200%;
          transform: scale(0.5);
          transform-origin: left top;
          box-sizing: border-box;
          border: 1px solid chocolate;
          border-radius: 4px;
      }
      

      image.png

    • 设置meta标签缩放页面:比如现在我们页面dpr为2,我们设置1px将对应2物理像素,那我们将我们的页面进行缩放原先的1/2,此时我们设置的1px实际上被缩放至0.5px,0.5px对应1物理像素,所以此时我们写的1px === 1物理像素

      // meta标签告诉浏览器该做些什么
      const dpr = window.devicePixelRatio
      const meta = document.createElement('meta')
      meta.setAttribute('name','viewport')
      // 宽为设备宽度,禁用用户缩放,默认缩放1/dpr,最大缩放比例1/dpr,最小缩放比例1/dpr
      meta.setAttribute('content',`width=device-width,user-scalable=no,initial-scale=${1/dpr},maximum-scale=${1/dpr},minimum-scale=${1/dpr}`)
      

17,什么是浮动及清除浮动的方式

  • 浮动:当元素设置float属性,该元素将会脱离标准文档流,浮动在父元素左右边界内,但是由于浮动元素脱离标准文档流,父元素计算高度时不会将浮动元素高度计算进去,这就导致了父元素高度塌陷,但这往往不是我们想要的,我们期望元素浮动的同时,父元素计算高度还可以将浮动元素高度计算进去。达到这个效果的过程叫做清除浮动。
  • 清除浮动方式
    • 使用clear属性:clear属性规定元素哪一边不允许出现浮动元素,如果声明clear属性,比如clear:left,这意味着clear元素不允许左边出现浮动元素,如果左边出现浮动元素,clear元素上边框将会顶着左边浮动元素下边距达到clear元素某一边允许出现浮动元素的规定,由于clear元素并未脱离标准文档流,父元素计算高度时一定包括clear元素撑起来的高度,而 clear元素撑起来的高度 = 浮动元素高度 + clear元素高度 ,所以我们只需要添加clear元素且其高度为0就能使得父元素高度等于浮动元素高度。
      // 这里设置clear元素使用伪元素方式,使用伪元素需要注意设置display:block
      // 因为伪元素为行内元素,clear属性针对块级元素生效。
      .container::after{
          content:'',
          display:block,
          clear:both
      }
      
  • 使得父级元素形成BFC:BFC,块格式上下文规定了计算块格式上下文时其中的浮动元素高度也参与计算,所以很简单,只要使得父级元素行程块级格式上下文就可以。
     // 满足下面任意生成块格式上下文的方式即可
     // 1float值不为none
     // 2overflow值不为visible
     // 3position为fixed/absolute
     // 4displayflex/inline-block/inline-flex等
     // 这里我们采用2方法 设置父元素overflow: hidden
     .container {
        overflow: hidden
     }
    

18,transform+动画与直接top,left+动画区别

  • transform+(transition或者animation)会创建合成图层,一定程度上避免回流重绘
    • 注意:单独使用transform 需要指定transformZ才会生成合成图层
  • top,left+(transition或者animation)不会创建合成图层,会导致整个页面(根合成图层)回流重绘

19,上下固定,中间滚动布局实现

  • 使用flex布局:设置上中下三个flex,且容器flex方向设置为垂直实现上中下三栏,中间设置overflow:auto形成滚动布局。
    <!DOCTYPE html>
    <head>
        <style>
            html,
            body {
                height: 100%;
            }
            .container {
                width: 100%;
                height: 100%;
                background-color: red;
                display: flex;
                flex-direction: column;
            }
            .header {
                flex: 1;
                background-color: rosybrown;
            }
            .content {
                flex: 10;
                background-color: salmon;
                overflow: auto;
            }
            .footer {
                flex: 1;
                background-color: royalblue
            }
            .scroll {
                height: 1000px;
                background-color: seashell;
            }
        </style>
    </head>
    
    <body>
        <div class="container">
            <div class="header"></div>
            <div class="content">
                <div class="scroll">
                    1
                </div>
            </div>
            <div class="footer"></div>
        </div>
    </body>
    
    </html>
    
    • ps:overflow四个属性
      • hidden:超出部分截取
      • visible:对象将被剪切为包含对象的window大小
      • auto:有多大展示多大,超出时加入滚动条
      • scroll:总是显示滚动条
  • 使用定位:主要将中间部分使用绝对定位,设置top:100px;left:0;bottom:100px;width:100%进行拉伸。
        <!DOCTYPE html>
    
    <head>
        <style>
            html,
            body {
                height: 100%;
            }
    
            .container {
                width: 100%;
                height: 100%;
                background-color: red;
                position: relative;
            }
    
            .header {
                position: fixed;
                height: 100px;
                top: 0;
                left: 0;
                background-color: sienna;
            }
    
            .content {
                position: absolute;
                right: 0;
                top: 100px;
                left: 0;
                bottom: 100px;
                background-color: salmon;
                overflow: auto;
            }
    
            .footer {
                position: fixed;
                height: 100px;
                bottom: 0;
                left: 0;
                background-color: royalblue
            }
    
            .scroll {
                height: 1000px;
                background-color: seashell;
            }
        </style>
    </head>
    
    <body>
        <div class="container">
            <div class="header"></div>
            <div class="content">
                <div class="scroll">
                    1
                </div>
            </div>
            <div class="footer"></div>
        </div>
    </body>
    
    </html>
    

20,:nth-child与:nth-of-type区别

  • ul li:nth-child(n) { color: sienna; }命中规则:选中ul,查找ul第n个子元素,如果该子元素是li,则选中
  • ul li:nth-of-type(n) { color: sienna; }命中规则:选中ul下面所有li元素,第n个li元素,被选中
  • 主要区别就是:nth-child在计算ul元素下子元素会包含所有类型子元素作为顺序一期计算,再命中设定好要命中的元素(li),nth-of-type会先选出父元素ul下所有设定好的子元素(li)计算顺序再命中。

21,<img/>是什么元素

  • 是行内元素,但是可以设置宽高
  • 屏幕中占比大小与图片实际像素一致,除非设置宽高

22,flex布局如何将8个元素分两行放置

容器flex方向水平,flex-wrap设置wrap换行,子元素宽度设置25%

<!DOCTYPE html>

<head>
   <style>
       div {
           display: flex;
           flex-direction: row;
           flex-wrap: wrap;
       }

       span {
           width: 25%; 
           /* 或者 flex : 0 0 1; 不放大 不缩小 占据株洲空间25% */
           background-color: royalblue;
           height: 100px;
       }
   </style>
</head>

<body>
   <div>
       <span>1</span>
       <span>2</span>
       <span>3</span>
       <span>4</span>
       <span>5</span>
       <span>6</span>
       <span>7</span>
       <span>8</span>
   </div>
</body>

</html>

23,Css实现不知宽高的div水平垂直居中的方式

  • 绝对定位+translate(-50%,-50%):
<!DOCTYPE html>
<head>
    <style>
        .container {
            position: relative;
            height: 200px;
            background-color: red;
        }
        .content {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: moccasin;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="content">
            Tsuki
        </div>
    </div>
</body>
</html>
  • 使用flex布局,justify-content居中,align-items居中:
<!DOCTYPE html>
<head>
    <style>
        .container {
            height: 200px;
            background-color: red;

            display: flex;
            flex-direction: row;
            justify-content: center;
            align-items: center;

        }
        .content {
            background-color: moccasin;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="content">
            Tsuki
        </div>
    </div>
</body>

</html>

24,flex布局中align-items、align-content以及align-self区别。

  • align-items:作用于父容器,指定一行子元素时其子元素在非主轴方向排列方式,左对齐,居中还是怎样。
  • align-content:作用域父容器,与align-items差不多,不过它针对于多行子元素时生效。
  • align-self:作用于子元素,控制某一子元素非主轴排列方式。

25,简述Grid布局

没用过,看过忘了暂且不更

26,实现左右100px,中间自适应三列布局(三种方式)

  • 定位拉伸:
<!DOCTYPE html>

<head>
    <style>
        html,
        body {
            height: 100%;
        }

        .left {
            background-color: red;
            height: 100%;
            width: 100px;

            position: absolute;
            top: 0;
            left: 0;
        }

        .mid {
            background-color: sienna;
            height: 100%;

            position: absolute;
            top: 0;
            left: 100px;
            right: 100px;
        }

        .right {
            background-color: blue;
            height: 100%;
            width: 100px;

            position: absolute;
            top: 0;
            right: 0;
        }
    </style>
</head>

<body>
    <div class="left"></div>
    <div class="mid"></div>
    <div class="right"></div>
</body>

</html>
  • flex布局:左右100px,中间flex:1:
<!DOCTYPE html>

<head>
    <style>
        html,
        body {
            height: 100%;
        }
        .container {
            height: 100%;
            display: flex;
            flex-direction: row;
        }
        .left {
            background-color: red;
            height: 100%;
            width: 100px;
        }

        .mid {
            background-color: sienna;
            height: 100%;

            flex: 1;
        }

        .right {
            background-color: blue;
            height: 100%;
            width: 100px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="left"></div>
        <div class="mid"></div>
        <div class="right"></div>
    </div>
</body>

</html>
  • 左右浮动+margin/padding拉伸:中间使用margin/padding:0 100px,左右各采取左右浮动。
<!DOCTYPE html>

<head>
    <style>
        html,
        body {
            height: 100%;
        }
        .container {
            height: 100%;
        }
        .left {
            background-color: red;
            height: 100%;
            width: 100px;
            float: left;
        }
        .mid {
            background-color: sienna;
            height: 100%;
            padding: 0 100px;
        }
        .right {
            background-color: blue;
            height: 100%;
            width: 100px;
            float: right;
        }
        
    </style>
</head>

<body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
        <div class="mid"></div>
    </div>
</body>

</html>
  • 左右浮动+BFC:中间使用display:flow-root生成bfc,利用bfc不与浮动元素发生重叠特性,设置高百分百,宽自动被拉伸到剩余宽度,左右各采取左右浮动。
<!DOCTYPE html>

<head>
    <style>
        html,
        body {
            height: 100%;
        }
        .container {
            height: 100%;
        }
        .left {
            background-color: red;
            height: 100%;
            width: 100px;
            float: left;
        }
        .mid {
            background-color: sienna;
            height: 100%;
            display:flow-root
        }
        .right {
            background-color: blue;
            height: 100%;
            width: 100px;
            float: right;
        }
        
    </style>
</head>

<body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
        <div class="mid"></div>
    </div>
</body>

</html>

ps:注意前两种带有左右浮动的三栏布局中的mid元素应该放在左右浮动元素最后,因为mid元素作为块元素会独占一行,如果放中间,右浮动元素发现父元素被mid元素一行占满了将会换行下去。

27,实现屏幕 占满/未占满时,footer元素固定在底部

  • 使用position:absolute/fixed定位在底部
<!DOCTYPE html>

<head>
    <style>
        html,
        body {
            height: 100%;
        }

        .footer {
            height: 100px;
            background-color: sienna;

            position: absolute;
            left: 0;
            bottom: 0;
            right: 0;
        }
    </style>
</head>

<body>
    <div class="footer"></div>
</body>

</html>
  • flex布局:父容器主轴垂直,高100%,内部放入两个元素,第一个元素用来放置除了footer外其他所有内容,对其设置flex:1,footer元素宽100%,高自定义。
<!DOCTYPE html>

<head>
    <style>
        html,
        body {
            height: 100%;
        }

        .container {
            height: 100%;
            display: flex;
            flex-direction: column;
        }

        .others {
            flex: 1;
        }

        .footer {
            width: 100%;
            height: 100px;
            background-color: sienna;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="others">1</div>
        <div class="footer">2</div>
    </div>
</body>

</html>

28,css超出省略怎么写,三行超出省略怎么写。

  • 单行:
p {
    width: 100px;
    /* 超出部分隐藏 */
    overflow: hidden;
    /* 超出部分变成省略号 */
    text-overflow: ellipsis;
    /* 如果不设置该属性 white-space 当我们文本内容有换行时还是会换行 */
    white-space: nowrap;

}
  • 多行
p {
    width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-inline-box;
    -webkit-box-orient: vertical;
    word-break: break-all;
    -webkit-line-clamp: 3;
}

29,Css中inherit、initial以及unset区别

  • inherit:css属性有些默认继承有些默认不继承,比如字体可以继承子元素默认继承父元素字体大小,而border是默认不继承的,如果我们希望子元素继承父元素的border则设置border: inherit

  • initial:初始化属性到浏览器默认值,比如color: initial,该颜色将初始化到浏览器默认颜色黑色

  • unset:可以理解为不设置,它其实是initial与inherit组合,比如当前属性是默认继承属性该值等同于inherit,如果是默认不继承属性该值等同于initial

30,响应式布局实现方案

  • 使用媒体查询:根据屏幕大小控制css,不同屏幕大小对应不同设备,具体可参考bootstrap如何根据屏幕大小区分设备。

    • 移动端优先:因为css样式后续样式会覆盖前面样式,所以移动设备优先应该使用min-width,比如下面这个媒体查询,当屏幕宽280px将匹配第一条css,当屏幕宽度560px将匹配第二条css(因为第二条第一条同时匹配,第二条写在后面将覆盖第一条样式),以此类推。
      p { color : yellow }
      @media screen and (min-width: 320px) { p { color : red }}
      @media screen and (min-width: 1024px) { p { color : blue }}
      
    • pc端优先:同移动端反之,优先使用max-width
      p { color : yellow }
      @media screen and (max-width: 1024px) { p { color : red }}
      @media screen and (max-width: 320px) { p { color : blue }}
      ```
    
  • 使用百分比布局:将设计稿的宽度换算成百分比进行设置,但我们需要注意某些百分比相对于谁,比如padding与margin相对于的是父元素的宽,border-radius相对于自身宽度。这个方式缺点很明显,不停的计算非常麻烦。

  • 使用rem做单位布局:rem以html根元素的fontSize为基准,当我们全局使用rem做单位,当窗口变化时只需要动态改变html的fontsize大小即可做到自适应,所以我们可以通过监听窗口变化动态改变html字体大小window.addEventListener('resize',refreshHtmlFontSize)实现

  • 使用vw为基准布局:1vw===屏幕宽度的百分之一,所以我们可以使用Sass函数对css宽度进行处理,然后使用时将css宽度传入该函数进行处理。

    • 处理函数:
    const _width = device-width
    function vm(px){
        return (px/_width)*100vw
    }
    
    • 使用函数
    p { width: vm(100) }
    
  • 图片大小自适应:使用max-width: 100%,使得图片跟着容器大小调节。

img {
	display: inline-block;
   max-width: 100%;
   height: auto
}

31,什么是BFC,如何创建BFC以及其应用场景

  • BFC:BFC(BlockFommatingContext,块级格式上下文)是一种布局规则,规定盒子内部如何布局以及盒子与盒子外如何交互影响。
    • 创建了BFC盒子的布局规则
      • 内部盒子垂直方向排列
      • 内部相邻盒子margin会重叠
      • BFC盒子是一个独立且隔离的容器,里面元素不会影响外面,反之亦然。
      • BFC盒子与同级的浮动元素不会发生重叠
      • 计算BFC盒子高度时,其内部浮动元素高度也会计算进去
  • 如何创建BFC:
    • 根元素(html)自带BFC
    • float属性不为none
    • overflow属性不为visible
    • position属性为fixed/absolute
    • display属性为inline-block或者inline-flex或者flow-root等
    • ps:创建BFC最好的方式是display:float-root,无副作用,该值本质上创建的内容是一个类似于新的根元素(如html所做)
  • 应用场景
    • 清除浮动:因为BFC元素会计算内部浮动元素高度

    • 避免margin重叠:两个元素如果发生margin重叠只需要将其中一个元素外部套一个BFC元素即可

    • 阻止相邻浮动元素覆盖当前元素:将当前元素变为BFC元素即可。

    • 处理自适应两栏布局:左边元素左浮动,右边元素因为设置BFC所以不会与左浮动元素重叠,右边BFC元素不设置宽度将自动填满右半部分。

      .left {
          width:100px;
          height:100%;
          fload:left
      }
      .right {
          display:flow-root
      }
      
      • ps:这种方式非常适合处理两栏/三栏布局,需要注意的是非浮动元素代码书写位置需要在所有浮动元素后面,这样才能实现宽度自适应,否则在浮动元素前面,非浮动元素占满容器剩下,剩下的浮动元素只能换行。

32,实现两栏布局

  • 使用左浮动+BFC:方法见上
  • 使用左浮动+margin拉伸:左边元素左浮动,右边元素设置margin: 0 0 0 100px
    <!DOCTYPE html>
    
    <head>
        <style>
            html,
            body {
                height: 100%;
    
            }
    
            .parent {
                height: 100%;
    
            }
    
            .left {
                background-color: red;
                width: 100px;
                height: 100%;
                float: left;
            }
    
            .right {
                background-color: blue;
                margin: 0 0 0 100px;
                height: 100%;
            }
        </style>
    </head>
    
    <body>
        <div class="parent">
            <div class="left"></div>
            <div class="right"></div>
        </div>
    
    </body>
    
    </html>
    
  • 使用flex布局:左元素固定宽高,右元素设置flex:1
    <!DOCTYPE html>
    
    <head>
        <style>
            html,
            body {
                height: 100%;
    
            }
    
            .parent {
                height: 100%;
                display: flex;
                flex-direction: row;
            }
    
            .left {
                background-color: red;
                width: 100px;
                height: 100%;
            }
    
            .right {
                flex: 1;
                background-color: blue;
            }
        </style>
    </head>
    
    <body>
        <div class="parent">
            <div class="left"></div>
            <div class="right"></div>
        </div>
    
    </body>
    
    </html>
    
  • 使用绝对定位拉伸:左边元素可以使用左浮动,也可以使用绝对定位,右边元素设置绝对定位拉伸top: 0;left: 100px;right: 0;height: 100%
    <!DOCTYPE html>
    
    <head>
        <style>
            html,
            body {
                height: 100%;
    
            }
    
            .parent {
                height: 100%;
                position: relative;
            }
    
            .left {
                background-color: red;
                width: 100px;
                height: 100%;
                float: left;
            }
    
            .right {
                background-color: blue;
                position: absolute;
                top: 0;
                left: 100px;
                right: 0;
                /* bottom: 0; */
                height: 100%;
            }
        </style>
    </head>
    
    <body>
        <div class="parent">
            <div class="left"></div>
            <div class="right"></div>
        </div>
    
    </body>
    
    </html>
    
  • 两栏全部左浮动,按照百分比计算其宽度,父元素清除浮动(太简单了不写了)

33,link引入css样式会阻塞页面渲染吗,js会阻塞吗

  • link:link标签不会阻塞dom解析,但会阻塞页面渲染,因为浏览器并行解析domTree与cssTree,并行解析(cssTree并不会影响domTree生成)当两者解析完毕才会生成renderTree,页面才会渲染,所以尽量减少引入样式文件大小,提高首屏展示速度。
  • script:script标签会阻塞dom解析与渲染,但是在阻塞同时其他线程会继续解析文档其他部分(预解析),找出加载其他网络资源。

34,什么是回流重绘,触发因素以及如何优化。

  • 回流(reflow):当我们改变某一dom元素尺寸属性时,不仅当前dom元素受到影响,其他dom元素的位置也会受到影响,这时候会重新进行样式计算,布局,绘制及后面所有流程

  • 重绘(repaint):当我们改变某元素的颜色(主要和尺寸无关的属性比如这里的color)会触发样式计算和绘制以及之后的流程

  • 触发因素:

    • 页面首次渲染
    • 浏览器视口放大缩小(resize)
    • dom元素尺寸属性以及位置改变
    • dom元素增删
    • 字体fontSize改变
    • ......
  • 优化

    • css优化:
      • 使用visibility: hidden替代display: hidden:visibility隐藏元素但实际元素还在dom上,display移除dom元素,所以display会导致回流重绘,visibility只会导致重绘。
      • 复杂动画元素使用绝对定位或者fixed:脱离文档流不影响文档流中其他元素
      • 使用硬件加速:硬件加速创建合成层,变化都会在当前合成层变化,不会导致回流重绘,比如使用transform替代top或者设置will-change: transform;生成合成层。
    • js优化
      • 避免频繁操作(样式/dom),合并(样式/dom)操作一次更新
      • 防抖节流阻止js频繁操作
      • 避免对某些属性的频繁读操作:回流重绘的操作会被缓存在任务队列中,等到队列满或者一定时间后一次执行,而读属性时为了拿到最新的属性,会将任务队列中的任务立即执行完毕后获取,如此导致读这些属性也会产生回流。
        • client(Width/Height/Left/Top),offset(...),scroll(...)
        • window.getComputedStyle/element.currentStyle

35,justify-content中space-between与space-around区别

  • space-between:space-between会在容器子元素之间产生等宽间隔,以主轴方向水平举例,左右靠近容器左右变宽的子元素不会与容器产生间隔
  • space-around: space-around也会在容器内子元素之间产生等宽距离,以主轴方向水平举例,左右靠近容器左右变宽的子元素会与容器产生间隔,间隔为子元素之间宽度1/2.

36,position属性有哪些

  • static:position默认值,既元素在文档流中正常布局,zindx,top等属性设置无效

  • relative:相对定位,相对于自身原点定位,可设置zindx,top等属性,且会保留原先位置,不会脱离标准文档流

  • absolute:绝对定位,脱离文档流,相对最近非static的定位祖先元素进行偏移,绝对定位元素可以设置外边距且不会与其他边距合并。

  • fixed:固定定位,脱离文档流,相对于屏幕视口(viewport)定位,因此即使屏幕滚动该元素位置依然保持不变。fixed元素会创建新的层叠上下文(z轴上渲染图层),当其祖先元素transform或filter不为none时,相对的容器由视口改为该祖先元素。

  • sticky:粘性定位,相对于最近的滚动祖先元素定位,且设置top等属性进行偏移量判定,偏移值不会影响任何其他元素位置,该元素也会创建层叠上下文(渲染图层),粘性定位可以看做相对定位与固定定位的混合,元素在跨越阈值之前为相对定位,之后为固定定位

    • 注意须指定 top left right bottom四个阈值其中之一粘性定位才会生效,否则表现形式与相对定位相同

37,css预处理器是什么、解决的问题及其他的优点

  • css预处理器:为css增加变成特性的拓展语言,可以使用变量,简单逻辑判断,函数等编程特性书写期望的CSS。相当于在真实css之间增加了一道桥,当然将我们css预处理器内容翻译成css也需要时间。
  • 解决:
    • 解决css样式不好复用的问题
    • 解决无法嵌套样式,导致很多重复选择器问题
  • 优点
    • 复用性好,修改变量css,使用该变量css样式都会生效
    • 常用代码使用代码块,减少代码冗余
    • 减少重复选择器,降低书写错误发生
    • 额外的工具类似颜色函数,mixins,loops等使得开发者有能力生成更复杂的css样式。

38,什么是标准文档流

  • 标准文档流:内联元素自左向右,空间不够换行继续自左向右排列,块级元素独占一行,自上而下排列的文档布局方式。

  • 如何脱离标准文档流:浮动,绝对定位/fixed定位。

39,CSS实现任意角度扇形

  • 实现原理:利用一个正方形,使用定位在正方形上半部分与下半部分分别实现两个半圆,这两个半圆的transform-origin都是位于正方形中心点,如果180度以内的扇形,则只需要其中一个半圆,另一个半圆隐藏,通过对半圆的rotate进行角度旋转,实现扇形,如果大于180度,则需要两个半圆配合。如下code实现270度扇形。
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <style>
            .container {
                width: 100px;
                height: 100px;
                position: relative;
                background-color: inherit;
            }
    
            .sectorUp {
                position: absolute;
                top: 50px;
                width: 100px;
                height: 50px;
                background-color: red;
                border-radius: 0 0 50px 50px;
                transform-origin: 50% 0;
                transform: rotate(-180deg);
                z-index: 10;
            }
    
            .hide {
                position: absolute;
                top: 50px;
                width: 100px;
                height: 50px;
                background-color: inherit;
                z-index: 20;
            }
    
            .sectorDown {
                visibility: visible;
                position: absolute;
                width: 100px;
                height: 50px;
                background-color: red;
                border-radius: 50px 50px 0 0;
                transform-origin: 50% 100%;
                transform: rotate(90deg);
                z-index: 30;
            }
        </style>
    </head>
    
    <body>
        <div class='container'>
            <div class="sectorUp"></div>
            <div class="sectorDown"></div>
            <div class="hide"></div>
        </div>
        <script>
        </script>
    </body>
    
    </html>
    

40,flex布局

  • 设置在容器上的flex属性

    • flex-direction:主轴方向

      • flex-direction:row:默认值, 水平方向,起始值在左端
      • flex-direction:row-reverse:水平方向,起始值在右端
      • flex-direction:column:垂直方向,起始值在上端
      • flex-direction:row:垂直方向,起始值在下端
    • flex-wrap:规定主轴线上的子元素超出一行时如何进行换行

      • flex-wrap:nowrap:默认值, 不换行
      • flex-wrap:wrap:换行,第一行位于交叉轴起点
      • flex-wrap:wrap-reverse:换行,第一行位于交叉轴终点🏁 image.png
    • flex-flow:flex-direction与flex-wrap的简写方式,默认值为 flew-flow:row nowrap

    • justify-content:规定主轴上子元素对齐方式,假设下面主轴水平从左到右

      • justify-content: flex-start:默认值, 左对齐
      • justify-content: flex-end:右对齐
      • justify-content: cneter:居中
      • justify-content: space-between:两端子元素对其两边,子元素之间间隔相等
      • justify-content: space-around:每个子元素两侧间隔相等,所以子元素与子元素之间的间隔时双份间隔,子元素与父元素之间为单份间隔
      • justify-content: space-evenly:子元素之间,子元素与容器两侧间隔均相等
    • align-items:规定子元素们如何在交叉轴上对齐,假设下面主轴水平从左到右

      • align-items:stretch:默认值, 如果子元素未设置高度或者高度auto,那么子元素拉伸占满整个容器高度
      • align-items:flex-start:交叉轴起点对齐
      • align-items:flex-end:交叉轴终点对齐
      • align-items:center:交叉轴中点对齐
      • align-items:baseline:第一行子元素文字基线对齐
    • align-content:如果存在多根主轴线(即出现换行),主轴线在交叉轴上的对齐方式,单行该属性不起作用,假设下面主轴水平从左到右

      • align-content: flex-start:主轴线对齐交叉轴起点
      • align-content: flex-end:主轴线对齐交叉轴终点
      • align-content: center:主轴线对齐交叉轴中点
      • align-content: space-between:两端主轴线对齐交叉轴两端,主轴线间间隔平分
      • align-content: space-around:主轴线两侧间隔相等,所以主轴线之间两倍间隔,主轴线与容器间一倍间隔
      • align-content: stretch:默认值 主轴线拉伸占满整个交叉轴
  • 设置在子元素上的flex属性

    • order:默认值为0,整型数字,数字越大,子元素位置越靠后,可以为负值 image.png

    • align-self:允许单个子元素在交叉轴上有自己的对齐方式,可以覆盖父元素设置的align-items,默认值为auto,表示继承父元素align-items属性,如果没有父元素,等同于stretch,除了设置auto之外,其他属性与align-items一致。

    • flex-grow:主轴存在剩余空间时,子元素如何分配这些剩余空间,该值为数字,默认值为0,即存在剩余空间也不放大。flex-grow 计算方式分为以下三种情况,这里假设主轴水平从左到右,主轴有3个子元素,子元素宽度分别是a,b,c,子元素flex-grow分别是x,y,z,主轴剩余宽度为w。

      • 子元素的flex-grow之和大于1(通常情况下都是如此):子元素最终宽度是为子元素原始宽度 + 主轴剩余宽度 *(当前子元素flex-grow/所有子元素flex-grow和)。所以三个子元素伸展后的宽度分别是

        • a + w * (x/(x+y+z))
        • b + w * (y/(x+y+z))
        • c + w * (z/(x+y+z))
      • 子元素的flex-grow之和小于等于1::子元素最终宽度是为子元素原始宽度 + 主轴剩余宽度 *(当前flex-grow/1),所以三个子元素伸展后的宽度分别是

        • a + w * (x/1)
        • b + w * (y/1)
        • c + w * (z/1)
      • 子元素设置了max-width:如果子元素最后flex-grow后的结果大于max-width,那么max-width将优先使用。

    • flex-shrink:规定主轴空间不足时,子元素如何收缩自己以适应有限空间。默认值为1,子元素具体如何收缩跟自身主轴方向宽/高也有关,具体计算方式如下:这里假设主轴水平从左到右,主轴有3个子元素,子元素宽度分别是x,y,z,子元素flex-shrink分别是a,b,c,子元素超出主轴宽度为w(w=a+b+c-主轴宽度)。

      • 子元素的flex-shrink之和大于1:子元素最终宽度是为子元素原始宽度 - 超出主轴宽度 *(当前flex-shrink*当前子元素宽度/所有子元素(flex-shrink*其宽度)的和),所以三个子元素伸展后的宽度分别是
        • a - (w * (x*a) / (x*a+y*b+z*c)) * 1
        • b - (w * (y*b) / (x*a+y*b+z*c)) * 1
        • c - (w * (z*c) / (x*a+y*b+z*c)) * 1
      • 子元素的flex-shrink之和小于等于1:子元素最终宽度是为子元素原始宽度 - (超出主轴宽度*(所有子元素flex-shrink和/1)) *(当前flex-shrink*当前子元素宽度/所有子元素(flex-shrink*其宽度)的和),所以三个子元素伸展后的宽度分别是
        • a - (w * (x*a) / (x*a+y*b+z*c)) * ( a+b+c )/1
        • b - (w * (y*b) / (x*a+y*b+z*c)) * ( a+b+c )/1
        • c - (w * (z*c) / (x*a+y*b+z*c)) * ( a+b+c )/1
      • 子元素设置了min-width:如果子元素最后flex-shrink后的结果小于min-width,那么min-width将优先使用。
    • flex-basis:规定子元素main-size(即横轴就是子元素的宽度,纵轴就是子元素的高度)的大小,默认值为'auto',即子元素本来的大小,横轴中即子元素的宽。 flex-basis设置后优先级大于子元素的width,但是小于min-width和max-width。

    • flex:flex-grow flex-shrink flex-basis 简写,默认值flex:0 1 auto,有以下几种常见简写

      • flex:1:即flex:1 1 0,可以伸展,可以收缩,子元素宽度为0
      • flex:auto:即flex:1 1 auto,可以伸展,可以收缩,子元素宽度为原始宽度
      • flex:none:即flex:0 0 auto,不可伸展,不可收缩,子元素宽度为原始宽度
      • flex如果两个值,第一个是flex-grow,第二个如果是数字是flex-shrink,如果是宽度(px,百分比,rem等)则是flex-basis。
      • flex三个值,即flex-grow,flex-shrink,flex-basis

感谢参考: