盒模型

盒模型分为四部分:

  • margin box
  • border box
  • padding box
  • content box

标准盒模型(content-box):

  • block 盒子可设置宽高(默认占满父容器宽度),padding/margin/border 会把其他元素推开,width/height 是指 content box 的宽高,整个 block 盒子的宽高应加上 padding box 和 border box,默认换行;
  • inline 盒子不可设置宽高(由内容决定),padding/margin/border 可以生效,但只有内联方向的值会把其他 inline 盒子推开,且默认不换行;现代浏览器默认为标准盒模型。

替代盒模型(border-box):宽高计算方式改变,width/height 是指 border box 的宽高,同时就是盒子的实际宽高。

盒模型转换:可通过 box-sizing 设置元素为标准(content-box)或替代(border-box)盒模型。

Others:

  • inline-block 外部显示为 inline 盒子,内部显示为 block 盒子;
  • 相邻盒子块方向上的 margin 会折叠(只保留最大的 margin);
  • 将盒模型设置为 border-box 方便计算盒子宽高;

px/em/rem/vw/vh

  • px:CSS 像素单位;
  • em:用于 font-size 时,指相对于父元素 font-size 的倍数;用于其他属性时,指相对于自身 font-size 的倍数;
  • rem:指相对于根元素(html)font-size 的倍数;
  • vw:viewport 宽的 1%;
  • vh:viewport 长的 1%;

注:对同一设备而言,px 是绝对长度,em/rem/vw/vh 是相对长度;

pixel 与 css 长度单位 px

  • pixel:针对设备而言,由硬件决定,表示屏幕上一个最小显示单元;
  • css px:针对 css 而言,由浏览器决定,一般定义为 1/96 inch 左右,也就是说 96px 约等于物理意义的 1 英寸;

像素、分辨率、ppi 及屏幕尺寸的关系

  • px:像素是虚拟单位,表示最小的独立色块;
  • 分辨率:设备硬件决定分辨率,一般表示为:横向像素数量 * 竖向像素数量,即屏幕上的总像素数量;
  • ppi:pixel per inch,也称为像素密度,显然本身是一个单位;
  • 屏幕尺寸:屏幕对角线的物理长度,单位 inch;

书写模式与逻辑方向(writing-mode & logic/physical properties)

writing-mode:horizontal-tb/vertical-rl/vertical-lr 用于控制书写方向,同时也会决定块和行的流动方向(进而影响盒子的排列方式)。

  • 当书写方向为 horizontal-tb (top to bottom)时,从上到下为块流动方向,从左到右为行流动方向;
  • 当书写方向为 vertical-rl (right to left)时,从右到左为块流动方向,从上到下为行流动方向;
  • 当书写方向为 vertical-lr (left to right)时,从左到右为块流动方向,从上到下为行流动方向;

从逻辑角度控制全局,而非物理/维度等角度,从而保证不同的 writing-mode 下表现也仍然一致,以下列举部分属性:

  • block-size 等同于 horizontal-tb 时的 height,vertical 时的 width(max/min-block-size 一样);
  • inline-size 等同于 horizontal-tb 时的 width,vertical 时的 height(max/min-block-size 一样);

大致规则就是假设 writing-mode:horizontal-tb,然后 block/inline 指示轴线,start/end 指示起始位置,根据物理属性可以推导出其逻辑属性,例如 margin-left,对应 margin-inline-start.

格式化上下文:BFC & IFC

Formatting Context,一种虚拟概念,表示一个具有特定布局规则的区域

  • BFC 是块级格式化上下文;
  • IFC 是内联格式化上下文;

如何创建 BFC

对于 block 元素,满足以下任意一点即可创建 BFC:

  1. 根元素
  2. position: absolute/fixed/sticky
  3. float item
  4. display 为
    1. inline-block
    2. table-cell(表格单元格)
    3. table-captain(表格标题)
    4. flow-root(HTML 根元素)
  5. flex-item, grid-item
  6. 多列布局元素
  7. overflow: 非 visible

BFC 特点及可解决的问题

特点

  • BFC 内部所有元素的 block 方向上的 margin 将会折叠
  • BFC 内部元素的布局不影响外部元素

