【前端面试手册】CSS系列-回流与重构

news2024/9/30 7:26:26

在这里插入图片描述

本专栏收录于前端面试手册-CSS系列如果该文章对您有帮助还希望你能点一个小小的订阅,来增加博主创作的动力✍🏻话不多说开始进入正题

回流和重构在前端CSS中是一个常见的问题,那么你对回流何重构有哪些了解呢?

一、什么场景下会触发回流和重构,如何减少回流重构?

想要回答这个问题首先要知道什么是回流和重构,然后从回流重构的

1.什么是回流和重构

重构

当元素的某些属性发生变化,这些属性又只影响元素的外观和风格,而不改变元素的布局、大小比如颜色、背景。 此时触发的浏览器行为称作重构。

回流

当元素的布局、大小规模和显示方式发生改变时,触发的浏览器行为叫回流

浏览器行为规范

首先,要解析HTML和CSS,分贝生成DOM树,CSSOM树,然后将DOM树和CSSOM树结合,生成渲染树

Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)

Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素

Display:将像素发送给GPU,展示在页面上

2.触发回流情况

①添加或删除可见的DOM元素

②元素的位置发生变化

③元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)

④内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代

⑤页面一开始渲染的时候(这避免不了)⑥浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

⑥获取一些特定属性的值(该属性们都需要通过计算来得到)

offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

3.重绘触发时机

触发回流一定会触发重绘,但触发重绘不一定触发回流

元素属性(颜色,阴影,背景颜色等)的修改就是重绘

4.如何使回流重绘得到优化

①如果想设定元素的样式,通过改变元素的 class 类名

②尽量避免内联样式的使用

③应用元素的动画,使用 position 属性的 fixed 值或 absolute

④由于table布局中若有一个元素修改,则需要重新计算所有的,所以我们可以避免使用table布局,从而达优化的目的

⑥使元素脱离文档流,从而减少对其他元素的影响

⑦使用css3硬件加速,可以让transformopacityfilters这些动画不会引起回流重绘

⑧避免使用 CSS 的 JS 表达式

⑨在使用 JavaScript 动态插入多个节点时, 可以使用DocumentFragment. 创建后一次插入. 就能避免多次的渲染性能

但有时候,我们会无可避免地进行回流或者重绘,我们可以更好使用它们

例如,多次修改一个把元素布局的时候,我们很可能会如下操作

// 获取DOM元素
const div = document.getElementById('div')
// 直接循环遍历应用到DOM上
for(let i=0;i<10;i++) {
    div.style.top  = div.offsetTop  + 100 + "rem";
    div.style.left = div.offsetLeft + 100 + "rem";
}

每次循环都需要获取多次offset属性,所以我们可以以变量的形式参起来,减少每次的计算获取

// 缓存offsetLeft与offsetTop的值
const div = document.getElementById('div')
let offLeft = div.offsetLeft, offTop = div.offsetTop
// 进行计算
for(let i=0;i<10;i++) {
  offLeft += 10
  offTop  += 10
}
// 将计算结果应用到DOM上
div.style.left = offLeft + "rem"
div.style.top = offTop  + "rem"

⑩使用类名去合并样式

<style>
    .basic_style {
        width: 100px;
        height: 200px;
        border: 10px solid red;
        color: red;
    }
</style>
<script>
    const container = document.getElementById('container')
    container.classList.add('basic_style')
</script>

二、如何实现单行或多行文本溢出的省略样式?

1.单行文本溢出省略

概:即的那行文本超出限制则以省略号形式呈现

我们可以使用一下css属性来进行单行文本超出省略号显示

  • text-overflow:规定当文本溢出时,显示省略符号来代表被修剪的文本

    text-overflow属性值有如下:

    • clip:当对象内文本溢出部分裁切掉
    • ellipsis:当对象内文本溢出时显示省略标记(…)

    text-overflow只有在设置了overflow:hiddenwhite-space:nowrap才能够生效的

  • white-space:设置文字在一行显示,不能换行

  • overflow:文字长度超出限定宽度,则隐藏超出的内容

    overflow设为hidden,普通情况用在块级元素的外层隐藏内部溢出元素

