CSS之面试题(二)

一、计算属性calc()的使用

1. 定义及用法

calc() 函数用于动态计算长度值。 语法:calc(expression)
.ele{
    width:calc(100% - 20px);
}

2. 注意事项

  • 需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px)。
  • 任何长度值都可以使用calc()函数进行计算。
  • calc()函数支持 "+", "-", "*", "/" 运算。
  • calc()函数使用标准的数学运算优先级规则。

二、--CSS变量

1. 概念

var() 函数用于插入 CSS 变量的值。

CSS 变量可以访问 DOM,这意味着您可以创建具有局部或全局范围的变量,使用 JavaScript 来修改变量,以及基于媒体查询来修改变量。

使用 CSS 变量的一种好方法涉及设计的颜色。您可以将它们放在变量中,而不必一遍又一遍地复制和粘贴相同的颜色。

2. 语法

var() 函数的语法如下:var(name, value)

  • name必需,变量名(以两条破折号开头)。
  • value可选。回退值(在未找到变量时使用)。
  • -- 前缀通常被用在类中,是CSS中对变量声明的前缀。
:root {
  --blue: #1e90ff;
  --white: #ffffff;
}
.container {
  color: var(--blue);
  background-color: var(--white);
  padding: 15px;
}

三、伪类和伪元素

使用伪元素的时候,总是感觉和伪类很相似,但又不能详细的说出两者的区别和联系,那么两者到底有什么区别和联系呢?

1.伪元素/伪对象

不存在在DOM文档中,是虚拟的元素,是创建新元素。代表某个元素的子元素,这个子元素虽然在逻辑上存在,但却并不实际存在于DOM树中。

伪元素选择符是指为一个HTML元素的各种状态和部分内容定义样式的一种方式。

☘️ 1. 前端CSS中的伪元素选择符有以下几种:
  • ::after:在元素的最后面添加一个伪元素,通常用于添加内容。
  • ::before:在元素的最前面添加一个伪元素,通常用于添加内容。
  • ::first-letter:用于选中元素中的第一个字母。
  • ::first-line:用于选中元素中的第一行文字。
  • ::selection:用于选中元素中被用户选中的文本部分。
  • ::placeholder 用于设置输入框或文本域中placeholder属性设置的文字的样式。
☘️ 2. 伪元素使用时的注意事项
  • 伪元素如果没有设置content属性,那么伪元素是无用的(可以将伪元素的内容设置为空)
  • 插入的内容在页面的源码里是不可见的,只能在css里面可见。
  • 插入的伪元素默认情况是内联元素,因此,为了给插入元素赋予高度,外边距、填充等等,必须显式定义它是一个块级元素。
  • 典型的css继承规则适用于插入的伪元素,比如,插入的字体系列,然后伪元素会像其他元素一样继承这些字体系列,同样的,伪元素不会继承没有自然继承自父元素(如padding和margin)的样式。
  • 使用伪元素插入非文本内容。

2. 伪类

存在DOM文档中,逻辑上存在但在文档树中却无须标识的“幽灵”分类,用来表示元素的一种状态。

☘️ 1.动态伪类选择器
  • :link。元素被定义了超链接但并未被访问过
  • :visited。元素被定义了超链接并已被访问过
  • :active。元素被激活
  • :hover。鼠标悬停
  • :focus。元素获取焦点

a 标签的这四种伪类选择器的顺序为:​a:link ,a:visited,a:hover ,a:active​。必须严格按照此规则来设置属性,否则无效。

☘️ 2. UI 元素状态伪类选择器
  • :checked。选中的复选按钮或者单选按钮表单元素
  • :enabled。所有启用的表单元素
  • :disabled。所有禁用的表单元素
☘️ 3. 结构伪类选择器
  • first-child: 元素得是其父元素的第一个子元素才匹配
  • :last-child: 元素得是其父元素的最后一个子元素才匹配
  • :nth-child(n): 元素得是其父元素的第n个子元素才匹配
  • :nth-last-child(n): 元素得是其父元素的倒数第n个子元素才匹配
  • :only-child: 元素得是其父元素的唯一一个子元素才匹配
  • :first-of-type: 元素得是其父元素的第一个该类元素才匹配
  • :last-of-type: 元素得是其父元素的最后一个该类元素才匹配
  • :only-of-type: 元素得是其父元素的唯一一个该类元素才匹配
  • :nth-of-type(n): 元素得是其父元素的第n个该类元素才匹配
  • :nth-last-of-type(n): 元素得是其父元素的倒数第n个子元素才匹配
  • not: 排除元素 例: li:not(:first-child): 元素不是其父元素的第一个子元素的li元素被匹配