通过父元素创建 BFC 可以解决:

  • 父子元素外边距折叠;
  • 隔离 float 元素的影响;
  • 父元素高度坍塌;

注 1:一般通用的创建 BFC 方法为 overflow:hidden/scroll/auto;

注 2:容器高度坍塌是指内部元素由于脱离正常文档流,导致容器高度计算时不会计算内部元素高度,进而使得高度缩小;

IFC 特点

IFC 由内联盒子(inline box)创建,IFC 内会划分出行框(line box),然后将所有内容放入行框,假如出现换行,则新创建一个行框。

特点:

  • inline 元素水平排列;
  • 上下方向的 margin、padding、height 不生效;
  • 用 line-height 代替 height(其实,我认为该属性的命名就是指:height of line box);

常见布局方式

  • 正常文档流布局(兼容所有浏览器)
  • 基于 position 的布局(IE 不兼容 position:sticky)
  • 基于 float 的 Multicol 布局(几乎兼容所有浏览器)
  • 网格布局(IE 10 使用-ms-前缀实现了旧版规范)
  • 弹性布局(IE 8 使用-ms-flexbox 前缀实现了旧版规范;IE 11 中 inline block 元素会被错误定位)
  • Multicol 布局(IE 10 +)

隐藏元素的几种做法

  • opacity: 0,DOM 没有移除,布局没有改变,可以点击,仍然需要计算 CSS;
  • visibility: hidden,DOM 没有移除,布局没有改变,可以点击,不需要计算 CSS;
  • display: none,完全移除 DOM,布局改变,不可点击;

文本超长截断的实现

单行文本

1
2
3
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

多行文本(兼容性不佳)

1
2
3
4
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; //行数
overflow: hidden;

元素居中之 transform vs margin

1
2
3
4
5
6
7
8
9
.transform-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.margin-center {
margin: 0 auto;
}
  • .transform-center元素脱离文档流,在新图层渲染;
  • .margin-center元素不脱离文档流;

注:如果页面会频繁改变边距,那么.transform-center是性能更优的选择,而且还可以实现一些边距改变时的动画效果。

position相关

  • static(default):静态定位,根据文档中的源顺序决定排列顺序;
  • relative:相对定位,相对于文档中自身位置进行定位;
  • absolute:绝对定位,相对于最近的非 static 祖先元素定位,将脱离正常文档流;
  • fixed:固定定位,相对于 Viewport 定位,将脱离正常文档流;
  • sticky:粘性定位,使用 top/right/bottom/left 设定阈值,初始时等同于 static 定位,通过滚动使其位置达到阈值,此时等同于 fixed 定位。

position:sticky相关

效果:sticky 定位的元素,相对于有滚动条最近块级祖先元素,其偏移量:

  • 未超过预设值(top/right/bottom/left),则随页面滚动;
  • 超过预设值,则不随页面滚动,而是固定在屏幕上;

细节:

  • 偏移量是相对于有滚动条最近块级祖先元素计算的,如果没有,则相对于 viewport 计算;
  • 会创建 stacking context;
  • 最近块级祖先的 overflow 不能为 hidden、scroll、auto、overlay;
  • 不会脱离正常文档流;

sticky polyfill 实现(简化)

1
2
3
<div id="container" class="sticky-container">
<div id="item" class="sticky-item"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
.sticky-container {
position: relative;
}
.sticky-item {
position: absolute;
top: 0;
}
.sticky-item-fixed {
position: fixed;
top: 0;
}
1
2
3
4
5
6
7
8
9
window.addEventListener("scroll", () => {
const container = document.getElementById("container");
const item = document.getElementById("item");

const elOffset = container.offsetTop;
const pageOffset = window.pageYOffset;

item.className = pageOffset > elOffset ? "sticky-item" : "sticky-item-fixed";
});

注:

  • 包一层 relative 定位的 div,避免内部元素脱离文档流后(position: fixed)offsetTop 丢失;
  • pageXOffset,pageYOffset文档左上角相对于viewport 左上角的横、纵向偏移量,单位是 px,兼容性好于scrollX,scrollY
  • 只模拟效果,未考虑其他复杂情况,例如 sticky 元素偏移量计算的参考元素(祖先元素)脱离 viewport 时如何显示,等等;