例如:

<style>
    p{
        overflow: hidden;
        line-height: 40px;
        width:400px;
        height:40px;
        border:1px solid green;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
</style>
<p 山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼山鱼的活动社区</p >

2.多行文本溢出省略多行文本溢出省略

多行文本溢出两种情况:①基于高度截断②基于行数截断

①基于高度截断

使用为元素+定位的方法实现

  • position: relative:为伪元素绝对定位
  • overflow: hidden:文本溢出限定的宽度就隐藏内容
  • position: absolute:给省略号绝对定位
  • line-height: 20px:结合元素高度,高度固定的情况下,设定行高, 控制显示行数
  • height: 40px:设定当前元素高度
  • ::after {xxx} :设置省略号样式

代码如下所示:

<style>
    .shanyu {
        position: relative;
        line-height: 20px;
        height: 40px;
        overflow: hidden;
    }
    .shanyu::after {
        position: absolute;
        content: "......";
        bottom: 0;
        right: 0;
        padding: 0 20px 0 10px;
    }
</style>

<body>
    <div class='shanyu'>--------超级超级长的文本——————</div>
</body>

注:该方法就是使用伪元素的绝对定位遮住多出来的文字,然后通过overflow:hidden隐藏超出的文本。若文本存在英文,可设置word-break: break-all使得单词可拆分

②基于行数截断

使用以下属性实现

①-webkit-line-clamp:2用来限制在一个块元素显示的文本的行数

  • display: -webkit-box:和①结合使用,将对象作为弹性伸缩盒子模型显示
  • -webkit-box-orient: vertical:和①结合使用 ,设置伸缩盒对象的子元素的排列方式
  • overflow: hidden:文本溢出限定的宽度就隐藏内容
  • text-overflow: ellipsis:多行文本下,用省略号...隐藏溢出范围的文本
<style>
    p {
        width: 400px;
        border-radius: 1px solid red;
        -webkit-line-clamp: 2;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        overflow: hidden;
        text-overflow: ellipsis;
    }
</style>
<p>
	小解的活动社区小解的活动社区小解的活动社区小解的活动社区小解的活动社区小解的活动社区
	小解的活动社区小解的活动社区小解的活动社区小解的活动社区小解的活动社区小解的活动社区
</p >

可以看到,上述使用了webkitCSS属性扩展,所以兼容浏览器范围是PC端的webkit内核的浏览器,由于移动端大多数是使用webkit,所以移动端常用该形式。如果文本为一段很长的英文或者数字,则需要添加word-wrap: break-word属性,还能通过使用javascript实现配合css

CSS部分

p {
    position: relative;
    width: 400px;
    line-height: 20px;
    overflow: hidden;

}
.pEnd:after{
    content: "..."; 
    position: absolute; 
    bottom: 0; 
    right: 0; 
    padding-left: 40px;
    background: -webkit-linear-gradient(left, transparent, #fff 55%);
    background: -moz-linear-gradient(left, transparent, #fff 55%);
    background: -o-linear-gradient(left, transparent, #fff 55%);
    background: linear-gradient(to right, transparent, #fff 55%);
}

JS部分

$(function(){
 //获取文本的行高,并获取文本的高度,假设我们规定的行数是五行,那么对超过行数的部分进行限制高度,并加上省略号
   $('p').each(function(i, obj){
       // 获取行高
        var lineHeight = parseInt($(this).css("line-height"));
       // 获取文本高度
        var height = parseInt($(this).height());
       判断文本的高度比上行高是否大于3
        if((height / lineHeight) >3 ){
           //  如果超过了3行则添加上面css里面所定义的类名且设置高度为60px
            $(this).addClass("pEnd")
            $(this).css("height","60px");
        }else{
           // 否则的话移除类名
            $(this).removeClass("pEnd");
        }
    })
})

三、你是如何理解CSS预编语言

1.CSS是什么

Css 作为一门标记性语言,语法相对简单,对使用者的要求较低,但同时也带来一些问题

如:逻辑性不强,不宜与维护等,所以就出现了预处理语言

2.CSS的预处理语言

扩充了 Css 语言,增加了诸如变量、混合、函数等功能,解决了CSS的逻辑性不强,不易维护等不足,他们通过自己的规则,最终将预处理语言编译为CSS

3.你了解有哪些预处理

三个常用的预编处理

  • sass
  • less
  • stylus

①sass

2007 年诞生,最早也是最成熟的 Css预处理器,拥有 Ruby 社区的支持和 Compass 这一最强大的 Css框架,目前受 LESS 影响,已经进化到了全面兼容 CssScss。文件后缀名为.sassscss,可以严格按照 sass 的缩进方式省去大括号和分号

②less

2009年出现,受SASS的影响较大,但又使用 Css 的语法,让大部分开发者和设计师更容易上手,在 Ruby社区之外支持者远超过 SASS

其缺点是比起 SASS来,可编程功能不够,不过优点是简单和兼容 Css,反过来也影响了 SASS演变到了Scss 的时代

③stylus

Stylus是一个Css的预处理框架,2010 年产生,来自 Node.js社区,主要用来给 Node 项目进行 Css 预处理支持

所以Stylus 是一种新型语言,可以创建健壮的、动态的、富有表现力的Css。比较年轻,其本质上做的事情与SASS/LESS等类似

4.他们的区别

常用特性有:

  • 变量(variables)
  • 作用域(scope)
  • 代码混合( mixins)
  • 嵌套(nested rules)
  • 代码模块化(Modules)

因此,下面就展开这些方面的区别

5.基本使用

/*stylus*/
.box
  display: block
/*sass*/
.box
  display: block
/*less和scss*/
.box {
  display: block;
}

6.嵌套使用

三者的嵌套语法都是一致的,甚至连引用父级选择器的标记 & 也相同区别只是 Sass 和 Stylus 可以用没有大括号的方式书写less

.a {
  &.b {
    color: red;
  }
}

7.变量使用

less

声明的变量必须以@开头,后面紧跟变量名和变量值,而且变量名和变量值需要使用冒号:分隔开

@red: #c00;

strong {
  color: @red;
}

sass

声明的变量跟less十分的相似,只是变量名前面使用@开头

$red: #c00;

strong {
  color: $red;
}

stylus

red = #FFFFFF

strong
  color: red

8.作用域

Css 预编译器把变量赋予作用域,也就是存在生命周期。就像 js一样,它会先从局部作用域查找变量,依次向上级作用域查找sass中不存在全局变量,所以,在sass中最好不要定义相同的变量名

$color: black;
.scoped {
  $bg: blue;
  $color: white;
  color: $color;
  background-color:$bg;
}
.unscoped {
  color:$color;
} 

lessstylus的作用域跟javascript十分的相似,首先会查找局部定义的变量,如果没有找到,会像冒泡一样,一级一级往下查找,直到最外层为止

@color: black;
.scoped {
  @bg: blue;
  @color: white;
  color: @color;
  background-color:@bg;
}
.unscoped {
  color:@color;
} 

9.预处理器的混入mixin

混入(mixin)应该说是预处理器最精髓的功能之一了,简单点来说,Mixins可以将一部分样式抽出,作为单独定义的模块,被很多选择器重复使用

可以在Mixins中定义变量或者默认参数

less中,混合的用法是指将定义好的ClassA中引入另一个已经定义的Class,也能使用够传递参数,参数变量为@声明

.alert {
  font-weight: 700;
}

.highlight(@color: red) {
  font-size: 1.2em;
  color: @color;
}

.heads-up {
  .alert;
  .highlight(red);
}

Sass声明mixins时需要使用@mixinn,后面紧跟mixin的名,也可以设置参数,参数名为变量$声明的形式

@mixin large-text {
  font: {
    family: Arial;
    size: 20px;
    weight: bold;
  }
  color: #ff0000;
}

.page-title {
  @include large-text;
  padding: 4px;
  margin-top: 10px;
}

stylus中的混合和前两款Css预处理器语言的混合有些许不同,他可以不使用任何符号,就是直接声明Mixins名,然后在定义参数和默认值之间用等号=来连接

error(borderWidth= 2px) {
  border: borderWidth solid #F00;
  color: #F00;
}
.generic-error {
  padding: 20px;
  margin: 4px;
  error(); /* 调用error mixins */
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  error(5px); /* 调用error mixins,并将参数$borderWidth的值指定为5px */
} 

10.代码模块化

模块化就是将Css代码分成一个个模块

scsslessstylus三者的使用方法都如下所示

@import './common';
@import './github-markdown';
@import './mixin';
@import './variables';

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/711312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vulnhub: EvilBox:One靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.130 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.130 secret目录爆破 feroxbuster -k -d 1 --url http://192.168.111.130/secret/ -w /opt/zidian/SecLists-2022.2/Disco…

【深度学习推荐系统 工程篇】二、从TF-Serving看生产环境的模型推理服务

前言 模型训练完成后&#xff0c;到在线部署是其所必须要做的一步&#xff0c;伴随模型结构复杂/算力增加&#xff0c;打造低延时/低资源占用的模型预测服务是模型上线的关键&#xff1b; tensorflow 很早就开源了tf-serving&#xff08;代码连接&#xff1a;https://github.…

Pygame中获取键盘按键的方法

1 事件与队列 在Pygame中&#xff0c;将用户对游戏的操作叫做“事件”。键盘按键是一种事件&#xff0c;鼠标点击和游戏手柄的输入也是一种事件。在Pygame的子模块locals中&#xff0c;对这些事件进行了定义。当用户通过键盘、鼠标或者游戏手柄对游戏进行操作后&#xff0c;产…

Bootstrap 代码

文章目录 Bootstrap 代码更多实例实例1实例2实例3&#xff0c;4实例5实例6 Bootstrap 代码 Bootstrap 允许您以两种方式显示代码&#xff1a; 第一种是 <code> 标签。如果您想要内联显示代码&#xff0c;那么您应该使用 <code> 标签。第二种是 <pre> 标签。…

mysql 创建用户(修改用户访问数据库权限,被外界IP访问权限)

我们执行,下面代码&#xff1a; select user,host from mysql.user;生成表: 这里面存放我们所有的用户&#xff0c;user 表示用户名, host表示 能被访问的IP范围。 1.修改用户能被访问的范围 # "%" 表示,能被所有IP访问。 update mysql.user set host "%&q…

力扣 538. 把二叉搜索树转换为累加树 1038. 从二叉搜索树到更大和树

题目来源&#xff1a; 538&#xff1a;https://leetcode.cn/problems/convert-bst-to-greater-tree/description/ 1038&#xff1a; https://leetcode.cn/problems/binary-search-tree-to-greater-sum-tree/description/ C题解1&#xff1a;递归法。二叉搜索树由大到小&#…

CST仿真半波偶极子天线学习笔记

CST仿真半波偶极子天线 文章目录 CST仿真半波偶极子天线1. 新建工程模板2.建模3. 激励方式设置4. 求解器设置5. 仿真分析6. 数据后处理 设计要求&#xff1a; 谐振频率为3.48GHz&#xff0c;基板采用Rogers RT5880板材&#xff0c;介电常数2.2&#xff0c;损耗角正切0.0009&…

Git学习笔记(三)

导航小助手 五、远程操作 5.1 理解分布式版本控制系统 5.2 远程仓库 5.2.1 新建远程仓库 5.2.2 克隆远程仓库 5.2.3 向远程仓库推送 5.2.4 拉取远程仓库 五、远程操作 5.1 理解分布式版本控制系统 前面博客所介绍的 关于 Git 的内容&#xff08;比如说&#xff1a;工作…

输入和输出处理

目录 1.File类 2.流 2.1.InputStream 2.2.OutputStream 总结 内容仅供学习交流&#xff0c;如有问题请留言或私信&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 有空您就点点赞 1.File类 文件&#xff1a;相关记录或存放在一起的数据的集合 Java程序如…

高考考了657分想重新复读一年,又害怕白费一年

高考考了657分想重新复读一年&#xff0c;又害怕白费一年。 如果你想重新复读一年&#xff0c;可能需要考虑到以下几点&#xff1a; 复读的代价&#xff1a;复读需要花费一年的时间和精力&#xff0c;而且这个过程中你可能会面临很多挑战和压力&#xff0c;包括学习上的、生活上…

多模态之论文笔记BEiT, BEiT V2, BEiT V3

文章目录 OverviewBEiT1.0. Summary1.1. BEiT VS BERT2.1. Two Views: visual tokens2.1. Two Views: image patches3. Results BEiT V21.0. Summary1.1. Motivation2.1. Methods -- VQ-KD2.2. Methods -- patch aggregation3.1. Results -- image classification & semant…

ChatGPT Plugins内幕、源码及案例实战(二)

第6章 ChatGPT Plugins内幕、源码及案例实战 检索插件的API需要以下环境变量才能工作,如表6-2所示。 ChatGPT检索插件示例中,“.well-known”目录里面的ai-plugin.json是一个插件的说明文档,插件名为Retrieval Plugin,用于搜索用户的文档(如文件、电子邮件等),该插件…

HDLbits--Exams/review2015 fsm

示例&#xff1a; 题目的主要意思是&#xff1a;复位之后寻找1101序列&#xff0c;找到之后shift ena在四个周期内为1&#xff0c;此后输出counting&#xff0c;如果done-counting0&#xff0c;则counting一直为1&#xff0c;直到done-counting1&#xff0c;counting才为0&…

Redis高可用——持久化

Redis高可用——持久化 一、Redis 高可用的相关知识1、什么是高可用2、Redis的高可用技术3、持久化的功能4 redis持久化的方式 二、RDB持久化1、RDB持久化的触发方式①.手动触发②.自动触发③.其他自动触发机制 2、bgsave执行流程3、启动时加载 三、AOF持久化1.开启AOF2.执行流…

RSUYZM9智能路侧终端使用说明书

1 产品概览 本说明 书适用于 RSUYZM8型及 RSUYZM9型智能路侧终端 产品 。智能路 侧终端 作为智能 车路协同系统 路侧的基础 设备&#xff0c; 是车载设备和路口 所有 设备的 汇 聚点&#xff0c;路侧设备和车载之间 通过 LTE-V进行 信息交互 。同时 &#xff0c;智能路侧终 端还…

【JavaWeb】JavaScript的基础语法

目录 1、JS简介 1.1、JavaScript的运行过程 1.2、了解浏览器的开发人员工具 2、JavaScript的书写形式 2.1、行内式 2.2、内嵌式 2.3、外部式 3、JavaScript的输入输出函数 4、JavaScript语法 4.1、变量声明 4.1.1、动态类型 4.2、基本数据类型 4.2.1、数字类型 4.…

青岛大学_王卓老师【数据结构与算法】Week03_13_线性表的链式表示和实现13_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c;另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础–…

C++数据结构笔记(6)栈的链式存储结构

对于栈的链式存储结构&#xff0c;实现原理本质上是受限的链表&#xff1b;此外与顺序存储不同的是&#xff0c;链式结构选用左边&#xff08;头结点&#xff09;作为栈的顶部&#xff0c;这样的好处是只要找到头结点即可实现插入元素等操作。 LinkStack.h头文件 #ifndef LIN…

CentOs7 64位 32位ISO镜像下载

链接: https://pan.baidu.com/s/1N181e6KFFFWPHhCTB7thMw 提取码: zht1

<Oracle>《(史上最完整)Linux 下安装Oracle数据库 - Oracle 19C By CentOS 8 》

《Linux 下安装Oracle数据库 - Oracle 19C By CentOS 8 》 1 说明1.1 前言1.2 资源下载 2 安装步骤2.1 上传安装包2.2 下载数据库预安装包2.3 安装数据库预安装包2.4 安装Oracle数据库2.4.1 第一次安装报错2.4.2 解决安装报错第一步&#xff1a;安装libnsl.so.1第二步&#xff…