3. 伪类与伪元素的区别与联系

  • 在计算权重的时候 :伪类与类优先级相同 、伪元素与标签优先级相同
  • 伪类与伪元素都是用于向选择器加特殊效果
  • 伪类与伪元素的本质区别就是是否抽象创造了新元素
  • 伪类只要不是互斥可以叠加使用
  • 伪元素在一个选择器中只能出现一次,并且只能出现在末尾
  • 伪类与伪元素优先级分别与类、标签优先级相同

四、什么是响应式?

跟随用户页面设备尺寸的变化,页面实现自动的适配

比如你逛掘金的商城页面,缩放页面的时候发现1000-1160宽是一个适配,1160以外又是一个适配

实现方案

☘️ 1. 弹性布局:适合做某个容器内的响应式,比如ulli,但是不方便做整个页面的响应式

弹性容器默认就是让子元素在收缩放大时平均分配

☘️ 2. 百分比:常适用于页面外层大容器,同样不适合整个页面的响应式,一般适配都是pc端一个,平板一个,手机一个,百分比过于灵活不适合。

百分比继承父容器

☘️ 3. rem + 媒体查询 (可用于任何地方,一般pc端是rem + 媒体查询,移动端是rem + js)

rem是参照根字体大小,css有媒体查询的语法,写法参考如下,min-widthmax-width就是区间

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        li{
            list-style: none;
            width: 200px;
            height: 100px;
        }
        li:nth-child(1){
            background-color: antiquewhite;
        }
        li:nth-child(2){
            background-color: aqua;
        }
        li:nth-child(3){
            background-color: aquamarine;
        }
        li:nth-child(4){
            background-color: azure;
        }
        li:nth-child(5){
            background-color: black;
        }
        li:nth-child(6){
            background-color: blueviolet;
        }
    </style>

    <style>
        li {
            width: 10rem;
            /* pc端用媒体查询 移动端用js处理 */
        }
        @media screen and (min-width: 1000px) {
            /* 大于1000时 变化 pc端 */
            html{
                font-size: 30px;
            }
        }
        @media screen and (min-width: 800px) and (max-width: 1000px) {
            /* 平板端 */
            html{
                font-size: 20px;
            }
        }
        @media screen and (max-width: 500px) {
            /* 手机端 */
            html{
                font-size: 14px;
            }
        }
    </style>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>    
</body>
</html>
☘️ 4. 直接媒体查询,不如第三个方法,这个代码量会很大
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        li{
            list-style: none;
            width: 200px;
            height: 100px;
        }
        li:nth-child(1){
            background-color: antiquewhite;
        }
        li:nth-child(2){
            background-color: aqua;
        }
        li:nth-child(3){
            background-color: aquamarine;
        }
        li:nth-child(4){
            background-color: azure;
        }
        li:nth-child(5){
            background-color: black;
        }
        li:nth-child(6){
            background-color: blueviolet;
        }
    </style>
    <style>
        @media screen and (min-width: 1000px) {
            li{
                width: 300px;
            }
        }
        @media screen and (min-width: 800px) and (max-width: 1000px) {
            li{
                width: 200px;
            }
        }
        @media screen and (max-width: 500px) {
            li{
                width: 100px;
            }
        }
    </style>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>    
</body>
</html>
5. vw / vh :相对于window大小
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        li{
            list-style: none;
            width: 200px;
            height: 100px;
        }
        li:nth-child(1){
            background-color: antiquewhite;
        }
        li:nth-child(2){
            background-color: aqua;
        }
        li:nth-child(3){
            background-color: aquamarine;
        }
        li:nth-child(4){
            background-color: azure;
        }
        li:nth-child(5){
            background-color: black;
        }
        li:nth-child(6){
            background-color: blueviolet;
        }
    </style>
    <style>
        li{
            width: 20vw;
        }
    </style>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>    
</body>
</html>

五、什么是重绘与回流?

1. 概念:

当renderTree发生因为元素的规模尺寸,布局,隐藏等改变而需要重建时,这就称为回流。每个页面在第一次加载时至少要经历一次回流。

当renderTree中的一些元素需要更新属性,但这些属性只会影响元素外观,风格,而不影响布局时,比如background-Color则叫重绘。

回流必将引起重绘,重绘不一定引起回流。

