《CSS World》 笔记

CSS 全称是 Cascading Style Sheet ,即层叠样式表。为图文信息展示服务的。1996年12月17日 CSS1 发布 到 1998年5月12日 CSS2 推行内容表现分离。。。

第 1 章

文档流 (Normal Flow)

默认是水平流, writing-mode 属性可以改变文档流方向

第 2 章

专业术语

  1. 属性
  • height
  • background-color
  • 整数值: z-index: 1
  • 数值: line-height: 1.5
  • 百分比值: padding: 50%
  • 长度值: height: 100px
  • 颜色值: color: #999
  • 字符串值: font-weight: bolder
  • 位置值: text-align: left
  • 角度值: transform: rotat(90deg) css3
  • 频率值: css3
  • 时间值: transition: all 3s css3
  1. 关键字
  • transparent
  • solid
  • inherit
  1. 变量
  • currentColor css3
  1. 长度单位
  • 绝对长度
    • px
    • pt
    • pc
    • cm
    • mm
  • 相对字体
    • em
    • ex
    • rem css3
    • ch (字符串 0 的宽度) css3
  • 相对视区
    • vh
    • vw
    • vmin
    • vmax
  1. 功能符 (值以函数的形式指定)
  • color: rbga(0, 0, 0, .3)
  • color: hsla(120, 20%, 70%, .5) Hue(色调) Saturation(饱和度) Lightness(亮度) Alpha透明度
  • background: url(../a.png)
  • height: calc(100vh - 55px)
  • transfrom: scale(-1)
  • content: attr(id)
  1. 属性值
  • 属性冒号后面的所有内容
  1. 声明
  • color: white (属性值 + 属性名)
  1. 声明块
  • { color: #333; height: 50% } (花括号包({})裹的一系列声明)
  1. 规则或规则集
  • .center { margin: 0 auto } (出现的选择器,而且后面跟着声明块)
  1. 选择器
  • 标签
    • p span div
    • .nav .footer .bar
  • id
    • #container
  • 属性
    • [name]
    • [name=”key”]
    • [name^=”key”]
    • [name$=”key”]
    • [name~=”key”]
  • 伪类
    • :nth-child
    • :active
    • :focus
    • :empty
    • :lang(zh) <html lang="zh"></html>
  • 伪元素
    • ::before
    • ::after
    • ::first-line
    • ::first-letter
    • ::selection
  1. 关系选择器
  • 后代
    • body .link
  • 相邻后代
    • .nav > li
  • 兄弟
    • .bar ~ .item
  • 相邻兄弟
    • .item + .item
  1. @规则
  • @font-face
  • @page
  • @media
  • @support
  • @keyframes

未定义行为

Web 标准规范描述以外的场景, 各个浏览器表现不一致, 即 “未定义行为”. 这并不是 bug

第 3 章

元素分类

元素可分为: 块级元素(block-level element), 内联级元素(inline-level element) (HTML4 规范中叫 内联元素)

一般来说: 块级盒子负责结构, 内联盒子负责内容.

常见的块级元素: div p h ul li table

常见的内联级元素: span i ins sup sub storng em img button input select(主要是 display 为 inline inline-block inline-table 的元素)

内联级元素的表现为可以和文字在一行显示.

inline-block 元素: button

每个元素都有 2 个盒子: “外在盒子” 和 “内在盒子(容器盒子)”. 除此自外, list-item 元素还有一个 “标记盒子(remark box)”

按照 display 的属性不同:

  • block = 块级盒子(外) + 块级容器盒子(内)
  • inline = 内联盒子(外) + 内联盒子(内)
  • inline-block = 内联盒子(外) + 块级容器盒子(内)

“内联级元素” 的 “内联” 指的是 “外在盒子”. “块级元素”和 display 为 block 的元素不是一个概念! 如: <li> 的 display 默认是 list-item, <table> 的 display 默认是 table. 但它们均是块级元素.

内联盒模型

内容区域(content area)

内容区域指一种围绕文字看不见的盒子, 本质上是一个字符盒子(character box), 可以认为是文本选择后的背景区域.

内联盒子(inline box)

“内联盒子” 不会让内容成块显示, 而是排成一行, 这里的 “内联盒子” 实际指的是元素的 “外在盒子”(决定元素是内联级还是块级), 该盒子又可以细分为 “内联盒子” 和 “匿名内联盒子”

1
2
<!-- 光秃秃的文字属于 "匿名内联盒子" -->
<p>当前文字是一个匿名内联盒子<span>这个 span 是一个内联盒子, 它后面<span>又是一个匿名内联盒子</p>

行框盒子(line box)

每一行就是一个 “行框盒子”, 每个 “行框盒子” 又是由一个个 “内联盒子” 组成的

1
2
<!-- 假设下面的文字只占据 1 行, 则是一个行框盒子 -->
<p>当前文字<span>和这个 span 以及它后面<span>文字组成的一行就是一个行框盒子</p>

包含块(盒子)(containing block)

多个 “盒子” 组成一个 “包含块(盒子)”

1
2
<!-- 当前 p 标签内有很多文字, 形成多行. p 标签就是一个包含快 -->
<p>p 标签内有很多很多的文字<span>可能不止 span 这一个内联盒子<span>这些文字(匿名内联盒子) 和 span 元素(内联元素) 组成了多行, 被 p 标签包裹着</p>

幽灵空白节点(strut)

在 HTML5 文档声明中, 内联元素的所有解析和渲染表现, 就如同每个行框盒子的前面有一个 “空白节点” 一样. 但这个 “空白节点” 永远透明, 不占据任何宽度, 看不见也无法通过脚本获取, 但又确确实实存在, 表现如同文本节点一样.

以下代码可以验证其真实存在:

1
2
3
4
5
6
7
8
9
10
<style>
.containing-block {
background-color: #f0f;
}
.inline-box {
display: inline-block;
}
</style>
<!-- span 没有内容, 但是 div 的高度不为 0 -->
<div class="containing-block"><span class="inline-box"></span></div>

“幽灵空白节点” 具有其所在行框盒子的 字体 和 行高 属性, 只是宽度值为 0

width/height

width height 属性是作用在 “内在盒子(容器盒子)” 上的

width: auto

width 的默认值是 auto, 它包含了以下 4 种不同的宽度表现

  1. 充分利用可用空间 (fill-available)
  2. 收缩与包裹 (shrink-to-fit) 典型代表: 浮动, 绝对定位, inline-block 元素, table 元素
  3. 收缩到最小 (min-content) 典型代表: 容易出现在 table-layout 为 auto 的表格中
  4. 超出容器限制 (max-content) 典型代表: inline-block 元素设置 white-space: nowrap

元素的尺寸可分为: “外部尺寸” 和 “内部尺寸”.

外部尺寸与流的特性

  1. 正常流宽度

块级元素默认宽度 auto, 大部分都表现为 100% 铺满父容器, 这就是 “外部尺寸”. 此时设置 margin/padding/border 不会影响父容器, 只影响自身的 content 内容区宽度

与设置了其它 width 属性不同, “外部尺寸” 的块级元素设置了宽度, 流特性就丢失了.

  1. 格式化宽度

position 的值为 absolute 或 fixed 时, 元素的宽度表现为 “包裹性” , 即宽度由内部尺寸决定.

但是,对于非替换元素, 当设置了 left/right 或 top/bottom 对立方位的属性值同时存在时,元素的宽度表现为 “格式化宽度”,其宽度大小相对 “包含块” (第六章)计算,具有和普通流一样完全的流特性.

内部尺寸与流的特性

“内部尺寸” 即元素的尺寸由内部元素决定,而非外部的容器.假设该元素没有内容时的宽度是 0, 那就是 “内部尺寸”. 它具有以下几种表现形式:

  1. 包裹性 (shrink-to-fit)

容器的宽度由内部尺寸决定,但永远小于 “包含块” 容器的尺寸(除非容器的尺寸小于元素的 “首选最小宽度”)

代表性的元素: button 浮动元素, 决定定位元素

“包裹性” 实际开发中的应用: 模块文字少的时候居中显示, 文字超过一行时, 左对齐显示.

1
2
3
4
5
6
7
.module {
text-align: center;
.content {
display: inline-block;
text-align: left;
}
}
  1. 首选最小宽度

“首选最小宽度” 指的是元素最适合的最小宽度.

如果父容器的宽度指定为 0, 子元素有内容且不指定宽度的情况下, 其宽度表现如下:

  • 东亚文字最小宽度为每个汉字的宽度
  • 西方文字最小宽度有特定的连续的英文字符单元(终止于空格, 文号, 连字符等)决定. 使用 word-break: break-all 则每一个字符都使用最小宽度, 和中文一样
  • 图片等替换元素最小宽度就是该元素内容本身的宽度
  1. 最大宽度

“最大宽度” 就是元素可以有的最大宽度, 实际上等同于 “包裹性” 元素设置 white-space: nowrap 声明后的宽度.

如果内部没有块级元素或者块级元素没有设定宽度, 则 “最大宽度” 实际上是最大的 “连续内联盒子” 的宽度

连续内联盒子: 全都是内联级别的一个或一堆元素,中间没有任何的换行 <br> 或其它块级元素。以下代码有 3 处连续内联盒子

1
2
3
4
5
6
7
<div>
文字内联 1
<button>元素内联 1</button>
<br/>
<p>块级内文字内联 2</p>
文字内联 3
</div>

width 的作用细节

首先 width 是作用在 “内在盒子” 上的. 而 “内在盒子” 有可分为: content box, padding box, border box, margin box. width 是作用在 content box 上的.

box-sizing 可以改变 width 做用的细节, 支持的属性有 content-box, padding-box (Firefox 曾经支持), border-box. 注意, 并不支持 margin-box

设置 width 不为 auto 的值后, 盒子的流特性丢失, 再设置 border, padding 或 margin 会导致盒子不能 100% 铺满父容器

宽度分离原则实现流布局

width 与 border, padding, margin 共存时, 会存在影响盒子的流特性

一种解决方式是: width 属性独立一个标签, 再该标签的子标签设置 border, padding, margin 的值. 子标签里设置内容.

1
2
3
4
5
6
7
8
.father {
width: 300px
.son {
border: 1px solid;
padding: 5px;
margin: 5px;
}
}

宽度分离的好处是: 内容区(.son)是具有流特性的, 可以修改修改 .father 的 width, 也可以修改 .son 的 border padding margin 但不会导致布局错乱
宽度分离的不足是: 多用了一层标签

更多人使用 box-sizing: border-box 声明来改变 width 作用细节, 但是建议用在替换元素上。

无论 display 的值 是 inline 还是 block, 替换元素的尺寸都由内部元素决定.要使其 100% 适应父容器, 就要设置 width: 100%

替换元素: input textarea img video object

height: auto

height: auto 要比 width: auto 简单的多

CSS 默认流使水平方向的. 宽度是稀缺的, 高度是无限的. 内部元素的累积高度撑起元素的高度

但在决定定位的模型中, 存在 “格式化高度”

height: 100%

为何 height: 100% 会失效

当父元素 width: auto 时, 子元素 width 可以设置百分比. 如下 div width 未指定, 即 auto, span 的 width 却是 div 的 100%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<style>
.box {
display: inline-block;
white-space: nowrap;
}
.text {
display: inline-block;
width: 100%;
}
</style>
<div class="box">
<img src="1.jpg">
<span class="text">文字内容</span>
</div>

height 与 width 不同, 如果父元素 height: auto, 子元素 height 设置成百分比, 会被完全忽略! 只有父元素的 height 是具体的值时才生效.

所以直接给 body 设置 height: 100% 是无效的! 应该 html, body { height: 100% }

浏览器渲染的基本原理: 下载文档, 加载头部资源, 然后按照从上而下, 自外而内的顺序渲染 DOM 内容

规范里的解释: 如果包含快的高度没有显示指定(即高度由内容决定), 并且该元素不是绝对定位, 则计算值为 auto. 所以 auto * 100% = NaN 无法计算

而对于宽度, 规范里的解释: 如果包含块的宽度取决于该元素的宽度, 那么产生的布局在 CSS 2.1 中是未定义的.

如何让元素支持 height: 100%

  • 显示设置高度. 如 height: 399px 或 height: 100%
  • 使用绝对定位. 如: div { position: absolute; height: 100% }, 此时祖先元素 height 为 auto, 元素高度为祖先元素高度

绝对定位元素的百分比计算是相对于 padding box 的, 而非绝对定位元素则是相对于 content box 计算的.

应用: 左右按钮切换图片, 自适应盒子内图片高度.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
.box {
display: inline-block;
position: relative;
}
.prev, .next {
position: absolute;
height: 100%;
width: 50%
}
.next {
right: 0;
}
</style>
<div class="box">
<a class="prev">上一张</a>
<a class="next">下一张</a>
<img src="https://demo.cssworld.cn/images/common/l/1.jpg">
</div>

min-height max-height min-width max-width

min-width max-width 的使用场景是自适应布局和流体布局, 应为它们是具有边界行为的属性.

比如页面版心布局 .container { min-width: 1200px; max-width: 1400px; }

比如移动端显示设置了 width 的大图片有溢出的情况发生. img { max-width: 100%; height: auto !important; } height 设置为 auto 是为了保持图片原有的比例

min-width min-height 的初始值是 auto, 而 max-width max-height 的初始值是 none. max-width 会覆盖 width, 即使 width 使用了 !important! 而 min-width 会覆盖 max-width, 即冲突时, min-width 生效.

max-height 应用: 元素高度不是固定定, 要实现展开, 收起时有明显的高度滑动效果.

1
2
3
4
5
6
7
8
.ele {
max-height: 0;
overflow: hidden;
transition: max-height .25s;
}
.ele:hover {
max-height: 999px; /* 设置一个足够安全的最小值, 不然动画右延迟 */
}

第 4 章

content 与替换元素

什么是替换元素

根据 “外在盒子” 是 “内联” 还是 “块级” 可把元素分为 “内联级元素” 和 “块级元素”

而根据是否具有可替换内容, 又可以把盒子分为 “替换元素” 和 “非替换元素”

替换元素的特点:

  • 可以通过修改某个属性值来呈现不同的内容
    如 img video iframe 的 src 属性修改后, 呈现不同的内容

  • 内容的外观不受页面上 CSS 的影响 (样式表现在 CSS 作用域之外)
    更改替换元素的外观需要类似 appearance 属性, 或者浏览器自身暴露的一些样式接口, 如: ::-ms-check {} 可以修改高版本 IE 单复选框的内间距, 背景色等.

  • 有自己的尺寸
    video iframe canvas 的默认尺寸(不包括边框) 是 300x150, 而 img 是 0x0, 表单类元素的尺寸则与浏览器有关

  • 在很多 CSS 属性上有自己的一套表现规则
    比如, vertical-align 属性默认值为 baseline, 替换元素的 vertical-align 的基线被定义成了元素的下边缘!

基线(baseline) 是字符 x 的下边缘

替换元素默认的 display 值

元素 Chrome IE Firefox
<img> inline inline inline
<iframe> inline inline inline
<video> inline inline inline
<select> inline-block inline-block inline-block
<button> inline-block inline-block inline-block
<textarea> inline-block inline-block inline
<input> inline-block inline-block inline
`<input type=”range file”>` inline-block inline-block inline-block
<input type="hiden"> none none none

<button><input type="button"> 的区别, white-space 属性默认值不一样, 前者是 normal 后者是 pre.

替换元素的 display 值, 不论是 inline, inline-block, block, 其尺寸的计算规则都是一样的[]

替换元素的尺寸计算规则

  1. 固有尺寸
    指的是替换内容原本的尺寸. 比如图片, 视频是有自己的宽度和高度的. 再比如, input 输入框默认有宽度和高度

  2. HTML 尺寸
    介于 固有尺寸 和 CSS 尺寸之间. 某些 HTML 属性是用来指定尺寸的. 比如 img 的 width height, textarea 的 cols rows 等.

  3. CSS 尺寸
    通过 CSS 的 width height max-width/height min-width/height 设置的尺寸, 作用于盒尺寸的 content-box

权重 CSS 尺寸 > HTML 尺寸 > 固有尺寸

<img> 在各浏览器的表现

无 src 时, 即只是 <img>

  • 尺寸
    IE 28x30, Chrome 0x0, Firefox 0x22
    很多浏览器在 src=”” 时也会发送请求

  • 盒子类型

Firefox 下 <img> 是普通的内联元素, 而不是替换元素. 无法设置宽高. 需要 display: inline-block

  • before after 伪元素支持

除了 Firefox 不支持 ::before 其它都支持

图片显示 alt 信息小技巧

1
2
3
4
5
6
7
8
9
10
11
12
img::after {
content: attr(alt);
position: absolute;
bottom: 0;
width: 100%;
background-color: rgba(0, 0, 0, .5);
transform: translateY(100%);
transition: transform .3s;
}
img:hover::after {
transform: translateY(0);
}

替换元素内容固有尺寸

1
2
3
4
5
6
7
/* 以下代码的图片按固有尺寸显示 */
div::before {
content: url(./1.jpg);
display: block;
width: 200px;
height: 200px;
}

使用 object-fit 属性控制替换内容的适配方式

  • object-fit: none 图片不受控制
  • object: fill <img> 的默认适配方式,
  • object: contain 替换内容会尽可能的利用 HTML 尺寸, 类似 backgrou-size: contain

图片懒加载占位小技巧 img { visibility: hidden } img[src] { visibility: visible }

content 属性与替换元素

替换元素替换掉的是 content box 中的内容 (使用 box-sizing 属性可以改变 content box)

理论上讲 content 属性决定了是替换元素还是非替换元素

Chrome 浏览器下, 所有的元素都支持 content 属性, 而其它浏览器仅在 ::before/::after 中才支持

content 属性特点

  • 设置了 content 属性不会影响 :empty 伪类选择器
  • content 属性生成的值无法获取, 无法选中, 无法被屏幕阅读器读取, 无法被搜索引擎抓取

实用技巧

  1. 图片替换

    1
    2
    3
    4
    5
    6
    <img src="icon-home.png">
    <style>
    img.active {
    content: url(icon-home-active.png)
    }
    </style>
  2. 网站图片 logo, 不影响 SEO

1
2
3
4
5
6
<h1>CSS World</h1>
<style>
h1 {
content: url(logo.png)
}
</style>

图片替换改变的只是视觉呈现, 右键保存图片还是保存 src 指向的地址, 屏幕阅读设备也不识别.

  1. 正在加载提示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
正在加载<dot>...</dot>
<style>
dot {
display: inline-block;
height: 1em;
line-height: 1;
text-align: left;
vertical-align: -.25em;
overflow: hidden;
}
dot::before{
display: block;
content: "...\a..\a.";
white-space: pre-wrap; /*pre-wrap 和 pre 效果是一样的*/
animation: dot 3s infinite step-start both;
}
@keyframes dot {
33% {
transform: translateY(-2em);
}
66% {
transform: translateY(-1em);
}
}
</style>
  1. 内联图片
1
2
3
4
5
6
7
a {
text-decoration: underline;
color: #cd0000;
}
a[target="_blank"]:after {
content: url(data:image/gif;base64,R0lGODlhBQAFAIABAM0AAAAAACH5BAEAAAEALAAAAAAFAAUAAAIHRIB2eKuOCgA7);
}
  1. open-quote close-quote

quotes 属性可以指定 open-quote 和 close-quote

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<p class="ask">为什么地球是圆的?</p>
<p class="answer">因为地球是本来就是圆的.</p>
<style>
.ask {
quotes: '提问: "' '"'
}
.ask {
quotes: '回答: "' '"'
}
.ask::before,
.answer::before {
content: open-quote;
}
.ask::after,
.answer::after {
content: close-quote;
}
</style>
  1. content 实现计数器

CSS 计数器有几个属性

  • counter-reset counter-name [0] 普照源(计数器重置), 一次指定多个计数器名, 空格隔开, 起始值默认是 0, 可以为负数
  • counter-increment counter-name [1] 普照(计数器递增), 指定计数器递增数量, 默认是 1, 可以是 负数
  • counter(counter-name, [list-style-type]) 当前计数器的值, 类似 attr(att)
  • counters(counter-name, connect-string [list-style-type]) 嵌套计数器的值, 显示为父级计数值链接子级计数值

list-style-type 支持 disc | circle | square | decimal | lower/upper-roman | lower/upper-latin | lower/upper-alpha 等等

1
2
3
4
5
6
7
8
9
.counter {
counter-reset: coun1 2;
counter-increment: coun1; /*增加1*/
}
.counter::before {
content: counter(coun1);
counter-increment: coun1 2; /*增加2*/
}
/*显示5*/

计数器的变化遵循 HTML 的渲染顺序, 遇到一个 increment 计数器就变化, 什么时候 counter() 就输出此时的计数值

counters 的使用需要子元素对父元素重置普照源(counter-reset),

实现目录效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!-- 
1. 第一章
1.2 第一节
2. 第二章
2.1 第一节
-->
<div class="reset">
<!-- 第一章 -->
<div class="counter">第一章
<div class="reset">
<div class="counter">第一节</div>
</div>
<!-- 第二章 -->
<div class="counter">第一章
<div class="reset">
<div class="counter">第一节<</div>
</div>
</div>

</div>
</div>
<style>
.reset {
padding-left: 20px;
counter-reset: index;
}
.counter:before {
content: counters(index, ".") ". ";
counter-increment: index;
}
</style>

padding 属性

块级元素 width 失效的情况

1
2
3
4
5
6
/* 下面设置空 div CSS,  最终宽度为 120px (首选最先宽度) */
.box {
width: 80px;
padding: 60px;
box-sizing: border-box;
}

内联元素设置 padding

内联元素(display 的值不是 inline-block)没有可视宽度(clientWidth)可视高度(clientHeight)的说法, 垂直方向的表现行为完全受 line-height 和 vertical-align 的影响.

视觉上并没有改变与上下内容的间距. 感觉像是垂直方向的 padding 没有起作用

实际上, 内联元素设置垂直方向 padding 同样会影响布局和视觉表现, 与其它元素在垂直方向发生了重叠, 对父元素设置 overflow: auto 就能看到滚动条

这类似 relative 定位, box-shadow outline, 但这些都是视觉性了影响, 对盒子尺寸没影响

实用技巧

  1. 扩展点击区域
1
2
3
a.click {
padding 0.25em 0
}
  1. 文字分割线 “注册 | 登录”
1
2
3
4
5
6
7
a + a::after {
content: "";
font-size: 0; /*使用 padding 控制盒尺寸*/
padding: 10px 3px 1px;
margin-left: 6px;
border-left: 1px solid grey;
}
  1. 点击带锚点的标题滚动窗口到距离标题 50px
1
2
3
4
5
6
7
8
9
10
<h3><span>标题标题标题</span></h3>
<style>
h3 {
line-height: 30px;
font-size: 14px;
}
h3 > span {
padding-top: 58px /*h3 上下有 8px 空白*/
}
</style>

padding 的百分比

padding 不支持负值, 其百分比的值无论是水平还是垂直方向均是相对于 父元素的 宽度计算的!

实用技巧

  1. 网页贯穿屏幕的顶部 banner 图
1
2
3
4
5
6
7
8
9
10
11
.box {
width: 10% 50%; /* 宽高比 5:1 */
position: relative;
}
.box > img {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
}

对于内联元素(inline), 有以下不同点

  • padding 会断行

padding 区域是更着内联盒模型中的行框盒子走的. 文字过多换行后, padding 区也跟着文字换行了. 且 padding 区域形成的背景不是矩形

1
2
3
4
5
6
7
/* <div><span>文字文字文字</span></div> */
div {
width:100px;
}
div > span {
padding: 50%;
}
  • 默认的宽度和高度细节不同

上述代码中, 如果 span 内没有文字, span 也不是正方形. 因为内联元素设置 垂直方向 的 padding, 会让内联元素内出现 “幽灵空白节点”.

所有, 只要给 span 设置 font-size: 0 就成正方形了

元素内置 padding

有些元素有默认的 padding 值, 而且不同的浏览器表现不一样

  1. ol/ul 内置 padding-left, Chrome 下 40px
  2. input/textarea/select/radio/checkbox/button 内置 padding

其中 button 的 padding 不好控制!

去除默认 padding 值

1
2
3
4
5
6
button {
padding: 0; /* Chrome */
}
button::-moz-focus-inner {
padding: 0; /* Firefox */
}

设置 padding 值

1
2
3
4
5
button {
line-height: 20px;
border: none;
padding: 20px; /* Chrome 下*/
}

实用技巧

  1. 使用 label 元素实现 button
1
2
3
4
5
6
7
8
9
10
11
12
13
/* 
<button id="btn"></button>
<label for="btn">按钮</label>
*/
button {
position: absolute;
clip: rect(0 0 0 0);
}
label {
display: inline-block;
line-height: 20px;
padding: 10px;
}
  1. “三杠” 菜单
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .icon-menu {
    display: inline-block;
    width: 140px;
    height: 10px;
    border-top: 10px solid;
    border-bottom: 10px solid;
    background-color: currentColor;
    background-clip: content-box;
    }

兼容性问题: 如果滚动容器设置 padding-bottom 值, overflow: auto, 对于 Chrome 浏览器, 子元素总高度超过 容器 content box 高度则触发滚动条提示, 而 IE Firefox, 子元素总高度超过容器 padding box 高度触发滚动条提示. 所以不要给滚动容器设置 padding-bottom 值! 以下代码在 Chrome 下滚动, Firefox 无滚动

1
2
3
4
5
6
7
8
9
10
11
12
div {
height: 200px;
overflow: auto;
padding-bottom: 100px;

}
div > span {
display: inline-block;
width: 100px;
height: 250px;
background-color: grey;
}

margin 属性

元素尺寸相关概念

  • 元素尺寸

也就是元素的 border-box 的尺寸, 包含了 padding 和 border 部分. 在 DOM API 中是 offsetWidth/offsetHeight 属性, 在 jQuery 中是 outerWidth/outerHeight 方法

  • 元素内部尺寸

也就是元素的 padding-box 的尺寸, 包含了 padding, 步包括 border 部分. 在 DOM API 中是 clientWidth/clientHeight 属性, 在 jQuery 中是 innerWidth/innerHeight 方法

  • 元素外部尺寸

也就是元素的 margin-box 的尺寸, 包含了 padding, border, margin 部分. 在 jQuery 中是 outerWidth(true)/outerHeight(true) 方法

负值 margin 对元素尺寸的影响

  • 对于块状特性的元素:

如果元素的表现是”充分利用可用空间”, 无论是垂直还是水平方向, 都可以通过设置 margin 正负值来改变自身尺寸.

对于定死 width 的元素, 设置 margin 不能自身尺寸, 改变的是自身对空间的占用, 即影响周边的元素布局.

  • 对于纯内联级元素(inline):

设置垂直方向的 margin 没有任何影响, 设置水平方向 margin 不影响内部尺寸. 不影响外部尺寸.

实用技巧

  1. 左侧定宽, 右侧自适应宽度布局
1
2
3
4
5
6
7
8
9
.wrapper {
overflow: hidden;
}
.left {
float: left
}
.right {
margin-left: 140px;
}
  1. 水平多列布局, 去除最后一列的的间隙
1
2
3
4
5
6
7
8
9
10
11
/* 不考虑 flex 布局 */
ul {
margin-right: -5px;
}
ul > li {
width: 25%;
}
ul > li > div {
margin-right: 5px;
background: grey;
}
  1. 多列等高布局

可以使用边框模拟 + 绝对定位来实现 2 列等高布局, 使用 display: table-cell 可以实现多列等高布局(IE8 以上推荐). 还可以使用 margin

1
2
3
4
5
6
7
8
9
.container {
overflow: hidden;
}
.container > .column {
float: left;
padding-bottom: 99999px;
/* border-bottom: 99999px; 也可以使用 border 替代 padding */
margin-bottom: -99999px;
}

上述方法有限制尽量不使用, 使用了 overflow: hidden 子元素不能定位到容器外, 触发锚点定位或使用 DOM.scrollIntoview() 方法可能出现奇怪的定位问题

margin 百分比

和 padding 一样, margin 的百分比水平, 垂直方向都是相对于父元素的宽度来计算的.

margin 合并

块级元素(不包括浮动, 绝对定位)的 margin-top margin-bottom 有时候会合并为单个外边距.

margin 合并发生情况

  • 相邻兄弟元素垂直方向相邻的 margin
  • 父级和最后一个/第一个子元素垂直方向相邻的 margin
  • 空块级元素自身的垂直方向的 margin

display: block 的替换元素同样拥有 margin 合并特性

阻止 margin 合并

  • 父元素设置为 “块状格式化上下文” 元素
  • 父元素设置 border-top/bottom/padding-top/bottom 值
  • 父元素和第一个/最后一个子元素直间添加内联元素隔开
  • 父元素设置 height/min-height/max-height (仅针对父元素 margin-bottom 的合并情况和空块级元素自身垂直方向 margin 的合并情况)

margin 合并导致 jQuery 的 slideUp()/slideDown() 动画时跳动

margin 计算规则

正正取大值, 正负值相加, 负负最负值

元素内置 margin 值

body margin: 8px
p ul h3 margin: 1em 0;

margin auto

在水平方向: 块级元素的宽度, 默认是父元素的 100%. 如果定死宽度, 并且宽度小于父元素. 则剩余的宽度空间由 margin auto 填充. 如果子元素定的尺寸大于父元素, margin auto 将失效!

水平方向:

  1. 一侧有 margin 值, 另一侧 margin 值为 auto, 则 auto 为剩余空间大小 (margin-left: auto 实现块级元素右对齐)
  2. 两侧 margin 值为 auto, 则左右平分剩余空间

margin auto 生效的条件是对应的方向有自动填充特性的, 要实现垂直方向 margin auto 生效, 则使用声明 writing-mode: vertical-lr. 但随之的是水平方向失效. 对于替换元素, 设置 display: block 后 margin auto 的计算规则同样适用!

实用技巧:

  1. 垂直水平居中定位(IE8 以上)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.pop {
position: relative;
}
.pop > .container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* 以上四行声明 "格式化宽度, 高度" */
width: 500px;
height: 300px;
margin: auto;
}

