Skip to content

Latest commit

 

History

History
692 lines (453 loc) · 22.5 KB

每日一题-CSS篇.md

File metadata and controls

692 lines (453 loc) · 22.5 KB

每日一题-CSS篇

CSS选择器优先级

  • !import
  • 内联 1000
  • ID 100
  • 类选择器/伪类选择器/属性选择器 10
  • 元素选择器/关系选择器/伪元素选择器 1
  • 通配符 *
  • 继承
  • 原始

盒模型及如何转换

box-sizing: content-box(W3C盒模型,又名标准盒模型):元素的宽高大小表现为内容的大小。

box-sizing: border-box(IE盒模型,又名怪异盒模型):元素的宽高表现为内容 + 内边距 + 边框的大小。背景会延伸到边框的外沿。

CSS3新特性

  • transition:过渡
  • transform: 旋转、缩放、移动或倾斜
  • animation: 动画
  • gradient: 渐变
  • box-shadow: 阴影
  • border-radius: 圆角
  • word-break: normal|break-all|keep-all; 文字换行(默认规则|单词也可以换行|只在半角空格或连字符换行)
  • text-overflow: 文字超出部分处理
  • text-shadow: 水平阴影,垂直阴影,模糊的距离,以及阴影的颜色。
  • box-sizing: content-box|border-box 盒模型
  • 媒体查询 @media screen and (max-width: 960px) {}还有打印print

文字单超出显示省略号