2. 引起回流的方式?

  1. 页面初始化时,DOM载入后的第一次回流,将会遍历所有frame。最消耗性能的一次回流;
  2. 删除或者添加可见的元素时;
  3. 元素的位置发生改变时;
  4. 元素的大小改变时(例如改变了元素的内外边距,宽高,边框大小);
  5. 元素的内容发生变化(字体、文字、图片更换);
  6. 改变浏览器窗口尺寸(例如 resize 事件发生时);
  7. 样式改变(StyleChange)。整个frame树都应得到遍历;
  8. Css伪类激活
  9. 设置 style 属性的值,因为通过设置 style 属性改变节点样式的话,每一次设置都会触发一次回流;
  10. 查询某些属性或调用某些计算方法:offsetWidth、offsetHeight 等,会触发回流,为了 “即时性” 和 “准确性” ;
  11. Dom操作。

3. 引起重绘的方式?

  1. 可见性(visibility)和透明度(opacity)的改变;2.
  2. 颜色的改变;
  3. 背景的改变;
  4. 阴影、轮廓的改变;
  5. 文本方向(text-decoration)的改变等。

4. 如何减少回流、重绘?

可以看到每次DOM元素的样式操作都会引发重绘,如果涉及布局还会引发回流。避免大量页面回流的手段也有很多,其本质都是尽量减少引起回流和重绘的DOM操作:

  1. 避免逐项更改样式。最好一次性更改style属性,或者将样式列表定义为class并一次性更改class属性。
  2. 避免循环操作DOM。创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。 3.避免循环读取offsetLeft等属性。在循环之前把它们存起来。 4.绝对定位具有复杂动画的元素。绝对定位使它脱离文档流,否则会引起父元素及后续元素大量的回流。

六、padding和margin设值为百分比时的依据是什么?

当一个div padding和margin设置为百分比时,实际上是根据这个div的最近的块级父元素width的值为基准值计算的,这一点一定要注意

css

.child-box {
    width: 100px;
    height: 100px;
    border: 1px solid #ccc;
    padding: 5%;
    background-color: blue;
    margin: 5%;
}
.parent-box {
    width: 200px;
    height: 200px;
    border: 1px #f00 solid;
    background-color: #f00;
}

html

<div class="parent-box">
    <div class="child-box"> </div>
</div>

分析

蓝色盒子的宽=100 + 5% * 200 *2 = 120px,即蓝色盒子的宽 = 自身width + 自身padding的5% * 红色父盒子的宽 * 2
document.querySelector(".child-box").clientWidth  //120 

七、line-heigt和font-size的关系是什么?

line-heigt和font-size是经常用到的属性,但很少有人注意他们的关系

 
行高是指两行文字的baseline之间的垂直距离 ,行距是上行底线与下行顶线之间的垂直距离,字体大小是一行文字的顶线与其底线之间的垂直距离; 

由上图的关系可以看出:

行高(line-heigt) = 字体大小(font-size) + 行距(即2 * 半行距) 

八、line-height 如何继承?

⽗元素的 line-height 写了具体数值,⽐如 30px,则⼦元素 line-height 继承该值。

⽗元素的 line-height 写了⽐例,⽐如 1.5 或 2,则⼦元素 line-height 也是继承该⽐例。

⽗元素的 line-height 写了百分⽐,⽐如 200%,则⼦元素 line-height 继承的是⽗元素 font-size * 200% 计 算出来的值。

九、为什么要初始化 CSS 样式 ?

- 因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。

- 当然,初始化样式会对SEO有一定的影响,但鱼和熊掌不可兼得,但力求影响最小的情况下初始化。

最简单的初始化方法:*{padding:0;margin:0;}(强烈不建议)

淘宝的样式初始化代码:

body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend
,button,input,textarea,th,td{margin:0;padding:0;}
body,button,input,select,textarea{font:12px/1.5tahoma,arial,\5b8b\4f53;}
h1,h2,h3,h4,h5,h6{font-size:100%;}
address,cite,dfn,em,var{font-style:normal;}
code,kbd,pre,samp{font-family:couriernew,courier,monospace;}
small{font-size:12px;}
ul,ol{list-style:none;}
a{text-decoration:none;}
a:hover{text-decoration:underline;}
sup{vertical-align:text-top;}
sub{vertical-align:text-bottom;}
legend{color:#000;}
fieldset,img{border:0;}
button,input,select,textarea{font-size:100%;}
table{border-collapse:collapse;border-spacing:0;}

posted on 2024-08-29 16:32  梁飞宇  阅读(11)  评论(0)    收藏  举报