及格线上的css
- CSS只是貌似简单
- CSS ≠ 设计
- CSS规范
- 向后兼容性
- CSS选择器
- 特异性
- 默认样式表
- 不同的浏览器有不同的默认值
- 默认样式表
- 每个属性也有一个默认的"初始值"
- CSS属性可以通过5种方式设置 (从低到高优先级)
- 单位
- 内联 vs 块级
- 盒子(Box)模型
- 每个HTML元素都在一个盒子中
- 盒子有内边距(padding), 边框(boarder)和外边距(margin)
- 宽度和高度不包含margin/boarder/padding
- 外边距竖向允许重叠, 横向不允许
box-sizing: border-box;包含边框+内边距在宽度/高度中- 内边距(padding)和边框(boarder)在元素内部, 外边距在外部
- 内边距和外边距语法
- 边框
- Flexbox基础
display: flex;flex-direction: row;flex-wrap: wrap;justify-content: center;align-items: center;- 可以嵌套Flexbox
- CSS Grid
- 居中
text-align居中文本margin: auto居中块级元素margin: auto仅水平居中- 使用Flexbox或Grid轻松实现垂直居中
- 只为居中一个东西而使用Flexbox或Grid是可以的
position: absoluteposition: absolute;- 典型的CSS
top,bottom,left,right将放置一个绝对定位的元素left: 0; right: 0;≠width: 100%;- 绝对定位的元素不会影响父元素布局
- 隐藏元素
- 层叠上下文
- CSS变量
- 过渡
- 媒体查询
- 现代浏览器的CSS检查器
- 检查清单