上述例子中, 如果 container 高度比父元素大, margin auto 计算为负值, 仍然会垂直居中.

margin 无效的情况

  • dispaly: inline 的 “非替换元素” 的垂直 margin (对于内联的替换元素, margin 有效, 并且永远不会出现 margin 合并的情况)
  • 表格中的 tr td 元素或者是 display 值是 table-cell table-row 的元素
  • margin 合并时, 生效了, 但合并结果不是你设置的值
  • 绝对定位元素, 非定位方位的 margin 值 “无效”
  • 浮动元素的子元素设置与浮动方向相反的 margin 无效
  • 内联特性也可导致 margin 失效 (受 vertical-align 的影响)

绝对定位的元素的渲染是独立的, 设置 margin 值不会影响其兄弟元素的定位(父元素可出现滚动条). 当其自身占用的空间却改变了. 而非定位元素设置 margin 值是可以影响其兄弟/父元素的

::first-letter 可以解析 margin 值

border 属

border-width 属性

border-width 不支持百分比值, 支持关键字 thin(1px) medium(3px)(默认) thick(4px)

border-style 支持的值:

  • none(默认) (这就是为啥 border 属性只设置宽度没有效果的原因, 只要设置 border-style 即可生效)
  • solid
  • dashed (Chrome, Firefox 颜色块宽高比 3:1, 颜色块与间隔宽度比 1:1, IE 均是 2:1)
  • dotted (Chrome, Firefox 颜色块下是正方形, IE 是圆形)
  • double (3px 以上才有效果)
  • inset(内凹), outset(外凸), groove(沟槽), ridge(山脊) 等的兼容性不佳, 且显得过时

