CSS

268 阅读9分钟

水平垂直居中

1. 绝对定位 + margin:auto

div{
      position: relative;
 }
 img{
      position: absolute;
      margin: auto;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
 }

2. position 元素已知宽度

父元素设置为:position: relative;

子元素设置为:position: absolute;

距上50%,据左50%,然后减去元素自身宽度的距离就可以实现

.box {
    position: relative;
}
.content {
    width: 100px;
    height: 100px;
    position: absolute;
    left: 50%;
    top: 50%;
    margin: -50px 0 0 -50px;
}

3. 绝对定位 + transform

.box {
    position: relative;
}
.content {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
}

4. flex布局

flex 布局详解

.box {
    display: flex;//flex布局
    justify-content: center;//使子项目水平居中
    align-items: center;//使子项目垂直居中
}

5. table-cell布局

table-cell相当于表格的td,td为行内元素,无法设置宽和高,所以嵌套一层,嵌套一层必须设置display: inline-block;td的背景覆盖了橘黄色,不推荐使用

<div class="box">
    <div class="content">
        <div class="inner">
        </div>
    </div>
</div>
.box {
    background-color: #FF8C00;//橘黄色
    display: table;
}
.content {
    background-color: #F00;//红色
    display: table-cell;
    vertical-align: middle;//使子元素垂直居中
    text-align: center;//使子元素水平居中
}
.inner {
    background-color: #000;//黑色
    display: inline-block;
}

6. Grid 方案

.box {
  display: grid;
}
.content {
  justify-self: center;
  align-self: center;
}
​
## 或者
.box {
  display: grid;
}
.content {
  margin: auto;
}

移动端1px

移动端1px

对于高清屏幕边框1px问题,有三个方面需要考虑

px,em,rem

px像素(Pixel),相对长度单位。像素px是相对于显示器屏幕分辨率而言的

em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸(16px)

rem(root em,根em)是CSS3新增的一个相对单位,相对于根元素html的字体尺寸。除了IE8及更早版本外,所有浏览器均已支持rem。为html标签的font-size设定一个数值,比如设为100px,当需要50px的时候,直接用0.5rem就可以了。

rgba()和opacity的透明效果有什么不同?

答案:

rgba()和opacity都能实现透明效果,但最大的不同是opacity作用于元素,以及元素内的所有内容的透明度,

而rgba()只作用于元素的颜色或其背景色。(设置rgba透明的元素的子元素不会继承透明效果!)

position

position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;

/* Global values */
position: inherit;
position: initial;
position: revert;
position: unset;

在线预览

sticky 详解

Flex

flex

在线测试

line-height

CSS 中起高度作用的是 heightline-height

如果一个标签未定义 height 属性,那么起高度作用的一定是 line-height

line-height 怎么产生了高度呢?

inline box模型中,有个line boxes,这玩意是看不见的,这个玩意的工作就是包裹每行文字。一行文字一个line boxes。例如“艾佛森退役”这5个字,如果它们在一行显示,你艾佛森再牛,对不起,只有一个line boxes罩着你;但“春哥纯爷们”这5个字,要是竖着写,一行一个,那真是够爷们,一个字罩着一个line boxes,于是总计五个line boxesline boxes什么特性也没有,就高度。所以一个没有设置height属性的div的高度就是由一个一个line boxes的高度堆积而成的。

其实line boxes不是直接的生产者,属于中层干部,真正的活儿都是它的手下 – inline boxes干的,这些手下就是文字啦,图片啊,<span>之类的inline属性的标签啦。line boxes只是个考察汇报人员,考察它的手下 谁的实际line-height值最高,它就要最高的值,然后向上汇报,形成高度。例如,<span style="line-height:20px;">取手下line-height<span style="line-height:40px;">最高</span>的值</span>。则line boxes的高度就是40像素了。

行高的垂直居中性

多行文字垂直居中

.mulit_line{
    line-height: 150px;
    border: 1px dashed #cccccc; 
    padding-left: 5px;
    font-size: 0;
}
.mulit_line span{
    display: inline-block; 
    line-height: 1.4em;
    vertical-align: middle;
}
<p class="mulit_line">
    <span style="font-size:12px;">这里是高度为150像素的标签内的多行文字,文字大小为12像素。<br />这里是第二行,用来测试多行的显示效果。</span>
</p>

使用行高代替高度避免 hasLayout

rem VS VW 布局

1. 静态布局

直接使用px作为单位

2. 流式布局

宽度使用%百分比,高度使用px作为单位

3. 自适应布局

创建多个静态布局,每个静态布局对应一个屏幕分辨率范围。使用 @media媒体查询来切换多个布局

4. 响应式布局

通常是糅合了流式布局+弹性布局,再搭配媒体查询技术使用

5. 弹性布局