z-index

决定元素堆叠顺序,值越大,堆叠越靠前;非 static 元素 z-index 默认为 auto,实际值为 0,但 auto 不会创建新的本地堆叠上下文,指定一个 number 会创建一个新的本地堆叠上下文,上下文中的子元素的 z-index 将不会对外部元素生效。

CSS 实现多边形

原理:借助盒模型理解,border 的相邻两边,其邻接处是一条斜线;

  • height/width 设为 0,隐去 border 的某些边(border-color: transparent),可得三角形;
  • height/width 不为 0,隐去 border 的某些边,可得梯形;
  • 以上任意组合,可得多边形;

CSS3 新增特性

  • 选择器
  • 盒子模型属性:border-radius、box-shadow、border-image
  • 背景:background-size、background-origin、background-clip
  • 文本效果:text-shadow、word-wrap
  • 颜色:新增 RGBA,HSLA 模式
  • 渐变:线性渐变、径向渐变
  • 字体:@font-face
  • 2D/3D 转换:transform、transform-origin
  • 过渡与动画:transition、@keyframes、animation
  • 多列布局
  • 媒体查询

flex: 1的含义

flex是 flex-grow、flex-shrink 和 flex-basis 的简写属性,共有三种语法形式,这里flex:1是单值语法,含义是指定flex-grow: 1,shrink 和 basis 分别默认为 1 和 0;

进一步的说,flex-grow: 1是指弹性容器如果出现剩余空间,此时按照 flex-grow 设置的比例去拉伸 flex item 以填充剩余空间;