实用技巧:

  1. “三道杠”菜单符号
1
2
3
4
5
6
.icon-menu {
width: 12em;
height: 2em;
border-top: 6em double;
border-bottom: 2em solid;
}

border-color 属性

border-color 的色值, 默认就是当前元素 color 属性的值! 对于上传文件那种 “田” 符号的宽, 只设置 color, border-color 缺省. :hover 时只要改变 color 就可以了

透明边框实用技巧:

  1. 增加点击区域的大小. 虽然 padding 也能做到, 但点击区域使用了雪碧图时会导致背景图片定位偏移

  2. background-position 只能相对于左上角定位, 利用透明边框, 可以实现相对于右下角定位

1
2
3
4
5
6
.box {
background-position: 100% 100%;
border-right: 40px solid transparent;
border-bottom: 10px solid transparent;
/* 图片右下角距离 box 右下角 40px 10px */
}
  1. 绘制等腰直角三角形
1
2
3
4
5
div {
width: 0; /* 有大小时, 是一个梯形 */
border: 10px solid;
border-color: #00 transparent transparent; /*减少透明边框的数量呈现不同的图像*/
}
  1. 两个三角形重叠, 形成对话框气泡的尾巴

  2. 两(三)列等高布局, (border 宽度固定, 使用 vw 单位可以实现类似等比效果)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.box {
border-left: 150px solid #bfa;
background-color: grey;
}
.box::after { /*不能使用 overflow: hidden 清除浮动, 会隐藏 nav */
content: "";
display: block;
clear: both;
}
.box > nav {
float: left;
width: 150px;
margin-left: -150px;
}
.box > section {
overflow: hidden;
}