通常指的是rem或em布局。rem是相对于html元素的font-size大小而言的,而em是相对于其父元素(非font-size的是相对于自身的font-size)

rem vs vw布局

浏览器回流重绘

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

回流(Reflow)

Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。

会导致回流的操作:

  • 页面首次渲染
  • 浏览器窗口大小发生改变
  • 元素尺寸或位置发生改变
  • 元素内容变化(文字数量或图片大小等等)
  • 元素字体大小变化
  • 添加或者删除可见DOM元素
  • 激活CSS伪类(例如::hover
  • 查询某些属性或调用某些方法

一些常用且会导致回流的属性和方法:

  • clientWidthclientHeightclientTopclientLeft
  • offsetWidthoffsetHeightoffsetTopoffsetLeft
  • scrollWidthscrollHeightscrollTopscrollLeft
  • scrollIntoView()scrollIntoViewIfNeeded()
  • getComputedStyle()
  • getBoundingClientRect()
  • scrollTo()

重绘(Repaint)

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:colorbackground-colorvisibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。

性能影响

回流比重绘的代价要更高。

有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。

现代浏览器会对频繁的回流或重绘操作进行优化:

浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。

当你访问以下属性或方法时,浏览器会立刻清空队列:

  • clientWidthclientHeightclientTopclientLeft
  • offsetWidthoffsetHeightoffsetTopoffsetLeft
  • scrollWidthscrollHeightscrollTopscrollLeft
  • widthheight
  • getComputedStyle()
  • getBoundingClientRect()

因为队列中可能会有影响到这些属性或方法返回值的操作,即使你希望获取的信息与队列中操作引发的改变无关,浏览器也会强行清空队列,确保你拿到的值是最精确的。

如何避免

CSS

  • 避免使用table布局。
  • 尽可能在DOM树的最末端改变class
  • 避免设置多层内联样式。
  • 将动画效果应用到position属性为absolutefixed的元素上。
  • 避免使用CSS表达式(例如:calc())。
  • 权衡平滑和速度。
    • Opera还建议我们牺牲平滑度换取速度,其意思是指您可能想每次1像素移动一个动画,但是如果此动画及随后的回流使用了100%的CPU,动画就会看上去是跳动的,因为浏览器正在与更新回流做斗争。动画元素每次移动3像素可能在非常快的机器上看起来平滑度低了,但它不会导致CPU在较慢的机器和移动设备中抖动。

JavaScript

  • 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
  • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
  • 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
  • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
  • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

常见布局

CSS常见布局

常见布局

BFC

BFC全称”Block Formatting Context”, 中文为“块级格式化上下文”。

BFC元素特性表现原则就是,内部子元素再怎么翻江倒海,翻云覆雨都不会影响外部的元素。所以,避免margin穿透啊,清除浮动什么的也好理解了。

BFC的特性

  1. 在BFC中,盒子都是从它的包含块的顶部一个一个的垂直放置的。两个相邻盒子的垂直间距决定于margin属性。在BFC中,两个相邻块级盒子之间垂直方向上的外边距是会塌陷的。
  2. 在BFC中,每个盒子的左外边界挨着包含块的左边界(对于从右到左的格式化,则为右边界互相挨着)。即使是存在浮动元素也是如此(即使一个盒子的行盒是因为浮动而收缩了的),除非这个盒子建立了一个新的BFC(在某些情况下这个盒子自身会因为浮动而变窄)。

创建BFC

满足以下条件之一即可创建BFC

  • 根元素或其它包含它的元素
  • 浮动元素 (元素的 float 不是 none)
  • 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
  • 内联块 (元素具有 display: inline-block)
  • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
  • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
  • 具有overflow 且值不是 visible 的块元素,
  • display: flow-root
  • column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中

CSS 预处理器

CSS 预处理器

CSS 预处理器的缺点

浏览器将rem转成px时有精度误差怎么办?

浏览器将rem转成px时有精度误差怎么办?

inline-block 元素之间的间距

<nav>
    <a href="#">One</a>
    <a href="#">Two</a>
    <a href="#">Three</a>
</nav>
nav a { 
    display: inline-block; 
    padding: 5px; 
    background: red; 
}

image.png

产生原因

元素之间有空格

移除空格

1. 最小化HTML

<ul> 
    <li>
        one</li><li> 
        two</li><li>
        three</li>
</ul>
<ul> 
    <li>one</li
    ><li>two</li ><li
    >three</li>
</ul>
<ul> 
    <li>one</li><!--
    --><li>two</li><!--
    --><li>three</li>
</ul>

2. 负 margin

nav a { 
    display: inline-block; 
    margin-right: -4px;
}

3. 跳过结束标签

<ul> 
    <li>one
    <li>two 
    <li>three
</ul>

4. 设置 font-size: 0

nav { 
    font-size: 0; 
} 
nav a { 
    font-size: 16px;
}