div {
	width: 200px;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

文字多行超出显示省略号

div {
	width: 200px;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
}

该方法适用于WebKit浏览器及移动端。

跨浏览器兼容方案:

p {
    position:relative;
    line-height:1.4em;
    /* 3 times the line-height to show 3 lines */
    height:4.2em;
    overflow:hidden;
}
p::after {
    content:"...";
    font-weight:bold;
    position:absolute;
    bottom:0;
    right:0;
    padding:0 20px 1px 45px;
}

页面变灰

body {
	filter: grayscale(100%); /* 百分比或者 0~1 */
}

CSS中可继承的属性

可继承的只有:颜色、文字、字体间距、行高对齐方式,列表样式。

所有元素可继承:visibility和cursor。

内联元素可继承:letter-spacing、word-spacing、white-space、line-height、color、font、font-family、font-size、font-style、font-variant、font-weight、text-decoration、text-transform、direction。

块状:text-indent和text-align。

列表元素可继承:list-style、list-style-type、list-style-position、list-style-image。

如何画扇形?

.sector {
  width: 0;
  height: 0;
  border: 100px solid red;
  border-color: red transparent transparent transparent;
  border-radius: 50%;
}
/*或者*/
.sector {
  width: 100px;
  height: 100px;
  border: 100px solid transparent;
  border-top-color: red;
  box-sizing: border-box; /* 这步很重要 */
  border-radius: 50%;
}

如何画三角形?

.triangle {
  width: 0;
  height: 0;
  border: 100px solid red;
  border-color: red transparent transparent transparent;
}
/*或者*/
.triangle {
  width: 100px;
  height: 100px;
  border: 100px solid transparent;
  border-top-color: red;
  box-sizing: border-box;
}

圆?半圆?椭圆?

div {
  width: 100px;
  height: 100px;
  background-color: red;
  margin-top: 20px;
}
.box1 { /* 圆 */
  /* border-radius: 50%; */
  border-radius: 50px;
}
.box2 { /* 半圆 */
  height: 50px;
  border-radius: 50px 50px 0 0;
}
.box3 { /* 椭圆 */
  height: 50px;
  border-radius: 50px/25px; /* x轴/y轴 */
}

用纯 CSS 判断鼠标进入的方向

题目来源:《陈大鱼头-面试官:你可以用纯 CSS 判断鼠标进入的方向吗?》

效果:codepen

什么是BFC

BFC全称 Block Formatting Context 即块级格式上下文,简单的说,BFC是页面上的一个隔离的独立容器,不受外界干扰或干扰外界

如何触发BFC

  • float不为 none
  • overflow的值不为 visible
  • position 为 absolute 或 fixed
  • display的值为 inline-block 或 table-cell 或 table-caption 或 grid

BFC的渲染规则是什么

  • BFC是页面上的一个隔离的独立容器,不受外界干扰或干扰外界
  • 计算BFC的高度时,浮动子元素也参与计算(即内部有浮动元素时也不会发生高度塌陷)
  • BFC的区域不会与float的元素区域重叠
  • BFC内部的元素会在垂直方向上放置
  • BFC内部两个相邻元素的margin会发生重叠

BFC的应用场景

  • 清除浮动:BFC内部的浮动元素会参与高度计算,因此可用于清除浮动,防止高度塌陷
  • 避免某元素被浮动元素覆盖:BFC的区域不会与浮动元素的区域重叠
  • 阻止外边距重叠:属于同一个BFC的两个相邻Box的margin会发生折叠,不同BFC不会发生折叠

可以参考这里:

作者:写代码像蔡徐抻 链接:https://juejin.im/post/5e8b261ae51d4546c0382ab4

float:left对比position:absolute

相同点:

  • 脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当做脱离文档流的元素不存在而进行定位。
  • 包裹性:也就是都会让元素inline-block化。等同于没有高度与宽度的inline-block元素。
    • 对于块状元素默认的宽度为100%,若设置为了绝对定位则宽度由内容决定
    • 对于内联元素原本设置width属性无效,若设置了浮动则可以设置width
  • 破坏性:都会导致父级高度塌陷。但若是设置了绝对定位的话,其父级即使设置为float:left;也还是不能解决高度塌陷的问题。

不同点:

  • 虽然它们都会脱离文档流,但是使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本依然会为这个元素让出位置,环绕在周围。而对于使用position:absolute脱离文档流的元素,其他盒子与其他盒子内的文本都会无视它。

float:left对比inline-block

  • 文档流:浮动会脱离文档流,且使得被覆盖的元素的文字内容会环绕在周围;而inline-block不会脱离文档流也就不会覆盖其它元素。浮动也会引发父级高度塌陷问题。
  • 水平位置:不能给有浮动元素的父级设置text-align:center使得子集浮动元素居中,而inline-block却可以。
  • 垂直对齐inline-block元素沿着默认的基线对齐(baseline),若是两个元素的font-size不同则可能会看到一高一低,你可以通过设置vertical-align: top或者bottom;来使得它们基于顶线或者底线对齐(注意这个是设置到元素本身而不是设置到它们的父级)。而浮动元素紧贴顶部,不会有这个问题。
  • 空白inline-block包含html空白节点。如果你的html中一系列元素每个元素之间都换行了,当你对这些元素设置inline-block时,这些元素之间就会出现空白。而浮动元素会忽略空白节点,互相紧贴。

针对第三点,垂直对齐可以看下面👇这个案例:

默认情况下:

css代码为:

.sub {
  background: hotpink;
  display: inline-block;
}

设置了vertial-align: top;后:

css代码为:

.sub {
  background: hotpink;
  display: inline-block;
  vertical-align: top;
}

如何解决inline-block空白问题?

原本的代码为:

<style>
.sub {
  background: hotpink;
  display: inline-block;
}
</style>
<body>
  <div class="super">
    <div class="sub">
      孩子
    </div>
    <div class="sub">
      孩子
    </div>
    <div class="sub">
      孩子
    </div>
  </div>
</body>

效果为:

图片1

可以看到每个孩子之间都会有一个空白。inline-block元素间有空格或是换行,因此产生了间隙。

解决办法:

  • (1) 删除html中的空白:不要让元素之间换行:

    <div class="super">
      <div class="sub">
        孩子
      </div><div class="sub">
        孩子
      </div><div class="sub">
        孩子
      </div>
    </div>
  • (2) 设置负的边距:你可以用负边距来补齐空白。但你需要调整font-size,因为空白的宽度与这个属性有关系。例如下面这个例子:

    .sub {
      background: hotpink;
      display: inline-block;
      font-size:16px;
      margin-left: -0.4em;
    }
  • (3) 给父级设置font-size: 0:不管空白多大,由于空白跟font-size的关系,设置这个属性即可把空白的宽度设置为0。但是如果你的子级有字的话,也得单独给子级设置字体大小。

  • (4) 注释

    <div class="super">
      <div class="sub">
        孩子
      </div><!--
      --><div class="sub sub2">
        孩子
      </div><!--
      --><div class="sub">
        孩子
      </div>
    </div>

脱离文档流是不是指该元素从DOM树中脱离?

并不会,DOM树是HTML页面的层级结构,指的是元素与元素之间的关系,例如包裹我的是我的父级,与我并列的是我的兄弟级,类似这样的关系称之为层级结构。

而文档流则类似于排队,我本应该在队伍中的,然而我脱离了队伍,但是我与我的父亲,兄弟,儿子的关系还在。

relative的定位规则

  • 相对于该元素在文档中的初始位置进行定位。通过 “left”、”top”、”right” 以及 “bottom” 属性来设置此元素相对于自身位置的偏移。
  • 如果他原来在常规流的默认位置改变了,那他也会跟着变位置,永远围着整个body自己原来的那一小块老地方转。所以说相对定位没有脱离文档流。

脱离文档流是会呈现什么样的效果呢?

脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当做脱离文档流的元素不存在而进行定位。

而在CSS中,使用float和设置position:absolute都会使得元素脱离文档流。只不过它两的区别是:

使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本依然会为这个元素让出位置,环绕在周围。而对于使用position:absolute脱离文档流的元素,其他盒子与其他盒子内的文本都会无视它。

常规流(文档流)是个怎样的排列关系

将窗体自上而下分成一行一行,并在每行中按从左至右的挨次排放元素。

inline-block的使用场景

  1. 要设置某些子元素在一行或者多行内显示,尤其是排列方向一致的情况下,应尽量用inline-block
  2. 希望若干个元素平行排列,且在父元素中居中排列,此时可以用inline-block,且给父元素设text-align: center
  3. inline-block可以用一排a {display: inline-block}实现横向导航栏,无论是居左的导航栏还是居右的都适用。

对于第一种和第三种情况虽然都可以使用float来实现,不过inline-block会比它好一些,原因如下:

  • 浮动会脱离文档流,导致父元素高度塌陷

设置了绝对定位的元素相对于谁进行定位?

绝对定位元素相对的元素是它最近的一个祖先,该祖先满足:position的值必须是:relative、absolute、fixed,若没有这样的祖先则相对于body进行定位。偏移值由其top、bottom、left、right值确定。

(绝对定位常见误区:我们之前总是听到的答案是绝对定位的盒子是相对于离它最近的一个设置为relative的盒子进行定位的,其实这是不对的,应该说是相对于离它最近的一个已定位的盒子进行定位;只不过我们实际开发中总是用relative配合absolute来用,所以就让我们潜意识的认为是前一种答案)

绝对定位的元素决定其定位的父级如果设置了padding或者border它是怎样定位的?

如果祖先元素是块级元素:

  • border会影响子级的定位
  • padding不会影响

如下图:

这里的代码是:

<style>
  body, html {
    margin: 0;
    height: 100%;
  }
  .super {
    text-align: right;
    position: relative;
    width: 200px;
    height: 200px;
    background-color: red;
    padding: 50px;
    border: 50px solid yellowgreen;
  }
  .sub {
    position: absolute;
    background-color: royalblue;
    width: 100px;
    height: 100px;
    top: 10px;
    left: 10px;
  }
</style>
<body>
  <div class="super">
    我是父级
    <div class="sub">
      我是子级
    </div>
  </div>
</body>

绝对定位和非绝对定位时元素的宽高百分比是如何计算的?

  • 绝对定位的元素其宽高的百分比是相对于父级的padding-box计算的
  • 非绝对定位的元素则是相对于父级的content-box计算

如下两个案例:

案例一:子级为绝对定位元素:

<style>
  body, html {
    margin: 0;
    height: 100%;
  }
  .super {
    text-align: right;
    position: relative;
    width: 200px;
    height: 200px;
    background-color: red;
    padding: 50px;
    border: 50px solid yellowgreen;
  }
  .sub {
    position: absolute;
    background-color: royalblue;
    width: 50%;
    height: 50%;
  }
</style>
<body>
  <div class="super">
    我是父级
    <div class="sub">
      我是子级
    </div>
  </div>
</body>

效果:子级宽高为:(父级的width(200) + 父级的左右padding(100)) / 2 = 150px

案例二:子级为绝对定位元素

效果:子级宽高为:父级的width(200) / 2 = 100px

margin: auto为什么能实现垂直居中?

普通的流体元素它的margin: auto的填充规则:

  • 若一侧是定值,一侧是auto,则auto为剩余空间的大小
  • 若两侧都为auto,则会平分剩余空间

若是我们给普通的块状水平元素设置了position: absolute之后,且其对立方向属性同时有具体的数值时,例如设置了top: 0; bottom: 0;,流体特性就发生了,此时它就会按普通流体元素的margin: auto填充规则来进行填充。所以margin: auto可以实现垂直居中。

line-height为什么可以垂直居中?

可以实现垂直居中的原因是CSS的行距上下等分机制,实际上line-height等于height也只是近似垂直居中,文字会向下偏移1px-2px的距离,但并不容易察觉。

position: fixed什么时候会失效?

我们知道,设置了position: fixed固定定位属性的元素会脱离文档流,达到“超然脱俗”的境界。 也就是说此时给这种元素设置top, left, right, bottom等属性是根据浏览器窗口定位的,与其上级元素的位置无关。

但是有一种情况例外:

若是设置了position: fixed属性的元素,它的祖先元素设置了transform属性则会导致固定定位属性失效。 只要你的transform设置的不是none,都会影响到position: fixed,因为此时就会相对于祖先元素指定坐标,而不是浏览器窗口。

注意,这个特性表现,目前只在Chrome浏览器/FireFox浏览器下有。IE浏览器,包括IE11, fixed还是fixed的表现。

(具体可以看我这里的案例:【问】position: fixed什么时候会失效?)

说一下回流和重绘

回流

触发条件:

当我们对 DOM 结构的修改引发 DOM 几何尺寸变化的时候,会发生回流的过程。

例如以下操作会触发回流:

  1. 一个 DOM 元素的几何属性变化,常见的几何属性有widthheightpaddingmarginlefttopborder 等等, 这个很好理解。

  2. 使 DOM 节点发生增减或者移动

  3. 读写 offset族、scroll族和client族属性的时候,浏览器为了获取这些值,需要进行回流操作。

  4. 调用 window.getComputedStyle 方法。

回流过程:由于DOM的结构发生了改变,所以需要从生成DOM这一步开始,重新经过样式计算生成布局树建立图层树、再到生成绘制列表以及之后的显示器显示这整一个渲染过程走一遍,开销是非常大的。

重绘

触发条件:

当 DOM 的修改导致了样式的变化,并且没有影响几何属性的时候,会导致重绘(repaint)。

重绘过程:由于没有导致 DOM 几何属性的变化,因此元素的位置信息不需要更新,所以当发生重绘的时候,会跳过生存布局树建立图层树的阶段,直接到生成绘制列表,然后继续进行分块、生成位图等后面一系列操作。

如何避免触发回流和重绘

  1. 避免频繁使用 style,而是采用修改class的方式。
  2. 将动画效果应用到position属性为absolutefixed的元素上。
  3. 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘
  4. 使用createDocumentFragment进行批量的 DOM 操作。
  5. 对于 resize、scroll 等进行防抖/节流处理。
  6. 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
  7. 利用 CSS3 的transformopacityfilter这些属性可以实现合成的效果,也就是CPU加速。

参考来源:https://juejin.im/post/5df5bcea6fb9a016091def69#heading-57

GPU加速的原因

在合成的情况下,会直接跳过布局和绘制流程,直接进入非主线程处理的部分,即直接交给合成线程处理。交给它处理有两大好处:

  1. 能够充分发挥GPU的优势。合成线程生成位图的过程中会调用线程池,并在其中使用GPU进行加速生成,而GPU 是擅长处理位图数据的。
  2. 没有占用主线程的资源,即使主线程卡住了,效果依然能够流畅地展示。

参考来源:https://juejin.im/post/5df5bcea6fb9a016091def69#heading-57

说说will-change

will-changeCSS3新增的标准属性,它的作用很单纯,就是"增强页面渲染性能",当我们在通过某些行为触发页面进行大面积绘制的时候,浏览器往往是没有准备,只能被动的使用CUP去计算和重绘,由于事先没有准备,对于一些复杂的渲染可能会出现掉帧、卡顿等情况。而will-change则是在真正的行为触发之前告诉浏览器可能要进行重绘了,相当于浏览器把CUP拉上了,能从容的面对接下来的变形。

常用的语法主要有:

  • whil-change: scroll-position; 即将开始滚动
  • will-change: contents; 内容要动画或者变化了
  • will-transform; transform相关的属性要变化了(常用)

注意:

  • will-change虽然可以开启加速,但是一定要适度使用
  • 开启加速的代价为手机的耗电量会增加
  • 使用时遵循最小化影响原则,可以对伪元素开启加速,独立渲染
  • 可以写在伪类中,例如hover中,这样移出元素的时候就会自动removewill-change
  • 如果使用JS添加了will-change,注意要及时remove掉,方式就是style.willChange = 'auto'

z-index和background的覆盖关系

移动端中css你是使用什么单位

比较常用的

  • em:定义字体大小时以父级的字体大小为基准;定义长度单位时以当前字体大小为基准。例父级font-size: 14px,则子级font-size: 1em;font-size: 14px;;若定义长度时,子级的字体大小如果为14px,则子级width: 2em;width: 24px
  • rem:以根元素的字体大小为基准。例如htmlfont-size: 14px,则子级1rem = 14px
  • %:以父级的宽度为基准。例父级width: 200px,则子级width: 50%;height:50%;width: 100px;height: 100px;
  • vw和vh:基于视口的宽度和高度(视口不包括浏览器的地址栏工具栏和状态栏)。例如视口宽度为1000px,则60vw = 600px;
  • vmin和vmaxvmin为当前vwvh中较小的一个值;vmax为较大的一个值。例如视口宽度375px,视口高度812px,则100vmin = 375px;100vmax = 812px;

不常用的:

  • ex和chex以字符"x"的高度为基准;例如1ex表示和字符"x"一样长。ch以数字"0"的宽度为基准;例如2ch表示和2个数字"0"一样长。

移动端布局总结

  1. 移动端布局的方式主要使用rem和flex,可以结合各自的优点,比如flex布局很灵活,但是字体的大小不好控制,我们可以使用rem和媒体查询控制字体的大小,媒体查询视口的大小,然后不同的上视口大小下设置设置html的font-size。
  2. 可单独制作移动端页面也可响应式pc端移动端共用一个页面。没有好坏,视情况而定,因势利导

(总结来源:玲珑)

rem和em的区别

em:

定义字体大小时以父级的字体大小为基准;定义长度单位时以当前字体大小为基准。例父级font-size: 14px,则子级font-size: 1em;font-size: 14px;;若定义长度时,子级的字体大小如果为14px,则子级width: 2em;width: 24px

rem:

以根元素的字体大小为基准。例如htmlfont-size: 14px,则子级1rem = 14px

在移动端中怎样初始化根元素的字体大小

一个简易版的初始化根元素字体大小。

页面开头处引入下面这段代码,用于动态计算font-size

(假设你需要的1rem = 20px)

(function () {
  var html = document.documentElement;
  function onWindowResize() {
    html.style.fontSize = html.getBoundingClientRect().width / 20 + 'px';
  }
  window.addEventListener('resize', onWindowResize);
  onWindowResize();
})();
  • document.documentElement:获取document的根元素
  • html.getBoundingClientRect().width:获取html的宽度(窗口的宽度)
  • 监听windowresize事件

一般还需要配合一个meta头:

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-sacle=1.0, maximum-scale=1.0, user-scalable=no" />

移动端中不同手机html默认的字体大小都是一样的吗

如果没有人为取改变根元素字体大小的话,默认是1rem = 16px;根元素默认的字体大小是16px