相比 margin + padding 的等高布局, 不会存在锚点定位带来的问题 多栏等高布局, 首选 display: table-cell

color: transparent (IE9+) border-color: transparent(IE7+)

第 5 章

字母 x 与 baseline

line-height 指的是两条基线的距离, vertical-align 的默认值是基线(baseline)

基线的位置, 就是字母 x 的下边缘. CSS 中 x-height 就是指字母 x 的高度. 而 middle 指的是基线往上 1/2 x-height 的高度

微软雅黑是一个字符下沉比较明显的字体. 1/2 x-height 的位置在容器中分线往下一点. 由此可见, vertical-align: middle 并不是绝对的垂直居中对齐.

字母 x 与 ex (IE6+)

ex 是 CSS 中的一个相对单位, 指的是小写字母 x 的高度, 即 x-height. 可以用于实现文字与小图标的垂直方向对齐, 不受字体大小影响

1
2
3
4
5
6
7
8
9
/*
<span>XXxxx<i class="icon-arrow-down"></i></span>
*/
.icon-arrow-down {
display: inline-block;
width: 20px;
height: 1ex;
background: url(/images/5/arrow.png) no-repeat center;
}

line-height

line-height 是内联元素高度之本! 对于非替换元素的纯内联元素, 其可视高度完全由 line-height 决定.

行距 = 行高 - em-box, 即 行距 = line-height - font-size

第 6 章

第 7 章

第 8 章

第 9 章

# book

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×