本篇文章围绕了 CSS 的核心知识点和项目中常见的需求来展开。虽然行文偏长,但较基础,适合初级中级前端阅读,阅读的时候请适当跳过已经掌握的部分。css
这篇文章断断续续写了比较久,也参考了许多优秀的文章,但或许文章里仍是存在很差或不对的地方,请多多指教,能够评论里直接提出来哈。html
小tip:后续内容更精彩哦。前端
CSS 的核心功能是将 CSS 属性设定为特定的值。一个属性与值的键值对被称为声明(declaration)。git
color: red;
复制代码
而若是将一个或者多个声明用 {}
包裹起来后,那就组成了一个声明块(declaration block)。github
{
color: red;
text-align: center;
}
复制代码
声明块若是须要做用到对应的 HTML 元素,那还须要加上选择器。选择器和声明块组成了CSS 规则集(CSS ruleset),常简称为 CSS 规则。web
span {
color: red;
text-align: center;
}
复制代码
规则集中最后一条声明能够省略分号,可是并不建议这么作,由于容易出错。算法
CSS 中的注释:canvas
/* 单行注释 */
/* 多行 注释 */
复制代码
在 CSS 文件中,除了注释、CSS 规则集以及 @规则 外,定义的一些别的东西都将被浏览器忽略。segmentfault
CSS 规则是样式表的主体,一般样式表会包括大量的规则列表。但有时候也须要在样式表中包括其余的一些信息,好比字符集,导入其它的外部样式表,字体等,这些须要专门的语句表示。浏览器
而 @规则 就是这样的语句。CSS 里包含了如下 @规则:
除了以上这几个以外,下面还将对几个比较生涩的 @规则 进行介绍。
@charset 用于定义样式表使用的字符集。它必须是样式表中的第一个元素。若是有多个 @charset
被声明,只有第一个会被使用,并且不能在HTML元素或HTML页面的 <style>
元素内使用。
注意:值必须是双引号包裹,且和
@charset "UTF-8";
复制代码
平时写样式文件都没写 @charset 规则,那这个 CSS 文件究竟是用的什么字符编码的呢?
某个样式表文件到底用的是什么字符编码,浏览器有一套识别顺序(优先级由高到低):
文件开头的 Byte order mark 字符值,不过通常编辑器并不能看到文件头里的 BOM 值;
HTTP 响应头里的 content-type
字段包含的 charset
所指定的值,好比:
Content-Type: text/css; charset=utf-8
复制代码
CSS 文件头里定义的 @charset 规则里指定的字符编码;
<link>
标签里的 charset 属性,该条已在 HTML5 中废除;
默认是 UTF-8
。
@import 用于告诉 CSS 引擎引入一个外部样式表。
link 和 @import 都能导入一个样式文件,它们有什么区别嘛?
@supports 用于查询特定的 CSS 是否生效,能够结合 not、and 和 or 操做符进行后续的操做。
/* 若是支持自定义属性,则把 body 颜色设置为变量 varName 指定的颜色 */
@supports (--foo: green) {
body {
color: var(--varName);
}
}
复制代码
层叠样式表,这里的层叠怎么理解呢?其实它是 CSS 中的核心特性之一,用于合并来自多个源的属性值的算法。好比说针对某个 HTML 标签,有许多的 CSS 声明都能做用到的时候,那最后谁应该起做用呢?层叠性说的大概就是这个。
针对不一样源的样式,将按照以下的顺序进行层叠,越往下优先级越高:
理解层叠性的时候须要结合 CSS 选择器的优先级以及继承性来理解。好比针对同一个选择器,定义在后面的声明会覆盖前面的;做者定义的样式会比默认继承的样式优先级更高。
CSS 选择器无疑是其核心之一,对于基础选择器以及一些经常使用伪类必须掌握。下面列出了经常使用的选择器。 想要获取更多选择器的用法能够看 MDN CSS Selectors。
h1
.checked
#picker
*
属性选择器
[attr]
:指定属性的元素;[attr=val]
:属性等于指定值的元素;[attr*=val]
:属性包含指定值的元素;[attr^=val]
:属性以指定值开头的元素;[attr$=val]
:属性以指定值结尾的元素;[attr~=val]
:属性包含指定值(完整单词)的元素(不推荐使用);[attr|=val]
:属性以指定值(完整单词)开头的元素(不推荐使用);A + B
A ~ B
A > B
A B
条件伪类
:lang()
:基于元素语言来匹配页面元素;:dir()
:匹配特定文字书写方向的元素;:has()
:匹配包含指定元素的元素;:is()
:匹配指定选择器列表里的元素;:not()
:用来匹配不符合一组选择器的元素;行为伪类
:active
:鼠标激活的元素;:hover
: 鼠标悬浮的元素;::selection
:鼠标选中的元素;状态伪类
:target
:当前锚点的元素;:link
:未访问的连接元素;:visited
:已访问的连接元素;:focus
:输入聚焦的表单元素;:required
:输入必填的表单元素;:valid
:输入合法的表单元素;:invalid
:输入非法的表单元素;:in-range
:输入范围之内的表单元素;:out-of-range
:输入范围之外的表单元素;:checked
:选项选中的表单元素;:optional
:选项可选的表单元素;:enabled
:事件启用的表单元素;:disabled
:事件禁用的表单元素;:read-only
:只读的表单元素;:read-write
:可读可写的表单元素;:blank
:输入为空的表单元素;:current()
:浏览中的元素;:past()
:已浏览的元素;:future()
:未浏览的元素;结构伪类
:root
:文档的根元素;:empty
:无子元素的元素;:first-letter
:元素的首字母;:first-line
:元素的首行;:nth-child(n)
:元素中指定顺序索引的元素;:nth-last-child(n)
:元素中指定逆序索引的元素;;:first-child
:元素中为首的元素;:last-child
:元素中为尾的元素;:only-child
:父元素仅有该元素的元素;:nth-of-type(n)
:标签中指定顺序索引的标签;:nth-last-of-type(n)
:标签中指定逆序索引的标签;:first-of-type
:标签中为首的标签;:last-of-type
:标签中为尾标签;:only-of-type
:父元素仅有该标签的标签;::before
:在元素前插入内容;::after
:在元素后插入内容;优先级就是分配给指定的 CSS 声明的一个权重,它由匹配的选择器中的每一种选择器类型的数值决定。为了记忆,能够把权重分红以下几个等级,数值越大的权重越高:
能够看到内联样式(经过元素中 style 属性定义的样式)的优先级大于任何选择器;而给属性值加上 !important
又能够把优先级提至最高,就是由于它的优先级最高,因此须要谨慎使用它,如下有些使用注意事项:
在 CSS 中有一个很重要的特性就是子元素会继承父元素对应属性计算后的值。好比页面根元素 html 的文本颜色默认是黑色的,页面中的全部其余元素都将继承这个颜色,当申明了以下样式后,H1 文本将变成橙色。
body {
color: orange;
}
h1 {
color: inherit;
}
复制代码
设想一下,若是 CSS 中不存在继承性,那么咱们就须要为不一样文本的标签都设置一下 color,这样一来的后果就是 CSS 的文件大小就会无限增大。
CSS 属性不少,但并非全部的属性默认都是能继承父元素对应属性的,那哪些属性存在默认继承的行为呢?必定是那些不会影响到页面布局的属性,能够分为以下几类:
font-family
、font-style
、font-size
、font-weight
等;text-align
、text-indent
、text-decoration
、text-shadow
、letter-spacing
、word-spacing
、white-space
、line-height
、color
等;list-style
、list-style-image
、list-style-type
、list-style-position
等;visibility
、cursor
等;对于其余默认不继承的属性也能够经过如下几个属性值来控制继承行为:
inherit
:继承父元素对应属性的计算值;initial
:应用该属性的默认值,好比 color 的默认值是 #000
;unset
:若是属性是默承认以继承的,则取 inherit
的效果,不然同 initial
;revert
:效果等同于 unset
,兼容性差。在 CSS 的世界中,会把内容按照从左到右、从上到下的顺序进行排列显示。正常状况下会把页面分割成一行一行的显示,而每行又可能由多列组成,因此从视觉上看起来就是从上到下从左到右,而这就是 CSS 中的流式布局,又叫文档流。文档流就像水同样,可以自适应所在的容器,通常它有以下几个特性:
如何脱离文档流呢?
脱流文档流指节点脱流正常文档流后,在正常文档流中的其余节点将忽略该节点并填补其原先空间。文档一旦脱流,计算其父节点高度时不会将其高度归入,脱流节点不占据空间。有两种方式可让元素脱离文档流:浮动和定位。
position: absolute;
)或者固定定位(position: fixed;
)也会使得元素脱离文档流,且空出来的位置将自动被后续节点填补。在 CSS 中任何元素均可以当作是一个盒子,而一个盒子是由 4 部分组成的:内容(content)、内边距(padding)、边框(border)和外边距(margin)。
盒模型有 2 种:标准盒模型和 IE 盒模型,本别是由 W3C 和 IExplore 制定的标准。
若是给某个元素设置以下样式:
.box {
width: 200px;
height: 200px;
padding: 10px;
border: 1px solid #eee;
margin: 10px;
}
复制代码
标准盒模型认为:盒子的实际尺寸 = 内容(设置的宽/高) + 内边距 + 边框
因此 .box
元素内容的宽度就为 200px
,而实际的宽度则是 width
+ padding-left
+ padding-right
+ border-left-width
+ border-right-width
= 200 + 10 + 10 + 1 + 1 = 222。
IE 盒模型认为:盒子的实际尺寸 = 设置的宽/高 = 内容 + 内边距 + 边框
.box
元素所占用的实际宽度为 200px
,而内容的真实宽度则是 width
- padding-left
- padding-right
- border-left-width
- border-right-width
= 200 - 10 - 10 - 1 - 1 = 178。
如今高版本的浏览器基本上默认都是使用标准盒模型,而像 IE6 这种老古董才是默认使用 IE 盒模型的。
在 CSS3 中新增了一个属性 box-sizing
,容许开发者来指定盒子使用什么标准,它有 2 个值:
content-box
:标准盒模型;border-box
:IE 盒模型;视觉格式化模型(Visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。CSS 中一切皆盒子,而视觉格式化模型简单来理解就是规定这些盒子应该怎么样放置到页面中去,这个模型在计算的时候会依赖到不少的因素,好比:盒子尺寸、盒子类型、定位方案(是浮动仍是定位)、兄弟元素或者子元素以及一些别的因素。
从上图中能够看到视觉格式化模型涉及到的内容不少,有兴趣深刻研究的能够结合上图看这个 W3C 的文档 Visual formatting model。因此这里就简单介绍下盒子类型。
盒子类型由 display 决定,同时给一个元素设置 display 后,将会决定这个盒子的 2 个显示类型(display type):
对外显示方面,盒子类型能够分红 2 类:block-level box(块级盒子) 和 inline-level box(行内级盒子)。
依据上图能够列出都有哪些块级和行内级盒子:
全部块级盒子都会参与 BFC,呈现垂直排列;而全部行内级盒子都参会 IFC,呈现水平排列。
除此以外,block、inline 和 inline-block 还有什么更具体的区别呢?
block
inline
inline-block
对内方面,其实就是把元素当成了容器,里面包裹着文本或者其余子元素。container box 的类型依据 display 的值不一样,分为 4 种:
值得一提的是若是把 img 这种替换元素(replaced element)申明为 block 是不会产生 container box 的,由于替换元素好比 img 设计的初衷就仅仅是经过 src 把内容替换成图片,彻底没考虑过会把它当成容器。
参考:
格式化上下文(Formatting Context)是 CSS2.1 规范中的一个概念,大概说的是页面中的一块渲染区域,规定了渲染区域内部的子元素是如何排版以及相互做用的。
不一样类型的盒子有不一样格式化上下文,大概有这 4 类:
其中 BFC 和 IFC 在 CSS 中扮演着很是重要的角色,由于它们直接影响了网页布局,因此须要深刻理解其原理。
块格式化上下文,它是一个独立的渲染区域,只有块级盒子参与,它规定了内部的块级盒子如何布局,而且与这个区域外部绝不相干。
BFC 渲染规则
如何建立 BFC?
BFC 应用场景
一、 自适应两栏布局
应用原理:BFC 的区域不会和浮动区域重叠,因此就能够把侧边栏固定宽度且左浮动,而对右侧内容触发 BFC,使得它的宽度自适应该行剩余宽度。
<div class="layout">
<div class="aside">aside</div>
<div class="main">main</div>
</div>
复制代码
.aside {
float: left;
width: 100px;
}
.main {
<!-- 触发 BFC -->
overflow: auto;
}
复制代码
二、清除内部浮动
浮动形成的问题就是父元素高度坍塌,因此清除浮动须要解决的问题就是让父元素的高度恢复正常。而用 BFC 清除浮动的原理就是:计算 BFC 的高度时,浮动元素也参与计算。只要触发父元素的 BFC 便可。
.parent {
overflow: hidden;
}
复制代码
三、 防止垂直 margin 合并
BFC 渲染原理之一:同一个 BFC 下的垂直 margin 会发生合并。因此若是让 2 个元素不在同一个 BFC 中便可阻止垂直 margin 合并。那如何让 2 个相邻的兄弟元素不在同一个 BFC 中呢?能够给其中一个元素外面包裹一层,而后触发其包裹层的 BFC,这样一来 2 个元素就不会在同一个 BFC 中了。
<div class="layout">
<div class="a">a</div>
<div class="contain-b">
<div class="b">b</div>
</div>
</div>
复制代码
.demo3 .a,
.demo3 .b {
border: 1px solid #999;
margin: 10px;
}
.contain-b {
overflow: hidden;
}
复制代码
针对以上 3 个 示例 ,能够结合这个 BFC 应用示例 配合观看更佳。
参考:CSS 原理 - Formatting Context
IFC 的造成条件很是简单,块级元素中仅包含内联级别元素,须要注意的是当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个 IFC。
IFC 渲染规则
针对如上的 IFC 渲染规则,你是否是能够分析下下面这段代码的 IFC 环境是怎么样的呢?
<p>It can get <strong>very complicated</storng> once you start looking into it.</p>
复制代码
对应上面这样一串 HTML 分析以下:
IFC 应用场景
偷个懒,demo 和图我就不作了。
在电脑显示屏幕上的显示的页面实际上是一个三维的空间,水平方向是 X 轴,竖直方向是 Y 轴,而屏幕到眼睛的方向能够当作是 Z 轴。众 HTML 元素依据本身定义的属性的优先级在 Z 轴上按照必定的顺序排开,而这其实就是层叠上下文所要描述的东西。
咱们对层叠上下文的第一印象可能要来源于 z-index,认为它的值越大,距离屏幕观察者就越近,那么层叠等级就越高,事实确实是这样的,但层叠上下文的内容远非仅仅如此:
在看层叠等级和层叠顺序以前,咱们先来看下如何产生一个层叠上下文,特定的 HTML 元素或者 CSS 属性产生层叠上下文,MDN 中给出了这么一个列表,符合如下任一条件的元素都会产生层叠上下文:
层叠等级
层叠等级指节点在三维空间 Z 轴上的上下顺序。它分两种状况:
普通节点的层叠等级优先由其所在的层叠上下文决定,层叠等级的比较只有在当前层叠上下文中才有意义,脱离当前层叠上下文的比较就变得无心义了。
层叠顺序
在同一个层叠上下文中若是有多个元素,那么他们之间的层叠顺序是怎么样的呢?
如下这个列表越往下层叠优先级越高,视觉上的效果就是越容易被用户看到(不会被其余元素覆盖):
如何比较两个元素的层叠等级?
参考:完全搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index
CSS 的声明是由属性和值组成的,而值的类型有许多种:
而还有些值是须要带单位的,好比 width: 100px,这里的 px 就是表示长度的单位,长度单位除了 px 外,比较经常使用的还有 em、rem、vw/vh 等。那他们有什么区别呢?又应该在何时使用它们呢?
屏幕分辨率是指在屏幕的横纵方向上的像素点数量,好比分辨率 1920×1080 意味着水平方向含有 1920 个像素数,垂直方向含有 1080 个像素数。
而 px 表示的是 CSS 中的像素,在 CSS 中它是绝对的长度单位,也是最基础的单位,其余长度单位会自动被浏览器换算成 px。可是对于设备而言,它其实又是相对的长度单位,好比宽高都为 2px,在正常的屏幕下,其实就是 4 个像素点,而在设备像素比(devicePixelRatio) 为 2 的 Retina 屏幕下,它就有 16 个像素点。因此屏幕尺寸一致的状况下,屏幕分辨率越高,显示效果就越细腻。
讲到这里,还有一些相关的概念须要理清下:
设备像素(Device pixels)
设备屏幕的物理像素,表示的是屏幕的横纵有多少像素点;和屏幕分辨率是差很少的意思。
设备像素比(DPR)
设备像素比表示 1 个 CSS 像素等于几个物理像素。
计算公式:DPR = 物理像素数 / 逻辑像素数;
在浏览器中能够经过 window.devicePixelRatio 来获取当前屏幕的 DPR。
像素密度(DPI/PPI)
像素密度也叫显示密度或者屏幕密度,缩写为 DPI(Dots Per Inch) 或者 PPI(Pixel Per Inch)。从技术角度说,PPI 只存在于计算机显示领域,而 DPI 只出现于打印或印刷领域。
计算公式:像素密度 = 屏幕对角线的像素尺寸 / 物理尺寸
好比,对于分辨率为 750 * 1334 的 iPhone 6 来讲,它的像素密度为:
Math.sqrt(750 * 750 + 1334 * 1334) / 4.7 = 326ppi
复制代码
设备独立像素(DIP)
DIP 是特别针对 Android设备而衍生出来的,缘由是安卓屏幕的尺寸繁多,所以为了显示能尽可能和设备无关,而提出的这个概念。它是基于屏幕密度而计算的,认为当屏幕密度是 160 的时候,px = DIP。
计算公式:dip = px * 160 / dpi
em 是 CSS 中的相对长度单位中的一个。竟然是相对的,那它究竟是相对的谁呢?它有 2 层意思:
咱们都知道每一个浏览器都会给 HTML 根元素 html 设置一个默认的 font-size,而这个值一般是 16px。这也就是为何 1em = 16px 的缘由所在了。
em 在计算的时候是会层层计算的,好比:
<div>
<p></p>
</div>
复制代码
div { font-size: 2em; }
p { font-size: 2em; }
复制代码
对于如上一个结构的 HTML,因为根元素 html 的字体大小是 16px,因此 p 标签最终计算出来后的字体大小会是 16 * 2 * 2 = 64px
rem(root em) 和 em 同样,也是一个相对长度单位,不过 rem 相对的是 HTML 的根元素 html。
rem 因为是基于 html 的 font-size 来计算,因此一般用于自适应网站或者 H5 中。
好比在作 H5 的时候,前端一般会让 UI 给 750px 宽的设计图,而在开发的时候能够基于 iPhone X 的尺寸 375px * 812px 来写页面,这样一来的话,就能够用下面的 JS 依据当前页面的视口宽度自动计算出根元素 html 的基准 font-size 是多少。
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
psdWidth = 750, // 设计图宽度
recalc = function () {
var clientWidth = docEl.clientWidth;
if ( !clientWidth ) return;
if ( clientWidth >= 640 ) {
docEl.style.fontSize = 200 * ( 640 / psdWidth ) + 'px';
} else {
docEl.style.fontSize = 200 * ( clientWidth / psdWidth ) + 'px';
}
};
if ( !doc.addEventListener ) return;
// 绑定事件的时候最好配合防抖函数
win.addEventListener( resizeEvt, debounce(recalc, 1000), false );
doc.addEventListener( 'DOMContentLoaded', recalc, false );
function debounce(func, wait) {
var timeout;
return function () {
var context = this;
var args = arguments;
clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
})(document, window);
复制代码
好比当视口是 375px 的时候,通过计算 html 的 font-size 会是 100px,这样有什么好处呢?好处就是方便写样式,好比从设计图量出来的 header 高度是 50px 的,那咱们写样式的时候就能够直接写:
header {
height: 0.5rem;
}
复制代码
每一个从设计图量出来的尺寸只要除于 100 便可获得当前元素的 rem 值,都不用通过计算,很是方便。偷偷告诉你,若是你把上面那串计算 html 标签 font-size 的 JS 代码中的 200 替换成 2,那在计算 rem 的时候就不须要除于 100 了,从设计图量出多大 px,就直接写多少个 rem。
vw 和 vh 分别是相对于屏幕视口宽度和高度而言的长度单位:
在 JS 中 100vw = window.innerWidth,100vh = window.innerHeight。
vw/vh 的出现使得多了一种写自适应布局的方案,开发者再也不局限于 rem 了。
相对视口的单位,除了 vw/vh 外,还有 vmin 和 vmax:
CSS 中用于表示颜色的值种类繁多,足够构成一个体系,因此这里就专门拿出一个小节来说解它。
根据 CSS 颜色草案 中提到的颜色值类型,大概能够把它们分为这几类:
颜色关键字(color keywords)是不区分大小写的标识符,它表示一个具体的颜色,好比 white(白),黑(black)等;
可接受的关键字列表在CSS的演变过程当中发生了改变:
以下这张图是 16 个基础色,又叫 VGA 颜色。截止到目前为止 CSS 颜色关键字总共有 146 个,这里能够查看 完整的色彩关键字列表。
须要注意的是若是声明的时候的颜色关键字是错误的,浏览器会忽略它。
transparent 关键字表示一个彻底透明的颜色,即该颜色看上去将是背景色。从技术上说,它是带有 alpha 通道为最小值的黑色,是 rgba(0,0,0,0) 的简写。
透明关键字有什么应用场景呢?
实现三角形
下面这个图是用 4 条边框填充的正方形,看懂了它你大概就知道该如何用 CSS 写三角形了。
div {
border-top-color: #ffc107;
border-right-color: #00bcd4;
border-bottom-color: #e26b6b;
border-left-color: #cc7cda;
border-width: 50px;
border-style: solid;
}
复制代码
用 transparent 实现三角形的原理:
看下示例:
增大点击区域
经常在移动端的时候点击的按钮的区域特别小,可是因为现实效果又不太好把它作大,因此经常使用的一个手段就是经过透明的边框来增大按钮的点击区域:
.btn {
border: 5px solid transparent;
}
复制代码
currentColor 会取当前元素继承父级元素的文本颜色值或声明的文本颜色值,即 computed 后的 color 值。
好比,对于以下 CSS,该元素的边框颜色会是 red:
.btn {
color: red;
border: 1px solid currentColor;
}
复制代码
RGB[A] 颜色是由 R(red)-G(green)-B(blue)-A(alpha) 组成的色彩空间。
在 CSS 中,它有两种表示形式:
十六进制符号
RGB 中的每种颜色的值范围是 00~ff,值越大表示颜色越深。因此一个颜色正常是 6 个十六进制字符加上 # 组成,好比红色就是 #ff0000。
若是 RGB 颜色须要加上不透明度,那就须要加上 alpha 通道的值,它的范围也是 00~ff,好比一个带不透明度为 67% 的红色能够这样写 #ff0000aa。
使用十六进制符号表示颜色的时候,都是用 2 个十六进制表示一个颜色,若是这 2 个字符相同,还能够缩减成只写 1 个,好比,红色 #f00;带 67% 不透明度的红色 #f00a。
函数符
当 RGB 用函数表示的时候,每一个值的范围是 0~255 或者 0%~100%,因此红色是 rgb(255, 0, 0), 或者 rgb(100%, 0, 0)。
若是须要使用函数来表示带不透明度的颜色值,值的范围是 0~1 及其之间的小数或者 0%~100%,好比带 67% 不透明度的红色是 rgba(255, 0, 0, 0.67) 或者 rgba(100%, 0%, 0%, 67%)
须要注意的是 RGB 这 3 个颜色值须要保持一致的写法,要嘛用数字要嘛用百分比,而不透明度的值的能够不用和 RGB 保持一致写法。好比 rgb(100%, 0, 0) 这个写法是无效的;而 rgb(100%, 0%, 0%, 0.67) 是有效的。
在第 4 代 CSS 颜色标准中,新增了一种新的函数写法,便可以把 RGB 中值的分隔逗号改为空格,而把 RGB 和 alpha 中的逗号改为 /,好比带 67% 不透明度的红色能够这样写 rgba(255 0 0 / 0.67)。另外还把 rgba 的写法合并到 rgb 函数中了,即 rgb 能够直接写带不透明度的颜色。
HSL[A] 颜色是由色相(hue)-饱和度(saturation)-亮度(lightness)-不透明度组成的颜色体系。
写法上能够参考 RGB 的写法,只是参数的值不同。
给一个按钮设置不透明度为 67% 的红色的 color 的写法,如下所有写法效果一致:
button {
color: #ff0000aa;
color: #f00a;
color: rgba(255, 0, 0, 0.67);
color: rgb(100% 0% 0% / 67%);
color: hsla(0, 100%, 50%, 67%);
color: hsl(0deg 100% 50% / 67%);
}
复制代码
小提示:在 Chrome DevTools 中能够按住 shift + 鼠标左键能够切换颜色的表示方式。
媒体查询是指针对不一样的设备、特定的设备特征或者参数进行定制化的修改网站的样式。
你能够经过给 <link>
加上 media 属性来指定该样式文件只能对什么设备生效,不指定的话默认是 all,即对全部设备都生效:
<link rel="stylesheet" src="styles.css" media="screen" />
<link rel="stylesheet" src="styles.css" media="print" />
复制代码
都支持哪些设备类型?
须要注意的是:经过 media 指定的 资源尽管不匹配它的设备类型,可是浏览器依然会加载它。
除了经过 <link>
让指定设备生效外,还能够经过 @media
让 CSS 规则在特定的条件下才能生效。响应式页面就是使用了 @media 才让一个页面可以同时适配 PC、Pad 和手机端。
@media (min-width: 1000px) {}
复制代码
媒体查询支持逻辑操做符:
媒体查询还支持众多的媒体特性,使得它能够写出很复杂的查询条件:
/* 用户设备的最小高度为680px或为纵向模式的屏幕设备 */
@media (min-height: 680px), screen and (orientation: portrait) {}
复制代码
以前咱们一般是在预处理器里才可使用变量,而如今 CSS 里也支持了变量的用法。经过自定义属性就能够在想要使用的地方引用它。
自定义属性也和普通属性同样具备级联性,申明在 :root 下的时候,在全文档范围内可用,而若是是在某个元素下申明自定义属性,则只能在它及它的子元素下才可使用。
自定义属性必须经过 --x
的格式申明,好比:--theme-color: red; 使用自定义属性的时候,须要用 var 函数。好比:
<!-- 定义自定义属性 -->
:root {
--theme-color: red;
}
<!-- 使用变量 -->
h1 {
color: var(--theme-color);
}
复制代码
上图这个是使用 CSS 自定义属性配合 JS 实现的动态调整元素的 box-shadow,具体能够看这个 codepen demo。
Retina 显示屏比普通的屏幕有着更高的分辨率,因此在移动端的 1px 边框就会看起来比较粗,为了美观一般须要把这个线条细化处理。这里有篇文章列举了 7 中方案能够参考一下:7种方法解决移动端Retina屏幕1px边框问题
而这里附上最后一种经过伪类和 transform 实现的相对完美的解决方案:
只设置单条底部边框:
.scale-1px-bottom {
position: relative;
border:none;
}
.scale-1px-bottom::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
复制代码
同时设置 4 条边框:
.scale-1px {
position: relative;
margin-bottom: 20px;
border:none;
}
.scale-1px::after {
content: '';
position: absolute;
top: 0;
left: 0;
border: 1px solid #000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}
复制代码
什么是浮动:浮动元素会脱离文档流并向左/向右浮动,直到碰到父元素或者另外一个浮动元素。
为何要清楚浮动,它形成了什么问题?
由于浮动元素会脱离正常的文档流,并不会占据文档流的位置,因此若是一个父元素下面都是浮动元素,那么这个父元素就没法被浮动元素所撑开,这样一来父元素就丢失了高度,这就是所谓的浮动形成的父元素高度坍塌问题。
父元素高度一旦坍塌将对后面的元素布局形成影响,为了解决这个问题,因此须要清除浮动,让父元素恢复高度,那该如何作呢?
这里介绍两种方法:经过 BFC 来清除、经过 clear 来清除。
前面介绍 BFC 的时候提到过,计算 BFC 高度的时候浮动子元素的高度也将计算在内,利用这条规则就能够清楚浮动。
假设一个父元素 parent 内部只有 2 个子元素 child,且它们都是左浮动的,这个时候 parent 若是没有设置高度的话,由于浮动形成了高度坍塌,因此 parent 的高度会是 0,此时只要给 parent 创造一个 BFC,那它的高度就能恢复了。
而产生 BFC 的方式不少,咱们能够给父元素设置overflow: auto 来简单的实现 BFC 清除浮动,可是为了兼容 IE 最好用 overflow: hidden。
.parent {
overflow: hidden;
}
复制代码
经过 overflow: hidden 来清除浮动并不完美,当元素有阴影或存在下拉菜单的时候会被截断,因此该方法使用比较局限。
我先把结论贴出来:
.clearfix {
zoom: 1;
}
.clearfix::after {
content: "";
display: block;
clear: both;
}
复制代码
这种写法的核心原理就是经过 ::after 伪元素为在父元素的最后一个子元素后面生成一个内容为空的块级元素,而后经过 clear 将这个伪元素移动到全部它以前的浮动元素的后面,画个图来理解一下。
能够结合这个 codepen demo 一块儿理解上图的 clear 清楚浮动原理。
上面这个 demo 或者图里为了展现须要因此给伪元素的内容设置为了 ::after,实际使用的时候须要设置为空字符串,让它的高度为 0,从而父元素的高度都是由实际的子元素撑开。
该方式基本上是如今人人都在用的清除浮动的方案,很是通用。
针对同一个类型的 HTML 标签,不一样的浏览器每每有不一样的表现,因此在网站制做的时候,开发者一般都是须要将这些浏览器的默认样式清除,让网页在不一样的浏览器上可以保持一致。
针对清除浏览器默认样式这件事,在很早以前 CSS 大师 Eric A. Meyer 就干过。它就是写一堆通用的样式用来重置浏览器默认样式,这些样式一般会放到一个命名为 reset.css 文件中。好比大师的 reset.css 是这么写的:
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
复制代码
他的这份 reset.css 听说是被使用最普遍的重设样式的方案了。
除了 reset.css 外,后来又出现了 Normalize.css 。关于 Normalize.css, 其做者 necolas 专门写了一篇文章介绍了它,并谈到了它和 reset.css 的区别。这个是他写那篇文章的翻译版:让咱们谈一谈 Normalize.css。
文章介绍到:Normalize.css 只是一个很小的CSS文件,但它在默认的 HTML 元素样式上提供了跨浏览器的高度一致性。相比于传统的 CSS reset,Normalize.css 是一种现代的、为 HTML5 准备的优质替代方案,如今已经有不少知名的框架和网站在使用它了。
Normalize.css 的具体样式能够看这里 Normalize.css
区别于 reset.css,Normalize.css 有以下特色:
默认:字符太长溢出了容器
字符超出部分换行
字符超出位置使用连字符
单行文本超出省略
多行文本超出省略
查看以上这些方案的示例: codepen demo
有意思的是恰好前两天看到 chokcoco 针对文本溢出也写了一篇文章,主要突出的是对整块的文本溢出处理。啥叫整块文本?好比,下面这种技术标签就是属于整块文本:
另外他还对 iOS/Safari 作了兼容处理,感兴趣的能够去阅读下:CSS 整块文本溢出省略特性探究。
让元素在父元素中呈现出水平垂直居中的形态,无非就 2 种状况:
如下列到的全部水平垂直居中方案这里写了个 codepen demo,配合示例阅读效果更佳。
水平居中
此类元素须要水平居中,则父级元素必须是块级元素(block level
),且父级元素上须要这样设置样式:
.parent {
text-align: center;
}
复制代码
垂直居中
方法一:经过设置上下内间距一致达到垂直居中的效果:
.single-line {
padding-top: 10px;
padding-bottom: 10px;
}
复制代码
方法二:经过设置 height
和 line-height
一致达到垂直居中:
.single-line {
height: 100px;
line-height: 100px;
}
复制代码
方法一:absolute + 负 margin
方法二:absolute + margin auto
方法三:absolute + calc
这里列了 6 种方法,参考了颜海镜 写的文章 ,其中的两种 line-height 和 writing-mode 方案看后让我惊呼:还有这种操做?学到了学到了。
方法一:absolute + transform
方法二:line-height + vertical-align
方法三:writing-mode
方法四:table-cell
方法五:flex
方法六:grid
针对如下这些方案写了几个示例: codepen demo
方法一:float + overflow(BFC 原理)
方法二:float + margin
方法三:flex
方法四:grid
针对如下这些方案写了几个示例: codepen demo
方法一:圣杯布局
方法二:双飞翼布局
方法三:float + overflow(BFC 原理)
方法四:flex
方法五:grid
结合示例阅读更佳:codepen demo
方法一:padding + 负margin
方法二:设置父级背景图片
列了 4 种方法,都是基于以下的 HTML 和 CSS 的,结合示例阅读效果更佳:codepen demo
<div class="layout">
<header></header>
<main>
<div class="inner"></div>
</main>
<footer></footer>
</div>
复制代码
html,
body,
.layout {
height: 100%;
}
body {
margin: 0;
}
header,
footer {
height: 50px;
}
main {
overflow-y: auto;
}
复制代码
方法一:calc
方法二:absolute
方法三:flex
方法四:grid
这是我断断续续写了 2 周完成的文章,算是本身对 CSS 的一个总结,虽然写得很长,但不足以覆盖全部 CSS 的知识,好比动画和一些 CSS3 的新特性就彻底没涉及,由于这要写下来估计得有大几万字(其实就是懒 😝 )。
码字做图不易,若是喜欢或者对你有丝毫帮助的话,帮忙点个👍 哈,点赞就是个人动力。同时也但愿本身能坚持认真的写下去,由于在总结提高本身的同时若是也能帮助更多的前端er,那将会让我感受很开心。