选择器

  • Basic Selector
    • Universal(*)
    • Type(div)
    • Class(.class)
    • ID(#id)
    • Attribute([attr] [attr=value] [attr~=value] [attr|=value] [attr^=value])
  • Group Selector(any, any)
  • Combinators
    • Descendant(A B)
    • Child(A > B)
    • General sibling(A ~ B)
    • Adjacent sibling (A + B)
    • Column ( A || B ),目前所有浏览器都不支持
  • Pseudo
    • Class (:visited)
    • Element(::nth-child)

CSS 优先级

关系选择器本身没有优先级,但由关系选择器组合而成的选择器的优先级,由基础选择器的优先级的权重计算而成,基础选择器优先级权重如下:

  • 最高级: 内联样式
  • 次高级: id 选择器
  • 中级: 类,属性,伪类选择器
  • 低级: 元素,伪元素选择器

马克思主义原理——量变质变,反着记:量变不会导致质变。也就是说,同级权重即便累加(量变),也不会超越更高级的权重(质变)。

!important 标识的 CSS 属性优先级超越以上任何权重。

属性选择器详解

  • [attr] 精确匹配属性 attr
  • [attr=”value”] 精确匹配属性 attr 和值 value
  • [attr|=”value”] 精确匹配属性 attr 和以 value 开头的值,value 可后接连字符”-“
  • [attr~=”value”] 精确匹配属性 attr 和以空格分隔含有 value 子串的值
  • [attr^=”value”] 属性同上,以 value 开头的值
  • [attr$=”value”] 属性同上,以 value 结尾的值
  • [attr*=”value”] 属性同上,模糊匹配含 value 的值
  • [attr=”ValuE”i] 大小写不敏感的值匹配

响应式

响应式布局技术:现代布局有 flex/grid/multi-column

媒体查询:通过@media 指令开启,语法包含两部分:媒体类型(media-type)和媒体条件(media-condition)。可通过与(and)或(,)非(not)混合媒体类型和条件。

常用媒体类型如下:

  • all:所有媒体;
  • print:打印机;
  • screen:屏幕设备;
  • speech:阅读器;

常用媒体特征如下:

  • width/height:明确指定的媒体设备的 width/height;
  • min-width/min-height:范围 width/height,媒体设备宽/高大于该值时,表达式才为真;
  • max-width/max-height:范围 width/height,媒体设备宽/高小于该值时,表达式才为真;
  • orientation:portrait/landscape,portrait 意为处于 viewport 纵向,即宽小于高,landscape 相反;
  • hover:none/hover,媒体是否支持悬浮操作(可用于判断是否是触摸屏设备);
  • pointer:none/fine/coarse,媒体支持的指针设备精度如何,fine 为高精度指针(如鼠标),coarse 为低精度指针(如触摸屏);

排版:使用 em/rem/vw/vh 等相对单位。

元标签:使用<meta name="viewport" content="width=device-width,initial-scale=1">覆盖移动端浏览器的 viewport 的某些属性,例如 width/height/initial-scale 等,来使移动端浏览器的 viewport 属性符合我们的预期。

响应式图片实现技巧:为不同设备的用户提供不同的图片,借助srcset/sizes/<picture> 实现图片尺寸/分辨率的自适应,IE 不支持srcset/picture,实现方式有如下几种。

  1. srcset + sizes:srcset 设置图片集,url + 像素宽(单位 w),之间以逗号分隔,每个 url 对应一张图片,像素宽就是该图片的像素宽度,sizes 设置多个媒体条件,格式为 (media condition) + 图片槽宽度,以逗号分隔,当媒体条件为真时图像将要填充指定宽度的图片槽,特别的是最后一条应当省略媒体条件,以作为所有条件都不匹配时的默认值。浏览器根据 sizes 获取图片槽宽度,选择 srcset 中最接近的一张图片加载。
  2. srcset:设置图片集,url + css 像素/device 像素 + x,例如(https://test.com/1.jpg 1.5x),设备大小相同,但是发光点数量可能不同,所以可能出现两个发光点来渲染出一个 css 像素点的情况,这时可以用语法 2x 表示,此时将会选择对应的图片加载。特别的是 1x 可以省略。
  3. <picture>:设置其子元素<source>,source 的 media 属性可以设置一个媒体条件,srcset 属性可以设置为 url + 像素宽,当媒体条件匹配时,该图片才会加载,最后一个子元素应当是一个<img>标签作为默认图片。

动画

Transition

添加厂商前缀(如-ms,-webkit 等)可以增强其兼容性,但一般通过类库统一处理

  • transition-property:定义需要动画过渡的属性;
  • transition-duration:time 定义动画的演出时间;
  • transition-timing-function:定义缓动函数(控制动画播放节奏);
  • transition-delay:time 定义动画的延迟时间;
  • transition:上述属性的简写,第一个时间被解析为 duration,第二个被解析为 delay,其他属性先后顺序不重要;

Animation

规则@keyframes用于定义动画关键帧列表,用百分比标识时间点,0% 和 100% 别名分别为 from 和 to,语法格式如下:

1
2
3
4
5
6
7
8
@keyframes slidein {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}

animation 相关属性如下:

  • animation-name:@keyframes name 用于指定动画的关键帧列表,设置为 none 可取消动画;
  • animation-duration:time 用于指定动画的一个演出周期的时长;
  • animation-delay:time 用于指定动画延迟时间;
  • animation-timing-function:定义缓动函数(控制动画播放节奏);
  • animation-iteration-count:number 用于定义动画循环次数,指定为 0 则动画将立刻结束,指定为 infinite 则为无限循环,指定为小数则最后一次动画将以小数点后的百分比作为最后一个关键帧;
  • animation-direction:默认为 normal 指动画方向不变;reverse 指动画播放从 to 到 from 的关键帧;alternate 指动画正向播放后再反向播放;alternate-reverse 指动画反向播放后再正向播放;
  • animation-fill-mode:默认为 none 指动画未执行时,不会把任何样式应用于目标;forwards 指动画执行结束后最后一个关键帧的样式将持续应用于目标上,执行前不存在影响;backwards 指执行之前第一个关键帧的样式将持续应用于目标上,结束后消失;both 是 forwads 和 backwards 的叠加,目标将在动画开始前应用第一个关键帧,并在动画结束后应用最后一个关键帧;该属性受 animation-direction & animation-iteration-count 影响;
  • animation-play-state:running 指动画正在执行,paused 指动画已被暂停,通过该属性查询/设置动画执行的状态;
  • animation:上述属性的简写,时间按相对顺序解析,第一个解析为 duration,第二个为 delay,其他属性顺序不重要;