2023前端面试八股文-css(个人汇总自用)

169 阅读10分钟
css3新特性

边框

  • border-radius:创建圆角边框
  • box-shadow:为元素添加阴影
  • border-image:使用图片来绘制边框

背景

  • background-clip:用于确定背景画区
  • background-origin:用于确定背景画区的起始位置
  • background-size:用于调整背景图片的大小,主要用于设定图片的本身
  • background-break:用于元素可以被分成几个独立的盒子(如使内联元素span跨越多行),background-break 属性用来控制背景怎样在这些不同的盒子中显示

文字

  • word-wrap:文字换行方式
  • text-overflow:设置或检索当当前行超过指定容器的边界时如何显示
  • text-shadow:可向文本应用阴影。能够规定水平阴影、垂直阴影、模糊距离,以及阴影的颜色
  • text-decoration:规定添加到文本的修饰

transition 过渡 transform 转换 animation 动画 渐变

  • linear-gradient:线性渐变
  • radial-gradient:径向渐变

flex布局 grid - 栅格布局 盒模型

css怎么实现居中

css 居中的8中方法

参考连接 [css 水平居中(8种方法)、垂直居中(8种方法) - 掘金 (juejin.cn)]

  1. 行内元素 text-align:center
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
    .parent {
        text-align: center;
    }
</style>
</head>
<body>
	<div class='parent'>
		<span>123</span>
	</div>
</body>
</html>

  1. 块级元素

通过设置 margin: 0 auto;来水平居中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            background: skyblue;
            width:200px;
            height:200px;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div class='box'>123</div>
</body>
</html>

  1. 父元素宽度加上fit-content, 子元素float, fit-content根据元素内容确定宽度
        .parent {
            margin: 0 auto;
            width: -moz-fit-content;
            width: -webkit-fit-content;
            width:fit-content;
        }
        .son{
            float: left;
            background: pink;
            width:50px;
            height:50px;
        }
  1. flex弹性盒的方法,父元素设置flex 和justify-content: center;
    <style>
        .parent {
            display: flex;
            justify-content: center;
        }
        .son{
            float: left;
            background: pink;
            width:50px;
            height:50px;
        }
    </style>
  1. 绝对定位, 子元素 left: 50%; transform: translate(-50%, 0);
    <style>
        .parent {

        }
        .son{
            float: left;
            background: pink;
            width:50px;
            height:50px;

            position: absolute;
            left: 50%;
            transform: translate(-50%, 0);
        }
    </style>
  1. 给子元素设置left: 50%; margin-left 为宽度的负一半
    <title>Title</title>
    <style>
        .parent {

        }
        .son{
            float: left;
            background: pink;
            width:50px;
            height:50px;

            position: absolute;
            left: 50%;
            /*负的一半width*/
            margin-left: -25px; 
        }
    </style>

7.left: 0; right: 0

    <style>
        .parent {

        }
        .son{
            float: left;
            background: pink;
            width:50px;
            height:50px;

            position: absolute;
            left:0;
            right:0;
            margin:0 auto;
        }
    </style>

垂直居中:

  1. 行内元素,设置line-height等于行高

  2. 基本思想是使用display: inline-block, vertical-align: middle和一个伪元素让内容块处于容器中央.

    <style>
        .parent {
            background: #ccc;
            height: 200px;
        }
        .son{
            width: 50px;
            height: 50px;
            background: pink;
        }
        .parent::after, .son{
            display:inline-block;
            vertical-align:middle;
         }
        .parent::after{
            content:'';
            height:100%;
        }
    </style>
  1. 使用table布局 display: table-cell; vertical-align: middle;
  2. Flex弹性盒, display: flex; align-items: center;
  3. 绝对定位+transform position: absolute; top: 50%; transform: translate( 0, -50%);
  4. top:50% ; position: absolute; top: 50%; /*-0.5 height*/ margin-top: -25px;
  5. top/bottom: 0; position: absolute; top: 0; bottom: 0;
flex两个轴居中的属性,轴方向调换用的是

参考文档[Flex 布局教程:语法篇 - 阮一峰的网络日志 (ruanyifeng.com)]

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

image.png

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size

主轴上的对齐方式,通过justify-content设置:

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

交叉轴的对齐方式,通过设置align-items:

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

flex-direction属性决定主轴的方向(即项目的排列方向):

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

image.png

  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿。
flex:1,什么作用

参考文档[flex:1 到底代表什么? - 知乎 (zhihu.com)]

flex: 1; === flex: 1 1 auto;

  • 第一个参数表示: flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
  • 第二个参数表示: flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
  • 第三个参数表示: flex-basis 给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 auto, 即项目本身的大小
flex-grow的作用

flex-grow属性在MDN上的定义是:

定义弹性盒子项(flex-item)的拉伸因子,默认值0”

用来设置子元素来瓜分父元素的剩余空间的比例

flex-basis的作用

flex-basis

MDN定义:指定了 flex 元素在主轴方向上的初始大小 max-width/min-width > flex-basis > width > box

z-index小的反而在上层的原因

参考[z-index细解:一个z-index的值很大为何却在一个很小的值下面? - 掘金 (juejin.cn)] 因为z-index依赖于父元素z-index ,

这个一个拼爹的属性,你再大再牛逼,你爹没我大没我牛逼,你还是得在我下面