了以下css知识, 开发react/vue/angular应该勉强够用, 不会太为样式问题太挠头.
CSS只是貌似简单
乍一看没啥东西
代码示例:
h2 {
font-size: 22px;
}
网页对应css布局
+--------------+
| Header |
+--------------+
| |
| Bldy |
| |
| |
+--------------+
一不留神就复杂了
+------------------------------------+
| +----+ |
| logo .. .. | | menu |
| +----+ |
+-----------+------------------------+
| +-------+ |+----------------------+|
| | | || ||
| +-------+ || ||
| ..... |+----------------------+|
| |+------+ +-----+ +-----+|
| .... |+------+ +-----+ +-----+|
| |+----------------------+|
| |+----------------------+|
+-----------+------------------------+
规范也是一言难尽
比如说 overflow: hidden 设置在内联块元素上会改变它的垂直对齐方式.
overflow: hidden 设置在内联块元素(display: inline-block)上时,
可能会影响其垂直对齐方式.
默认情况下, 内联块元素会基于基线(baseline)对齐, 但 overflow: hidden
会使其基于底部(bottom)对齐.
这种行为可以通过 vertical-align 属性进行调整, 例如设置为 top 或
middle 来改变对齐方式.
所有浏览器都有bug
比如safrai就不支持 <summary> 元素上的flexbox.
调整费事费力
❤️ + ⌚️ = 很棒的网页样式
CSS ≠ 设计
网页设计不简单, 能实现这些设计的CSS更加不易, 需要了解css规范, 以及各类扩展知识(flexbox?)
- 设计和实现css是两种不同的技能.
- 当有一个好的设计时, CSS就更容易.
- 理解技术的限制, 调整整设计.
- 草图可以起到很大的帮助.
CSS规范
CSS的规范详尽
max-width: 150px;
max-width: 20em;
max-width: 75%;
max-width: 75ch;
曾经, 只有一个规范(css2.1)
而今, 每个CSS 特性 都有自己的规范
主要的浏览器通常遵守规范, 但有时它们有bug
级别
CSS版本被称为"级别". 新的级别只添加新特性. 它们不会改变现有CSS代码的行为.
新特性需要时间来实现
向后兼容性
浏览器永远支持旧的HTML和CSS
1998年的CSS, 在2020年的浏览器上仍然运行良好!
历史决定了包袱
比如为什么CSS单位这么奇怪? 一说就得从20年前.
当然也有好处
css是web标准!
- 花几天时间让CSS工作, 然后可以用一辈子.
- 如果不遵循标准, 就不能保证向后兼容性
- 只要测试CSS在用户正在使用的浏览器上就能工作!
- 自从1998年以来, 较新的CSS特性使响应式设计变得容易.
CSS选择器
div | 匹配div元素 | <div> |
#welcome | 通过id匹配元素 | <div id="welcome"> |
.button | 通过class匹配元素 | <a class="button"> |
div .button | 匹配div的每个button | |
div.button | 匹配带有class "button"的div | <div class="button"> |
div > .button | 匹配每个作为div的直接子元素的button素 | |
.button, #welcome | 匹配 .button 和 #welcome 元素 | |
[href^="http"] | 匹配href属性以http开头的a元素 | |
:checked | 如果复选框或单选按钮被选中则匹配 | |
a:hover | 配光标悬停在其上的a元素 | |
tr:nth-child(odd) | 匹配交替的tr元素(制作条纹表格! ) |
特异性
不同的规则可以设置相同的属性
a:visited {
color: purple;
font-size: 1.2em;
}
#start-link {
color: orange;
}
哪个会被选中?
CSS使用与元素匹配的"最特异" 选择器
浏览器将使用 color: orange, 因为ID(如 #start-link)比伪类(如
:visited)更特异.
CSS可以混合来自不同规则的属性
a:visited {
color: purple;
font-size: 1.2em;
}
#start-link {
color: orange;
}
它将使用这个字体大小, 但使用这个颜色, 因为 #start-link 更特异.
CSS如何选择"最特异"的规则
流程图:
| 元素名称选择器 | < | 类选择器或伪类选择器 |
| 类选择器或伪类选择器 | < | ID选择器 |
| ID选择器 | < | 内连样式 |
| 内连样式 | < | !important 规则 |
!important 非常难以覆盖, 这是给未来的自己上强度.
默认样式表
每个浏览器都有一个默认样式表(也称为" 用户代理样式表" )
代码示例 (来自Firefox默认样式表):
h1 {
font-size: 2em;
font-weight: bold;
}
不同的浏览器有不同的默认值
文字: 按钮和表单有一些最大的差异.
默认样式表
文字: Firefox的默认样式表位于: resource:///gre-resources/
每个属性也有一个默认的"初始值"
初始值(在规范中定义)是在没有样式表设置任何内容时使用的值. 例如,
background-color 的初始值是透明的.
CSS属性可以通过5种方式设置 (从低到高优先级)
- 初始值
- 浏览器的默认样式表
- 网站的样式表
- 用户样式表(最不常用)
- 使用HTML/JS设置的内联样式
单位
CSS有两种单位: 绝对单位和相对单位
绝对单位: px, pt, pc, in, cm, mm; 相对单位: em, rem, vw, vh, %, ch
等
| px | 像素 |
| pt | 点,1pt = 1/72英寸 |
| pc | 派卡,1pc = 12pt |
| in | 英寸 |
| cm | 厘米 |
| mm | 毫米 |
| Q | 四分之一毫米,1Q = 0.25mm |
| em | 相对于当前元素的字体大小. |
| rem | 相对于根元素(通常是 <html> 元素)的字体大小. |
| vw | 相对于视口宽度的 1%. |
| vh | 相对于视口高度的 1%. |
| vmin | 相对于视口宽度和高度中较小者的 1%. |
| vmax | 相对于视口宽度和高度中较大者的 1%. |
| % | 相对于父元素的尺寸. |
| ch | 相对于数字" 0" 字符的宽度. |
| ex | 相对于当前元素字体的 x 高度(通常是小写字母的高度). |
| fr | 网格布局中的比例单位, 用于分配剩余空间(例如在 CSS Grid 中). |
rem
根元素的字体大小. 1rem在文档中的任何地方都是相同的. rem是设置字体大小的好单位!
em
父元素的字体大小. 代码示例: .child { font-size: 1.5em; }
0在所有单位中都是相同的
.btn {
margin: 0;
}
0与 none 不同. border: 0 设置边框宽度, border: none 设置样式.
1英寸 = 96像素
在屏幕上, 1个CSS"英寸" 并不是真正的英寸, 1个CSS"像素" 也不是真正的屏幕像素. 搜索"设备像素比"以了解更多信息.
rem和em有助于辅助功能
.modal {
width: 20rem;
}
如果用户增加了他们的浏览器默认字体大小, 这将很好地缩放.
内联 vs 块级
HTML元素默认为内联或块级
内联元素示例: <a>, <span>, <strong>, <i>, <small>, <abbr>,
<img>, <code>, <blockquote>;
块级元素示例: <p>, <div>, <ol>, <ul>, <li>, <h1> - <h6>,
<blockquote >, <pre>
内联元素水平排列
内联元素 <a> 和 <span> 水平排列
~~~~~ <a> ~~~ ~~ ~~~~~
~~~~~~~~~ ~~ <span>~~~~
~~ ~~~~~~ ~~~~~
块级元素默认垂直排列
块级元素 <div> 和 <p> 垂直排列;
+-------------------+
| div |
+-------------------+
| p |
+-------------------+
为了获得不同的布局, 请使用 display: flex 或 display: grid
内联元素忽略宽度和高度
设置宽度是不可能的, 但在某些情况下, 可以使用 line-height 来改变高度;
<img> 是对此的例外: 查找"替换元素(replaced element)"以了解更多信息.
display 可以强制元素为内联或块级
display 决定两件事:
- 元素本身是否是内联(
inline), 块级(block), 内联块级(inline-block)等; - 子元素如何排列:网格(grid), flex, 表格(table), 默认(default)等;
display: inline-block;
inline-block 使块级元素像内联元素一样水平排列; 图示说明内联文本,
更多内联文本和内联块级文本的排列方式
~~~~~ <a> ~~~ ~~ ~~~~~ ~~~~
+------------+
~~~~~~~~~ ~~ |inline block|~~
+------------+
~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~
盒子(Box)模型
每个HTML元素都在一个盒子中
<div class="1">
<div class="2"/>
<div class="3"/>
</div>
+-----------------+
|1 |
| +------------+ |
| |2 | |
| +------------+ |
| +------------+ |
| |3 | |
| +------------+ |
+-----------------+
盒子有内边距(padding), 边框(boarder)和外边距(margin)
+-----------------------+
| margin |
| +-------------------+ |
| | boarder | |
| | +---------------+ | |
| | | padding | | |
| | | +-----------+ | | |
| | | | | | | | |
| | | | | | | | | height
| | | | | | | | |
| | | +-----------+ | | |
| | +---------------+ | |
| +-------------------+ |
+-----------------------+
------------
width
宽度和高度不包含margin/boarder/padding
+-----------------------+
| margin |
| +-------------------+ |
| | boarder | |
| | +---------------+ | |
| | | padding | | |
| | | +-----------+ | | |
| | | | | | | | |
| | | | | | | | | height
| | | | | | | | |
| | | +-----------+ | | |
| | +---------------+ | |
| +-------------------+ |
+-----------------------+
------------
width
外边距竖向允许重叠, 横向不允许
+----------------+
| |
| +------------+ |
| | | |
| | | |
| | | |
| +------------+ |
+----------------+
| +------------+ |
| | | |
| | | |
| | | |
| +------------+ |
| |
+----------------+
浏览器组合这些顶部/底部外边距;
查看文档中的"外边距折叠(margin collapse)" 以了解更多信息.
box-sizing: border-box; 包含边框+内边距在宽度/高度中
+-----------------------+
| margin |
| +-------------------+ |
| | boarder | | |
| | +---------------+ | | |
| | | padding | | | |
| | | +-----------+ | | | |
| | | | | | | | | height
| | | | | | | | |
| | | | | | | | |
| | | +-----------+ | | | |
| | +---------------+ | | |
| +-------------------+ |
+-----------------------+
--------------------
width
box-sizing: border-box; 情况下, 宽度和高度包含了边框和内边距.
内边距(padding)和边框(boarder)在元素内部, 外边距在外部
点击元素的边框/内边距会触发它的 onclick 事件, 但点击外边距不会.
内边距和外边距语法
有四种方法设置内边距
padding: 1em; /* 四周都设置 */
padding: 1em 2em; /* 垂直和水平方向设置 */
padding: 1em 2em 3em; /* 上, 右, 下设置 */
padding: 1em 2em 3em 4em; /* 上, 右, 下, 左设置 */
也可以只设置一侧的内边距
padding-top: 1em;
padding-right: 10px;
padding-bottom: 3em;
padding-left: 4em;
内边距和外边距之间的区别
内边距在元素"内部": 背景颜色覆盖内边距, 可以点击内边距来点击元素等等. 外边距在"外部" .
可以使用外边距居中: auto, 但不能对内边距使用
外边距可以为负值, 内边距不可以.
外边距语法与内边距相同
border-width 也使用相同的顺序: 上, 右, 下, 左
边框
边框有三个组成部分
border: 2px solid black;
等同于: border-width: 2px; border-style: solid; border-color: black;
border-style 选项
solid(实线), dotted(点虚线), dashed(线虚线), double(双线), 以及更多 (inset, groove, 等)
border-{side}
可以分别设置每一侧的边框: border-bottom: 2px solid black;
border-radius
border-radius 允许圆角; 代码示例: border-radius: 10px;;
border-radius: 50%; 将正方形变成圆形!
box-shadow
允许为任何元素添加阴影; 代码示例: box-shadow: 5px 5px 8px black;
(x偏移量, y偏移量, 模糊半径, 颜色)
outline
outline 类似于边框, 但在添加时不会改变元素的大小; 悬停/激活时的
outline 有助于辅助功能: 使用键盘导航时, 需要一个 outline
来查看焦点所在.
Flexbox基础
display: flex;
设置在父元素上, 以Flexbox布局来排列其子元素. 默认情况下, 它设置
flex-direction: row;
flex-direction: row;
+------+ +--------------+ +----+
| | | | | |
+------+ +--------------+ +----+
默认情况下, 子元素在一行中排列. 另一个选项是 flex-direction: column
+------+
| |
+------+
+---------+
| |
+---------+
+-------------+
| |
+-------------+
flex-wrap: wrap;
将换行, 而不是缩小所有内容以适应一行.
+------------+ +-------+
| | | +---+
+------------+ +-------+ |
+-----------------------------+
| +--------+
+->| |
+--------+
justify-content: center;
水平居中(如果设置了 flex-direction: column 则垂直居中)
+------------+ +-------+
| | | |
+------------+ +-------+
+--------+
| |
+--------+
align-items: center;
垂直居中(如果设置了 flex-direction: column 则水平居中)
+---------------------------------+
| +------+ |
| | | +--------+ |
| +-------+ | | | | |
| | | | | | | |
| +-------+ | | | | |
| | | +--------+ |
| +------+ |
+---------------------------------+
可以嵌套Flexbox
disply: flex
+---------------------------------------------+
| disply:flex disply:flex |
| +-------------------+ +-------------------+ |
| | +---+ +---+ +---+ | | +---------------+ | |
| | | | | | | | | | | | | |
| | | | | | | | | | +---------------+ | |
| | | | | | | | | | +---------------+ | |
| | | | | | | | | | | | | |
| | | | | | | | | | +---------------+ | |
| | | | | | | | | | +---------------+ | |
| | | | | | | | | | | | | |
| | +---+ +---+ +---+ | | +---------------+ | |
| +-------------------+ +-------------------+ |
+---------------------------------------------+
CSS Grid
构建一个布局
简单的网页布局, 包含头部, 侧边栏和主要内容区域.
+------------------------+
| Header |
+------------------------+
+----+ +-----------------+
| | | |
|side| | content |
|bar | | |
| | | |
+----+ +-----------------+
grid-template-areas 允许以一种几乎是可视化的方式定义你的布局
grid-template-areas:
"header header"
"sidebar content";
编写HTML
代码示例:
<div class="grid">
<div class="top"></div>
<div class="side"></div>
<div class="main"></div>
</div>
定义区域
.grid {
display: grid;
grid-template-columns: 200px 800px;
grid-template-areas:
"header header"
"sidebar content";
}
设置 grid-area
.top { grid-area: header; }
.side { grid-area: sidebar; }
.main { grid-area: content; }
居中
text-align 居中文本
h2 {
text-align: center;
}
margin: auto 居中块级元素
HTML示例:
<div class="parent">
<div class="child"></div>
</div>
margin: auto 仅水平居中
.child {
width: 400px;
margin: auto;
}
垂直方向没有居中.
+---+------+----+
| |child | |
| +------+ |
| |
| |
| |
+---------------+
使用Flexbox或Grid轻松实现垂直居中
使用Grid的方法
代码示例:
.parent {
display: grid;
place-items: center;
}
使用Flexbox的方法
.parent {
display: flex;
}
.child {
margin: auto;
}
只为居中一个东西而使用Flexbox或Grid是可以的
- 使用 Flexbox:
display: flex; justify-content: center; align-items: center; - 使用 Grid:
display: grid; place-items: center;
position: absolute
position: absolute;
绝对定位相对于父级容器(containing block), 而不是页面;
包含块是最近的祖先元素, 其 position 属性不是 static (默认值),
或者如果不存在这样的祖先, 则为 body.
典型的CSS
#square {
position: absolute;
top: 1em; left: 1em;
}
#parent {
position: relative;
}
+-------------------+
| ^ |
| | 1em |
| v |
| 1em +--------+ |
| <----> | | |
| |#square | |
| +--------+ |
| |
|#parent |
+-------------------+
top, bottom, left, right 将放置一个绝对定位的元素
top: 50%;
bottom: 2em;
right: 30px;
left: -3em;
使用 top, bottom, left, right 属性进行绝对定位, 负值也适用.
+---------------+
| |
| |
+-----+-------------+ |
| | | |
| | | |
| | | |
+-----+-------------+ |
+---------------+
left: 0; right: 0; ≠ width: 100%;
left: 0; right: 0;
width: 100%;
left: 0; right: 0; ~和 ~width: 100%; 的区别, 默认情况下宽度不包含边框.
left:0 right:0 width :100%
+--------------+ +--------------+
|+------------+| |+------------+|
||+----------+|| ||+-----------++
||| ||| ||| ||
||| ||| ||| ||
||+----------+|| ||+-----------++
|| || || ||
|| || || ||
|| || || ||
|+------------+| |+------------+|
+--------------+ +--------------+
绝对定位的元素不会影响父元素布局
当一个元素被设置为 position: absolute; 时, 它会脱离正常的布局流程.
这意味着:
父元素不会扩展以适应绝对定位的子元素: 父元素在布局时不会考虑绝对定位子元素的大小和位置, 因此不会自动调整自身的高度或宽度来包含它.
绝对定位的元素相对于最近的已定位祖先元素定位: 如果没有已定位的祖先元素, 它会相对于初始包含块(通常是视口)定位.
因此, 绝对定位的元素不会影响父元素的布局, 父元素也不会根据它的大小进行调整.
隐藏元素
有很多方法可以让元素消失
选择哪一个取决于: 它留下的空位要被填补吗?
display: none;
其他元素将移动以填充空位.
+----+ +----+ +----+
| 1 | | 2 | | 3 |
+----+ +--+-+ +----+
|
+---+ display:none
|
v
+----+ +----+
| 1 | | 3 |
+----+ +----+
visibility: hidden;
空位将保持为空.
+----+ +----+ +----+
| 1 | | 2 | | 3 |
+----+ +--+-+ +----+
|
| visibility:hidden
+----+ v +----+
| 1 | | 3 |
+----+ +----+
opacity: 0;
类似于 visibility: hidden;, 但是仍然可以点击该元素,
并且它对屏幕阅读器仍然可见. 通常 visibility: hidden 更好.
如何缓慢淡出
#fade:hover {
transition: all 1s ease;
visibility: hidden;
opacity: 0;
}
只需设置不透明度, 以便动画起作用.
z-index
z-index 设置重叠的定位元素的顺序.
+----------+ +----------+
| | | |
+----+----+ | +----+ |
| | | | | | |
| | | | | | |
+----+----+ | +----+ |
+----------+ +----------+
层叠上下文
z-index 可以指定元素显示的堆叠中的层级
.first {
z-index: 3;
}
.second {
z-index: 0;
}
+----------+
| +-------+
|.first | |
| +-------+
+----------+
但是更高的 z-index 并不总是将元素放在顶部
即使 z-index 值较高, 元素也可能不会位于顶部, 这取决于层叠上下文.
+----------------------------+
| z-index:0 |
| +---------------------+ |
| |z-index:10 | |
| | | |
| | +---------+---+--------------+
| | | z-index:2 |
| | | |
| +-----------+ |
| | |
+--------------+ |
| |
| |
| |
| |
+----------------------------+
每个元素都在一个层叠上下文中
默认情况下, 元素的子元素共享其层叠上下文.
设置 z-index 会创建一个层叠上下文
#modal {
z-index: 5;
position: absolute;
}
这是创建层叠上下文的一种常用方法.
层叠上下文令人困惑
可以在完全不理解它们的情况下做很多事情. 但是, 如果 z-index
没有按照期望的方式工作,那就得花点功夫了.
CSS变量
避免重复
在100个地方设置了 color: #f79, 就需要在100个地方更改它!
在任何选择器中定义变量
body {
--text-color: #f79;
}
#header {
--text-color: #c50;
}
应用于所有内容; 应用于 #header 的子元素
使用 var() 使用变量
body {
color: var(--text-color);
}
变量总是以 -- 开头
使用 calc() 对它们进行数学运算
#sidebar {
width: calc(var(--my-var) + 1em);
}
可以在JavaScript中更改变量的值
let root = document.documentElement;
root.style.setProperty('--text-color', 'black');
对变量的更改会立即生效
文字: 图示说明JS更改变量后, CSS渲染器立即更新颜色.
过渡
元素的计算样式可以改变
发生这种情况的两种方式: 1. 伪类(如 :hover); 2. JavaScript代码
el.classList.add('x')
新样式会立即更改元素
a:hover {
color: red;
}
元素将立即变为红色
除非设置了 transition 属性
a {
color: blue;
transition: all 2s;
}
a:hover {
color: red;
}
将在2秒内从蓝色淡化为红色
transition 有三个部分
transition: color 1s ease;
哪些CSS属性要进行动画; 持续时间; 时间函数
并非所有属性更改都可以进行动画
list-style-type: square;
CSS渲染器不知道如何为此制作动画.
但是有很多属性可以进行动画
如果它是一个数字或颜色, 它很可能可以进行动画! 比如:
font-size: 14px; rotate: 90deg; width: 20em;
媒体查询
媒体查询允许在不同的情况下使用不同的CSS
@media print {
#footer {
display: none;
}
}
媒体查询如何根据不同的媒介类型应用不同的CSS样式.
max-width 和 min-width
@media (max-width: 500px) {
/* 小屏幕的CSS */
}
@media (min-width: 950px) {
/* 大屏幕的CSS */
}
打印和屏幕
screen 用于计算机/移动屏幕; print 用于打印网页; 还有更多: tv, tty,
语音(speech), 盲文(braille)等等.
辅助功能查询
可以有时通过媒体查询找出用户的偏好; 示例:
prefers-reduced-motion: reduce, prefers-color-scheme: dark
可以组合媒体查询
@media screen and (max-width: 1024px)
写这样的东西很常见.
视口元标记
<meta name="viewport" content="width=device-width, initial-scale=1">
如果在HTML的 <head> 中没有添加这样的标签,
网站在移动设备上看起来会很糟糕.
现代浏览器的CSS检查器
所有主要的浏览器都有一个CSS检查器
通常可以通过右键单击一个元素然后"检查元素" 来打开.
查看被覆盖的属性
button { display: inline-block; color: var(–orange); }
编辑CSS属性
button {
display: inline-block;
border: 1px solid black;
}
这允许更改每个 <button> 的边框!
查看计算样式
这是一个包含12000行CSS的网站, 这个链接的字体大小是多少? 12px, 因为
x.css 第436行. (图示说明浏览器如何计算最终样式)
查看外边距和内边距
浏览器开发者工具查看盒子模型的外边距和内边距.
以及更多
不同的浏览器有不同的工具, Firefox有用于调试Grid/Flexbox的特殊工具.
检查清单
用不同的浏览器, 屏幕尺寸和辅助功能评估工具测试网站非常重要.
浏览器
- ☐ Chrome
- ☐ Safari
- ☐ Firefox
- ☐ 也许还有其他浏览器!
尺寸
- ☐ 小手机(300像素宽)
- ☐ 平板电脑(大约700像素)
- ☐ 桌面电脑(大约1200像素)
辅助功能
- ☐ 颜色对比度
- ☐ 文字大小
- ☐ 键盘导航
- ☐ 可与屏幕阅读器一起使用
性能
- ☐ 模拟慢速/高延迟网络连接!