共计 7950 个字符,预计需要花费 20 分钟才能阅读完成。
前言
本文是对《CSS 世界》阅读中所做笔记和感悟,若有错误请指正。
概述
CSS 设计初衷是为了更好地展示图文。HTML 元素根据”外在盒子“是内联还是块级,分成块级元素和内联元素。HTML 元素也可根据是否具有可替换内容,分成替换元素和非替换元素
块级元素
一个水平流上只能显示一个块级元素,多个块级元素则换行显示。display 值为 block、list-item、table。
/* 利用块级元素换行特性清除浮动:*/
.clear:after{
content:”,
display:table;
clear:both;
}
常见的块级元素有 div、li、table。
块级元素构成 ={
主块:{
内在盒子:block|table{
content-box:”width 默认作用在这 ”
padding-box:
border-box:” 改变 box-sizing 使得 width 作用在这 ”
margin-box:
},
外在盒子:block,
},
附加块(可选):如 list-item,
}
[兼容]IE 不支持 before/after 伪元素 display 为 list-item
width:auto 表现:fill-available,fit-content,min-content,max-content
通过设定显示的高度和绝对定位可让元素支持 height:100%,前者相对于 content-box, 后者相对于 padding-box 计算百分比。
min-width/height 初始值是 auto,max-width/height 初始值是 none。权重:min-width>max-with>width!important
[技巧]transition 搭配 max-height 可制造展开收起动画
内联元素
可以和文字在一行显示。display 值为 inline、inline-block, inline-table 常见的内联元素有 button、img、input、select。
内联元素构成 ={
主块:{
内在盒子:block|table{
content-box
padding-box
border-box
margin-box
},
外在盒子:”inline”,
},
}
<!– 包含盒子 –>
<p><!– 内容区域 –>
文字 <!– 内联盒子(匿名)–>
<em><!– 内联盒子(具名)–>
em
</em>
<!– 行框盒子 –>
文字 <em>em</em>
</p>
HTML5 的内联元素渲染每个行框盒子前面有个”幽灵空白节点“即 strut(支柱), 一个具有该元素字体和行高属性的 0 宽内联盒子 *(如下效果相同)
<div class=”box”>
字符 <span> 内容 …</span>
</div>
<div class=”box”>
<span> 内容 …</span>
</div>
解决上述幽灵空白节点方法:
内联元素块状化
容器 line-height:0
font-size:0
内联元素设置 vertical-align:top|middle|bottom
替换元素
通过修改某个属性呈现内容可被替换的元素。如 img、object、video、iframe、textarea、input。内容外观不受 css 影响,在很多 css 属性上有自己的一套表现规则。[兼容]textarea & input 在 ie 和 chrome 是 inline-block,在 firefox 上是 inline
[技巧]img 的 src 与 content 搭配,可以使得看到的图是 content, 保存的是 src[技巧]content 可设置 attr(alt)和自定义属性如 attr(data-title)、font-icon[技巧]content 计数器 counters
盒模型
padding
内联元素 padding 会断行
[技巧]padding 增加点击区域,增加锚链接顶部留白 [技巧] 利用 padding 百分比横竖都是相对于宽度计算,实现块状元素自适应等比例矩形
[兼容]ol/ul 列表内置 padding-left 单位是 px(chrome 内置 40px)[兼容]firefox 的 button 需设置 button::-moz-focus-inner{padding:0}才能消除 padding
margin
margin 百分比横竖都是相对于宽度计算
[技巧]margin 一侧 auto, 则 auto 为剩余空间大小;两侧 auto 则平分剩余空间 [技巧] 使用 writing-mode 改变流向,搭配 margin:auto 垂直居中 [技巧] 使用 absolute 上下左右零 + 固定宽高 +margin:auto 可水平垂直居中
[兼容]如果容器可以滚动,ie 和 firefox 会忽略 padding-bottom,chrome 则不会,因为前者超过 content-box 触发滚动,后者超过 padding-box 触发。所以建议使用 margin-bottom
margin 合并
块级元素的 margin-top 与 margin-bottom 合并为单个。合并计算:“正正取大值”“正负值相加”“负负最负值”合并场景:
1. 相邻兄弟元素 margin 合并
设计缘由:让图文信息排版更舒服自然。
p {margin: 1em 0;}
<p> 第一行 </p>
<p> 第二行 </p>
2. 父级和第一个 / 最后一个子元素
设计缘由:div 语义作用是分组,嵌套分组被设计成不阻断合并
<div class=”father” style=”margin-top:80px;”>
<div class=”son” style=”margin-top:80px;”></div>
</div>
对于 margin-top 合并,解决方案选其一:
父元素设置为块状格式化上下文元素;
父元素设置 border-top 或 padding-top 值;
父元素和第一个子元素之间添加内联元素进行分隔。
对于 margin-bottom 合并,解决方案选其一:
父元素设置为块状格式化上下文元素;
父元素设置 border-bottom 或 padding-bottom 值;
父元素和最后一个子元素之间添加内联元素进行分隔;
父元素设置 height、min-height 或 max-height
3. 空块级元素 margin 合并
设计缘由:可以避免多个空标签(如 <p>)影响排版
.father {overflow: hidden;}
.son {margin: 1em 0;}
<div class=”father”>
<div class=”son”></div>
</div>
对于空块级元素 margin 合并,解决方案选其一:
设置垂直方向的 border 或 padding;
里面添加内联元素(直接 Space 键空格是没用的);
设置 height 或者 min-height。
margin 无效情形
display:inline 的费替换元素的垂直 margin 无效
tr|td 或 display:table-cell|table-row 的 margin 无效
margin 合并,见上节
绝对定位元素非定位方位的 margin 值看上去“无效”
定高容器的子元素的 margin-bottom 或者宽度定死的子元素的 margin-right 的定位看上去“失效”。
鞭长莫及(float 和 overflow)导致的 margin 无效
内联特性 (vertical-align) 导致的 margin 无效
border
border-width 不支持百分比值
border-style 的默认值是 none
[兼容]虚线边框 (dashed) 在 Chrome 和 Firefox 下,颜色区的宽高比是 3:1, 颜色区和透明区的宽度比例是 1:1; 而 IE 颜色区的宽高比是 2:1, 颜色区和透明区的宽度比例也是 2:1[兼容]虚点边框 (dotted) 在 Chrome 和 Firefox 浏览器下是方点; 而 IE 下则是小圆点
[技巧]双线边框 (double) 在 3px 以上才开始有双线边框的表现(包括 retina 屏)。[技巧]利用 double+solid 实现三道杠 [技巧] 缺省 border-color 可以统一用 color 设置边框颜色(currentColor)[技巧]border 绘制三角形
line-height
vertical-align:middle 是对文字中线,不是相对容器
[技巧]内联图标使用 height:1ex 使得基线对齐
内联元素 line-height 的高度作用细节:em-box=font-size(不含 gq 等字母尾巴,汉字图形高度略小于 font-size)行距 = line-height – em-box 半行距 = 行距 / 2 内容区域 = 文本选中带背景色的区域,高度受 font-family 和 font-size 影响(宋体内容区域和 em-box 等高)
块级元素高度不受 line-height 影响, 平时我们看到的高度本质是由内联元素“行框盒子”line-height 撑开高度(如 div 内有文字时)
替换元素高度不受 line-height 影响,平时我们看到的高度本质是“行框盒子”前面的“幽灵空白节点”撑开高度
内联替换元素和内联非替换元素在一起时会共同形成一个“行框盒子”,line-height 决定这个行盒的最小高度。原因有二:
替换元素的高度不受 line-height 影响
vertical-align
line-height 可以让单行或多行内联元素近似垂直居中(“近似”:文字中线位置低于“行框盒子”;多行需搭配 vertical-align)
line-height 默认值为 normal,不同字体不同。值为数值(如 1.5)时:子元素继承该数值;值为百分比(150%)或长度(20px)时:子元素继承计算值。(注:line-height 数值需向上舍入)
line-height 是相对于 font-size 计算的
vertical-align
只能应用于内联元素以及 display:table-cell 的元素。(浮动和绝对定位会让元素块状化,vertical-align 失效)
负值全部都是往下偏移, 正值全部都是往上偏移, 而且数值大小全部都是相对于基线位置计算的, 即 vertical-align:baseline 等同于 vertical-align:0。
值类型:
线类, 如 baseline(默认值)、top、middle、bottom;
文本类, 如 text-top、text-bottom;
上标下标类, 如 sub、super;
数值百分比类, 如 20px、2em、20% 等(相对于 line-height 的计算值计算的)
[技巧]vertical-align:middle 的 table-cell 使得内部元素垂直居中
vertical-align:baseline 的显示:
内联元素:字符 x 的下边缘
替换元素:替换元素的下边缘
inline-block:
里面无内联元素或 overflow 不是 visible: margin 底边缘
否则:最后一行内联元素的基线
vertial-align:top 的显示:
内联元素: 元素底部和当前行框盒子的顶部对齐。
table-cell 元素: 元素底 padding 边缘和表格行的顶部对齐
vertial-align:bottom 的显示:“顶部”换成“底部”,“上边缘”换成“下边缘”。
vertial-align:middle 的显示:
内联元素: 元素的垂直中心点和行框盒子基线往上 1/2 x-height 处对齐。
table-cell 元素: 单元格填充盒子相对于外面的表格行居中对齐。
vertical-align:text-top: 盒子的顶部和父级内容区域的顶部对齐。vertical-align:text-bottom: 盒子的底部和父级内容区域的底部对齐 vertical-align:super: 提高盒子的基线到父级合适的上标基线位置。vertical-align:sub: 降低盒子的基线到父级合适的下标基线位置。
流
float
浮动的本质就是为了实现文字环绕效果。特性:• 包裹性;• 块状化并格式化上下文;• 破坏文档流;• 没有任何 margin 合并;
块状化:一旦 float 的属性值不为 none, 则其 display 计算值就是 block 或者 table。
float 定位参考的是“行框盒子”。
BFC
如果一个元素具有 BFC, 内部子元素不会影响外部的元素。(不会 margin 重叠); 可以用来清除浮动的影响(子元素浮动则父元素高度塌陷)。
触发 BFC 的情况:
<html> 根元素;
float 的值不为 none;
overflow 的值为 auto | scroll | hidden;
display 的值为 table-cell | table-caption | inline-block
position 的值不为 relative | static。
overflow
当子元素内容超出容器宽度高度限制的时候, 剪裁的边界是 border box 的内边缘, 而非 padding box 的内边缘。PC 端浏览器滚动条作用在 html 而不是 body。*[技巧]text-overflow:ellipsis 搭配 -webkit-line-clamp 实现多行文字打点效果
absolute
absolute 是非常独立的 CSS 属性值,其样式和行为表现不依赖其他任何 CSS 属性就可以完成。
“包含块”规范:
根元素 (html) 被称为“初始包含块”,尺寸 = 浏览器可视窗口的大小。
对于其他元素,如果该元素的 position :relative|static,则“包含块”由其最近的块容器祖先盒的 content box 边界形成。
如果元素 position:fixed,则“包含块”是“初始包含块”。
如果元素 position:absolute,则“包含块”由最近的 position 不为 static 的祖先元素建立,具体方式如下:
如果该祖先元素是纯 inline 元素:
假设给内联元素的前后各生成一个宽度为 0 的内联盒子(inline box),则这两个内联盒子的 padding box 外面的包围盒就是内联元素的“包含块”;
如果该内联元素被跨行分割了,规范并没有明确定义,浏览器自行发挥。
否则,“包含块”由该祖先的 padding box 边界形成。
如果没有符合条件的祖先元素,则“包含块”是“初始包含块”。
如果 overflow 不是定位元素,同时绝对定位元素和 overflow 容器之间也没有定位元素,则 overflow 无法对 absolute 元素进行剪裁。
[技巧]避免被“包含块”限制一柱擎天,使用 white-space:no-wrap。[技巧]右上角标签通过 absolute 配合透明 border 实现[技巧]text-align 实现“返回顶部”
[兼容]overflow 元素自身 transform,IE9 +、Firefox 和 Safari(OS X、iOS)剪裁;Chrome 和 Opera 不剪裁
relative 最小化影响原则能避免创建新的层叠上下文。默认的文档流是自上而下、从左往右,因此优先级 top>bottom.left>right。
蒙层弹窗 2 种实现方案:
absolute 模拟 fixed 定位,滚动结构调整大
js: 移动端:阻止 touchmove 桌面端:根元素 overflow:hidden + border 代替滚动条
层叠上下文
特性
• 层叠上下文的层叠水平要比普通元素高。• 层叠上下文可以阻断元素的混合模式。• 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的“层叠上下文”。• 每个层叠上下文和兄弟元素独立,也就是说,当进行层叠变化或渲染的时候,只需要考虑后代元素。• 每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中。
创建
根元素 (HTML),
z-index 值不为 “auto” 的 绝对 / 相对定位
一个 z-index != “auto” 的 flex 项目 (flex item),即:父元素 display:flex|inline-flex
opacity < 1 的元素
transform != “none” 的元素
mix-blend-mode != “normal” 的元素
filter !=“none”的元素
perspective !=“none”的元素
isolation : “isolate” 的元素
position: fixed
在 will-change 中指定了任意 CSS 属性
-webkit-overflow-scrolling 属性被设置 “touch” 的元素
层叠顺序
从低到高:
background、border
负 z -index
block 块状水平盒子
float 浮动盒子
inline 水平盒子
z-index:auto 或 不依赖 z -index 数值的层叠上下文(看成 z -index:0)
正 z -index
[技巧]z-index 布局不超 2,浮层组件利用 js 层级计数不超 9
文本
font-weight 取值是 100,200,…,800,900。系统自带不同粗细字体决定浏览器能否渲染。italic 是使用当前字体的斜体字体,而 oblique 只是单纯地让文字倾斜。::first-letter 包含符号 (包括空格),::before 直到一个字符。font 属性:caption | icon | menu | message-box | small-caption | status-bar[兼容]caption、icon、message-box 在 Windows 下 Chrome 无效[技巧]html {font: menu;} 可以让浏览器字体跟随系统 font-face 兼容写法:
@font-face {
font-family: ICON;
src: url(‘icon.eot’);
src: local(‘☺’),
url(‘icon.woff2’) format(“woff2”),
url(‘icon.woff’) format(“woff”),
url(‘icon.ttf’);
}
[技巧]font-weight 实现响应式图标 text-indent 的百分比值是相对于当前元素的“包含块”计算的,而不是当前元素。[技巧]text-indent+overflow:hidden 隐藏 img 的 alt 边框 letter-space、word-spacing 默认 normal, 不是 0,支持负值、小数,不支持百分比。[技巧]white-space:nowrap 解决尺寸过小,水平列表切换 [技巧]text-transform:uppercase 解决身份证验证码输入自动大写[技巧] 借助:after 补行搭配 text-align:justify 实现两端对齐
其他
伪类:用于向某些选择器加特殊的效果。(:active, :focus, :hover, :link, :visited, :first-child, :lang)伪元素:用于将特殊的效果添加到选择器。(::first-letter, ::first-line, ::before, ::after)visibility 可继承,不影响计数器,display:none 则相反。unicode-bidi:bidi-override 强制字符根据 direction:rtl|ltr 方向排列 writing-mode:horizontal-tb|vertical-rl|vertical-lrwriting-mode 特性:
水平方向也能 margin 合并
普通块元素可以使用 margin:auto 实现垂直居中
可以使用 text-align:center 实现图片垂直居中
可以使用 text-indent 实现文字下沉效果
不可全局 outline:0 none[技巧]visibility 搭配 transition 实现悬停延时显示,移出瞬时隐藏 [技巧] 很大的 outline 实现周五半透明遮罩,用在剪裁图片矩形镂空上和填补网页底部留白[兼容]display:none 子元素背景图片在 chrome safari 不加载,其他情况加载