应式布局

响应式布局指的是同一页面在不同屏幕尺寸下有不同的布局。传统的开发方式是PC端开发一套,手机端再开发一套,而使用响应式布局只要开发一套就够,缺点就是CSS比较重。 响应式布局实现的方案:

  1. 媒体查询CSS3媒体查询可以让我们针对不同的媒体类型定义不同的样式,当重置浏览器窗口大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面。

  2. 百分比布局 通过百分比单位,可以使得浏览器中组件的宽和高随着浏览器的高度的变化而变化,从而实现响应式的效果。Bootstrap里面的栅格系统就是利用百分比来定义元素的宽高,CSS3支持最大最小高,可以将百分比和max(min)一起结合使用来定义元素在不同设备下的宽高。

  3. rem布局, rem单位都是相对于根元素html的font-size来决定大小的,根元素的font-size相当于提供了一个基准,当页面的size发生变化时,只需要改变font-size的值,那么以rem为固定单位的元素的大小也会发生响应的变化。

  4. rem布局的缺点: 在响应式布局中,必须通过js来动态控制根元素font-size的大小,也就是说css样式和js代码有一定的耦合性,且必须将改变font-size的代码放在css样式之前

  5. vw/vh布局:vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度,除了vwvh外,还有vminvmax两个相关的单位

旋转动画css,怎么去做

通过关键帧技术, @keyframes 配合transform:rotate();来实现

dom树和cssom树原理

参考[浏览器渲染流程(上) DOM树、CSSOM树、布局 - 掘金 (juejin.cn)]

  1. 解析HTML,生成DOM树

  2. 解析CSS,生成CSSOM树

  3. 布局(Layout)

    • 结合DOM树CSSOM树,生成渲染树
    • 布局计算
  4. 分层(Layer)

  5. 绘制(Paint)

  6. 合成(上面部分是在主线程,而合成部份是在合成线程上执行的\color{red}上面部分是在主线程,而合成部份是在合成线程上执行的上面部分是在主线程,而合成部份是在合成线程上执行的)

    • 光栅化(Raster)
    • 合成(Composite)与显示

为什么要生成DOM树? 因为浏览器不理解和使用HTML,所以需要解析HTML,转换成浏览器能够理解的结构。 生成CSSOM树和生成DOM树的目的一样,都是转换为浏览器能够理解的结构

通过document.styleSheets可以查看最后的结构。CSSOM结构主要是给JavaScript提供操作样式表的能力,以及提供基础的样式信息

为什么link要在前,script标签要在后面呢

参考[为什么link放在头部,script放在尾部? - 掘金 (juejin.cn)]

image.png

问题一:script标签会阻塞页面渲染吗?

答案是肯定的,js会阻塞页面渲染。在浏览器解析html文档的时候,遇到script标签时要等待script标签内容加载并执行完成,因为js可能会修改dom元素,如果先解析html在执行js,js中有修改dom的操作,那就需要重新解析,之前的解析就白做了。

问题二:link标签会阻塞页面渲染吗?

这里回答会或者不会都是不准确的,要分情况讨论,大致分为以下几种情况:

  • 情况一:当script标签和link标签都放在dom元素之前时,由于script会阻塞html解析,而script加载执行之前要求必须完成css加载(因为js可能会修改样式),从而导致了css阻塞解析的假象,实际还是js阻塞了html解析
  • 情况二:当只有link标签(或者script标签在dom元素之后),并且link标签在head(dom之前)时,css不会阻塞html解析,但是会阻塞dom绘制。浏览器在解析html之前会预解析html,找出html中的link,script等依赖项,link在dom之前,也就是说dom绘制依赖css样式,解析完html必须等css也解析完才能开始绘制,也就造成了css阻塞dom绘制;
  • 情况三:当只有link标签(或者script标签在dom元素之后),并且link标签在dom元素之后时,css样式对dom的绘制不会构成依赖,浏览器会先绘制dom,等css样式加载解析完成后,再次解析html,计算样式,进行重绘

问题三:为什么link标签要放在文档头部(head),script标签要放在文档尾部?

经过对上面两个问题的讨论,我们知道script标签会阻塞html解析,从而阻塞页面渲染,这是我们不想看到的,所以一般把script标签放在html文档的最后,或者给script标签加上defer,async参数,强制让script标签延迟加载

link标签不会阻塞html解析,如果link标签放在dom之后,会导致浏览器发生回流重绘,这个开销是非常大的,所以我们一般把link标签放在html文档开头(head)中

保证浏览器不受脚本的恶意攻击,(xss攻击,解决方法)
  • 可以从浏览器的执行来进行预防,一种是使用纯前端的方式,不用服务器端拼接后返回(不使用服务端渲染) 。另一种是对需要插入到 HTML 中的代码做好充分的转义。对于 DOM 型的攻击,主要是前端脚本的不可靠而造成的,对于数据获取渲染和字符串拼接的时候应该对可能出现的恶意代码情况进行判断

  • 使用 CSP ,CSP 的本质是建立一个白名单,告诉浏览器哪些外部资源可以加载和执行,从而防止恶意代码的注入攻击。

  • 对一些敏感信息进行保护,比如 cookie 使用 http-only,使得脚本无法获取。也可以使用验证码,避免脚本伪装成用户执行一些操作。