CSS (Cascading Style Sheets) 其实并不是编程语言,CSS可以直接运行在浏览器中,浏览器就是它们的运行环境,CSS 中文名为层叠样式表,也就是一些样式的配置。
什么是 CSS?
- CSS 指层叠样式表 ( Cascading Style Sheets )
- 样式定义如何显示 HTML 元素
- 样式通常存储在样式表中
- 把样式添加到 HTML 4.0 中,是为了解决内容与表现分离的问题
- 外部样式表可以极大提高工作效率
- 外部样式表通常存储在 CSS 文件中
- 多个样式定义可层叠为一
- 样式对网页中元素位置的排版进行像素级精确控制
本文并没有详细介绍每个知识点,因为官方的文档介绍的更好,建议前往学习(https://www.w3cschool.cn/css/index.html),本文主要记录一些重点内容和细节。
基础概念
选择器
要在 HTML 元素中设置 CSS 样式,你需要在元素中设置 "id" 和 "class" 选择器,CSS 中 id 选择器以 #
来定义
class 选择器用于描述一组元素的样式,class 选择器有别于 id 选择器,class 可以在多个元素中使用。
class 选择器在 HTML 中以 class 属性表示, 在 CSS 中,类选择器以一个点".
"号显示
ID 属性不要以数字开头,数字开头的 ID 在 Mozilla/Firefox 浏览器中不起作用
第三种选择器为标签选择器,即以 HTML 标签作为 CSS 修饰所用的选择器
第四种内联选择器即直接在标签内部写 CSS 代码。
这四种 CS 选择器有修饰上的优先级,即:
内联选择器 > id选择器 > 类选择器 > 标签选择器
如果某些属性在不同的样式表中被同样的选择器定义,那么属性值将从更具体的样式表中被继承过来。即某些属性相同,按照优先级选择对应的样式表的属性。
当 !important 规则被应用在一个样式声明中时,该样式声明会覆盖 CSS 中任何其他的声明,无论它处在声明列表中的哪里。尽管如此,!important 规则还是与优先级毫无关系。使用 !important 不是一个好习惯,因为它改变了你样式表本来的级联规则,从而使其难以调试。
一些经验法则:
- Always 要优化考虑使用样式规则的优先级来解决问题而不是 !important
- Only 只在需要覆盖全站或外部 css(例如引用的 ExtJs 或者 YUI )的特定页面中使用 !important
- Never 永远不要在全站范围的 CSS 上使用 !important
- Never 永远不要在你的插件中使用 !important
CSS 优先级法则:
- 选择器都有一个权值,权值越大越优先;
- 当权值相等时,后出现的样式表设置要优于先出现的样式表设置;
- 创作者的规则高于浏览者:即网页编写者设置的 CSS 样式的优先权高于浏览器所设置的样式;
- 继承的 CSS 样式不如后来指定的 CSS 样式;
- 在同一组属性设置中标有 "!important" 规则的优先级最大;
样式声明方式:
- 点 .a.b
获取同时含有a和b的元素
- 空格(也叫做选择器嵌套)
A B 表示选择A元素的所有后代B元素
- 大于符号 >
A>B 表示选择A元素的所有亲儿子后代B元素 ,不会选中孙级的后代B元素
- 逗号 ,
同级(兄弟)的样式
- 加号
这个 也是同级,但与,有点区别,它是相邻兄弟选择器,即元素之间必须相邻,比如A B,B必须紧随着A,在A前面也不行,并且只会改变B的样式
属性选择器
CSS 属性选择器就是指可以根据元素的属性以及属性值来选择元素。
把包含标题(title)的所有元素变为蓝色:
[title] { color:blue; }
改变了标题 title='test'
元素的边框样式:
[title=test] { border:5px solid green; }
下面是包含指定值的 title
属性的元素样式的例子,使用(~
)分隔属性和值,模糊匹配:
[title~=hello] { color:blue; }
下面是包含指定值的 lang
属性的元素样式的例子,使用(|
)分隔属性和值:
[lang|=en] { color:blue; }
<h2>适用于:</h2> <p lang="en">你好!</p> <p lang="en-us">嗨!</p> <p lang="en-gb">小明!</p>
表单样式
input[type="text"] {...}
input[type="button"] {...}
组合选择符
CSS组合选择符包括各种简单选择符的组合方式。
在 CSS3 中包含了四种组合方式:
- 后代选取器(以空格分隔)
- 子元素选择器(以大于号分隔)
- 相邻兄弟选择器(以加号分隔)
- 普通兄弟选择器(以波浪号分隔)
后代选取器
后代选取器匹配所有指定元素的后代元素。
以下实例选取所有 <p> 元素插入到 <div> 元素中:
div p { background-color:yellow; }
子元素选择器
与后代选择器相比,子元素选择器(Child selectors)只能选择作为某元素子元素的元素。
以下实例选择了<div>元素中所有直接子元素 <p> :
div>p { background-color:yellow; }
相邻兄弟选择器
相邻兄弟选择器(Adjacent sibling selector)可选择紧接在另一元素后的元素,且二者有相同父元素。
如果需要选择紧接在另一个元素后的元素,而且二者有相同的父元素,可以使用相邻兄弟选择器(Adjacent sibling selector)。
以下实例选取了所有位于 <div> 元素后的第一个 <p> 元素:
div p { background-color:yellow; }
普通相邻兄弟选择器
普通兄弟选择器选取所有指定元素的相邻兄弟元素。
以下实例选取了所有 <div> 元素之后的所有相邻兄弟元素 <p> :
div~p { background-color:yellow; }
字体大小
用em来设置字体大小
为了避免 Internet Explorer 中无法调整文本的问题,许多开发者使用 em 单位代替像素。
em 的尺寸单位由W3C建议。
1em 和当前字体大小相等。在浏览器中默认的文字大小是16px。
因此,1em的默认大小是16px。可以通过下面这个公式将像素转换为em:px/16=em
(注:16 等于父元素的默认字体大小,假设父元素的 font-size 为 30px,那么公式需改为:pixels/30=em)
链接样式
链接的样式,可以用任何 CSS 属性(如颜色,字体,背景等)。
特别的链接,可以有不同的样式,这取决于他们是什么状态。
这四个链接状态是:
a:link
- 正常,未访问过的链接a:visited
- 用户已访问过的链接a:hover
- 当用户鼠标放在链接上时a:active
- 链接被点击的那一刻
a:link {color:#FF0000;} /* 未访问链接*/ a:visited {color:#00FF00;} /* visited link */ a:hover {color:#FF00FF;} /* mouse over link */ a:active {color:#0000FF;} /* selected link */
当设置为若干链路状态的样式,也有一些顺序规则:
a:hover
必须跟在a:link
和a:visited
后面a:active
必须跟在a:hover
后面
a{ display:block; width:60px; },display:block
- 显示块元素的链接,让整体变为可点击链接区域(不只是文本),它允许我们指定宽度。
伪类
CSS 伪类是用来添加一些选择器的特殊效果。由于状态的变化是非静态的,所以元素达到一个特定状态时,它可能得到一个伪类的样式;当状态改变时,它又会失去这个样式。由此可以看出,它的功能和 class 有些类似,但它是基于文档之外的抽象,所以叫伪类。
伪类的语法:
selector:pseudo-class {property:value;}
CSS 类也可以使用伪类:
selector.class:pseudo-class {property:value;},如a.red:visited {color:#FF0000;}
:first-child
可以使用 :first-child 伪类来选择元素的第一个子元素
在下面的例子中,选择器匹配所有作为元素的第一个子元素的 <p> 元素中的所有 <i> 元素
<style> p:first-child i { color:blue; } </style> </head> <body> <p>我是一个 <i>强壮</i> 的男人. 我是一个 <i>强壮</i> 的男人.</p> <p>我是一个 <i>强壮</i> 的男人. 我是一个 <i>强壮</i> 的男人.</p> </body>
:lang
:lang 伪类使你有能力为不同的语言定义特殊的规则
注意:IE8 必须声明 <!DOCTYPE> 才能支持; lang 伪类。
在下面的例子中,:lang 类为属性值为 no 的 q 元素定义引号的类型:
<style> q:lang(no) {quotes: "~" "~";} </style> </head> <body> <p>一些文字 <q lang="no">段落中的引用</q> 一些文字。</p> </body>
效果:
伪元素
CSS 伪元素是用来添加一些选择器的特殊效果。CSS 伪元素控制的内容和元素是没有差别的,但是它本身只是基于元素的抽象,并不存在于文档中,所以称为伪元素。
在CSS1和CSS2中,伪元素和伪类都采用单冒号进行表示,在CSS3中为了区分伪元素和伪类,规定使用双冒号代表伪元素,单冒号代表伪类,即CSS3标准中应该这么写:selector.class::pseudo-element {property:value;}
:first-line 伪元素
"first-line" 伪元素用于向文本的首行设置特殊样式。
在下面的例子中,浏览器会根据 "first-line" 伪元素中的样式对 p 元素的第一行文本进行格式化:
p:first-line { color:#ff0000; font-variant:small-caps; }
注意:"first-line" 伪元素只能用于块级元素。下面的属性可应用于 "first-line" 伪元素:
- font properties
- color properties
- background properties
- word-spacing
- letter-spacing
- text-decoration
- vertical-align
- text-transform
- line-height
- clear
:first-letter
"first-letter" 伪元素用于向文本的首字母设置特殊样式,"first-letter" 伪元素只能用于块级元素。
举例:p.article:first-letter {color:#ff0000;} 会使所有 class 为 article 的段落的首字母变为红色。
:before和:after
before和after都是类似的效果,此处仅介绍before
:before 选择器向选定的元素前插入内容。
:before是伪元素,并且它生成包含放置在元素中的内容之前的生成内容的伪元素。
使用content 属性来指定要插入的内容。
默认情况下,生成的伪元素是内联的,但这可以使用属性显示更改。
在每个<p>之前插入的内容和样式: p:before { content:"Read this -"; background-color:yellow; color:red; font-weight:bold; }
盒子模型
CSS 盒模型本质上是一个盒子,封装周围的 HTML 元素,它包括:边距,边框,填充,和实际内容。
不同部分的说明:
- Margin(外边距) - 清除边框区域。Margin 没有背景颜色,它是完全透明
- Border(边框) - 边框周围的填充和内容。边框是受到盒子的背景颜色影响
- Padding(内边距) - 清除内容周围的区域。会受到框中填充的背景颜色影响
- Content(内容) - 盒子的内容,显示文本和图像
在盒模型中,外边距可以是负值,而且在很多情况下都要使用负值的外边距。
margin和Padding可以定义一个使用百分比的边距,属性的百分比数值是相对于其父元素的 width 计算的,如果改变了父元素的 width,则它们也会改变。后面可以跟4个属性值,即上右下左,若跟2个属性值,即上下和右左,若1个属性值,则是所有方向。
样式分组和嵌套
在样式表中有很多具有相同样式的元素。
h1{ color:green; } h2{ color:green; }
为了尽量减少代码,你可以使用分组选择器。
每个选择器用逗号分隔.
在下面的例子中,我们对以上代码使用分组选择器:
h1,h2{ color:green; }
嵌套选择器
它可能适用于选择器内部的选择器的样式。
在下面的例子,为所有 p 元素指定一个样式,为所有元素指定一个 class="marked"的样式,并仅用于class="标记",类内的 p 元素指定第三个样式:
p{ color:blue; text-align:center; } .marked{ background-color:red; } .marked p{ color:white; }
元素显示和隐藏
SS display 属性和 visibility 属性都可以用来隐藏某个元素
display 属性设置一个元素应如何显示,visibility 属性指定一个元素应可见还是隐藏。
隐藏一个元素可以通过把 display 属性设置为"none",或把 visibility 属性设置为"hidden"。但是请注意,这两种方法会产生不同的结果。
visibility:hidden 可以隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间。也就是说,该元素虽然被隐藏了,但仍然会影响布局。
display:none 可以隐藏某个元素,且隐藏的元素不会占用任何空间。也就是说,该元素不但被隐藏了,而且该元素原本占用的空间也会从页面布局中消失。
可以更改内联元素为块元素,反之亦然,可以使页面看起来是以一种特定的方式组合,并仍然遵循 web 标准。
下面的示例把列表项显示为内联元素:li {display:inline;}
下面的示例把 span 元素作为块元素:span {display:block;}
变更元素的显示类型看该元素是如何显示,它是什么样的元素。例如:一个内联元素设置为 display:block 是不允许有它内部的嵌套块元素。
设置了inline-block属性的元素既拥有了block元素可以设置width和height的特性,又保持了inline元素不换行的特性。
position定位
Static 定位
HTML 元素的默认值,即没有定位,元素出现在正常的流中。
静态定位的元素不会受到 top, bottom, left, right 影响。
Fixed 定位
元素的位置相对于浏览器窗口是固定位置。
即使窗口是滚动的它也不会移动:
p.pos_fixed { position:fixed; top:30px; right:5px; }
注意: Fixed 定位在 IE7 和 IE8 下需要描述 !DOCTYPE 才能支持.
Fixed 定位使元素的位置与文档流无关,因此不占据空间。Fixed 定位的元素和其他元素重叠。
Relative 定位
相对定位元素的定位是相对其正常位置。h2.pos_left { position:relative; left:-20px; }
可以移动的相对定位元素的内容和相互重叠的元素,它原本所占的空间不会改变。即使相对定位元素的内容是移动,预留空间的元素仍保存在正常流动。
相对定位元素经常被用来作为绝对定位元素的容器块。
Absolute 定位
绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于 <html>:
h2 { position:absolute; left:100px; top:150px; }
Absolutely 定位使元素的位置与文档流无关,因此不占据空间。Absolutely 定位的元素和其他元素重叠。用绝对定位,一个元素可以放在页面上的任何位置。
元素的定位与文档流无关,所以它们可以覆盖页面上的其它元素
z-index 属性指定了一个元素的堆叠顺序(哪个元素应该放在前面,或后面)
一个元素可以有正数或负数的堆叠顺序:
img { position:absolute; left:0px; top:0px; z-index:-1; }
具有更高堆叠顺序的元素总是在较低的堆叠顺序元素的前面。
注意: 如果两个定位元素重叠,没有指定 z - index,最后定位在 HTML 代码中的元素将被显示在最前面。
float浮动
CSS 的 Float(浮动),会使元素向左或向右移动,其周围的元素也会重新排列。
Float(浮动),往往是用于图像,但它在布局时一样非常有用。
一个浮动元素会尽量向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。
浮动元素之后的元素将围绕它。
浮动元素之前的元素将不会受到影响。
如果图像是右浮动,下面的文本流将环绕在它左边:
<p> <img src="/attachments/cover/cover_css.png" width="95" height="84" /> 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 这是一些文本。这是一些文本。这是一些文本。 </p>
如果你把几个浮动的元素放到一起,如果有空间的话,它们将彼此相邻。
元素浮动之后,周围的元素会重新排列,为了避免这种情况,使用 clear 属性。
clear 属性指定元素两侧不能出现浮动元素。
.text_line { clear:both; }
水平对齐
中心对齐,使用margin属性
块元素可以把左,右页边距设置为"自动"对齐。
Note: 在IE8中使用margin:auto属性无法正常工作,除非声明 !DOCTYPE
margin属性可任意拆分为左,右页边距设置自动指定,结果都是出现居中元素:
.center { margin-left:auto; margin-right:auto; width:70%; background-color:#b0e0e6; }
使用 position 属性设置左,右对齐
元素对齐的方法之一是使用绝对定位:.right { position:absolute; right:0px; width:300px; background-color:#b0e0e6; }
使用 float 属性设置左,右对齐
使用 float 属性是对齐元素的方法之一:
.right { float:right; width:300px; background-color:#b0e0e6; }
使用 Padding 设置垂直居中对齐
CSS 中一个简单的设置垂直居中对齐的方式就是头部顶部使用 padding:
.center { padding: 70px 0; border: 3px solid green; }
如果要水平和垂直都居中,可以使用 padding 和 text-align: center:
.center { padding: 70px 0; border: 3px solid green; text-align: center; }
Crossbrowser 兼容性问题
类似这样的元素对齐时,预先确定 margin 和元素的填充,始终是一个好主意。这是为了避免在不同的浏览器中的可视化差异。
IE8 和早期有一个问题,当使用 float 属性时。如果一个容器元素(在本例中<div class="container">)指定的宽度,!DOCTYPE 声明缺失,IE8 和早期版本会在右边增添 17px 的 margin。这似乎是一个滚动的预留空间。使用 float 属性始终设置在 DOCTYPE 声明中!
body { margin:0; padding:0; } .right { float:right; width:300px; background-color:#b0e0e6; }
透明度
IE9,Firefox,Chrome,Opera,和 Safari 浏览器使用透明度属性可以将图像变的不透明。 Opacity 属性值从0.0 - 1.0。值越小,使得元素更加透明。
IE8和早期版本使用滤镜:alpha(opacity= x)。 x可以采取的值是从0 - 100。较低的值,使得元素更加透明。
img { opacity:0.4; filter:alpha(opacity=40); /* For IE8 and earlier */ }
图像拼合
图像拼合就是单个图像的集合。有许多图像的网页可能需要很长的时间来加载和生成多个服务器的请求。使用图像拼合会降低服务器的请求数量,并节省带宽。
#home{left:0px;width:46px;} #home{background:url('img_navsprites.gif') 0 0;} #prev{left:63px;width:43px;} #prev{background:url('img_navsprites.gif') -47px 0;} #next{left:129px;width:43px;} #next{background:url('img_navsprites.gif') -91px 0;}
定义背景图像和它的位置(左 0px,顶部 0px),即左上角是(0,0),往右和往下都是负数。
media 规则
媒体类型允许你指定文件将如何在不同媒体呈现。该文件可以以不同的方式显示在屏幕上,在纸张上,或听觉浏览器等等。
@media 规则允许在相同样式表为不同媒体设置不同的样式。
<style>
@media screen
{ p.test {font-family:verdana,sans-serif;font-size:14px; } }
@media print
{ p.test {font-family:times,serif;font-size:10px;} }
@media screen,print
{ p.test {font-weight:bold;}}
</style>
其它细节
CSS注释以 "/*
" 开始, 以 "*/
" 结束。
list-style-type:none
- 移除列表前小标志。
不要在属性值与单位之间留有空格。假如你使用 "margin-left: 20 px" 而不是 "margin-left: 20px",它仅在 IE 6 中有效,但是在 Mozilla/Firefox 或 Netscape 中却无法正常工作。
margin:0; padding:0;可以移除浏览器的默认设置将边距和填充设置为 0
CSS3
CSS3 是最新的 CSS 标准。
CSS3使用了层叠样式表技术,可以对网页布局、字体、颜色、背景灯效果做出控制。css3作为css的进阶版,拆分和增加了盒子模型、列表模块、语言模块 、背景边框 、文字特效 、多栏布局等等。
CSS3的改变有很多,增加了文字特效,丰富了下划线样式,加入了圈重点的功能。在边框方面,有了更多的灵活性,可以更加轻松地操控渐变效果和动态效果等等。在文字效果方面,特意增加了投影。
CSS3在兼容上做了很大的功夫,并且网络浏览器也还将继续支持CSS2,因此原来的代码不需要做太多的改变,只会变得更加地轻松。
CSS3被拆分为"模块"。旧规范已拆分成小块,还增加了新的规范。
一些最重要CSS3模块如下:
- 选择器
- 盒模型
- 背景和边框
- 文字特效
- 2D/3D转换
- 动画
- 多列布局
- 用户界面
圆角和边框
在CSS3中border-radius属性就是被用于创建圆角:border-radius:25px;,在 border-radius 属性中只指定一个值,那么将生成 4 个 圆角。也可以在四个角上一一指定,两个和三个值也可以。
box-shadow属性被用来添加阴影: box-shadow: 10px 10px 5px #888888;
border-image属性允许你指定一个图片作为边框:
border-image:url(border.png) 30 30 round; -webkit-border-image:url(border.png) 30 30 round; /* Safari 5 and older */ -o-border-image:url(border.png) 30 30 round; /* Opera */
背景属性
CSS3中可以通过background-image属性添加背景图片。不同的背景图像和图像用逗号隔开,所有的图片中显示在最顶端的为第一张。background-image: url(img_flwr.gif), url(paper.gif);同时显示多张图片。可以给不同的图片设置多个不同的属性。
background-size指定背景图像的大小。CSS3以前,背景图像大小由图像的实际大小决定。CSS3中可以指定背景图片,让我们重新在不同的环境中指定背景图片的大小。您可以指定像素或百分比大小。你指定的大小是相对于父元素的宽度和高度的百分比的大小。
background-Origin属性指定了背景图像的位置区域。content-box, padding-box,和 border-box区域内可以放置背景图像。background-origin:content-box;
CSS3中background-clip背景剪裁属性是从指定位置开始绘制,background-clip: content-box;
渐变
background: linear-gradient(direction, color-stop1, color-stop2, ...); 方向可以是to right或to bottom right等,或者是度数,如180deg
为了添加透明度,我们使用 rgba() 函数来定义颜色结点。rgba() 函数中的最后一个参数可以是从 0 到 1 的值,它定义了颜色的透明度:0 表示完全透明,1 表示完全不透明。
background: linear-gradient(to right, rgba(255,0,0,0), rgba(255,0,0,1)); /* 标准的语法 */
文本特征
CSS3中包含几个新的文本特征。
- text-shadow:适用于文本阴影
- box-shadow:适用于盒子阴影
- text-overflow:指定应向用户如何显示溢出内容,如text-overflow: clip;
- word-wrap:如果某个单词太长,不适合在一个区域内,它扩展到外面,CSS3中,自动换行属性允许您强制文本换行 - 即使这意味着分裂它中间的一个字允许长文本换行,如:word-wrap:break-word;
- word-break:单词拆分换行属性指定换行规则,value可以是keep-all或break-all
字体
在新的 @font-face 规则中,您必须首先定义字体的名称(比如 myFirstFont),然后指向该字体文件。
<style> @font-face { font-family: myFirstFont; src: url(sansation_light.woff); } div { font-family:myFirstFont; } </style>
2D 转换
2D变换方法:
- translate():根据左(X轴)和顶部(Y轴)位置给定的参数,从当前元素位置移动。如:transform: translate(50px,100px);
- rotate():在一个给定度数顺时针旋转的元素。负值是允许的,这样是元素逆时针旋转。如:transform: rotate(30deg);
- scale():元素增加或减少的大小,取决于宽度(X轴)和高度(Y轴)的参数。如:transform: scale(2,4);转变宽度为原来的大小的2倍,和其原始大小4倍的高度。
- skew():包含两个参数值,分别表示X轴和Y轴倾斜的角度,如果第二个参数为空,则默认为0,参数为负表示向相反方向倾斜。如:transform: skew(30deg,20deg);元素在X轴和Y轴上倾斜30度和20度。
- matrix():和2D变换方法合并成一个。matrix 方法有六个参数,包含旋转,缩放,移动(平移)和倾斜功能。如:transform:matrix(0.866,0.5,-0.5,0.866,0,0);
3D转换类似,如:translateX(x),多了X或Y或Z的坐标轴。
过渡
CSS3中,我们为了添加某种效果可以从一种样式转变到另一个的时候,无需使用Flash动画或JavaScript。
CSS3 过渡是元素从一种样式逐渐改变为另一种的效果。
要实现这一点,必须规定两项内容:
- 指定要添加效果的CSS属性
- 指定效果的持续时间。
如果未指定的期限,transition将没有任何效果,因为默认值是0。
指定的CSS属性的值更改时效果会发生变化。一个典型CSS属性的变化是用户鼠标放在一个元素上时,如:
div { width: 100px; height: 100px; background: red; -webkit-transition: width 2s, height 2s, -webkit-transform 2s; /* For Safari 3.1 to 6.0 */ transition: width 2s, height 2s, transform 2s; }
div:hover { width: 200px; height: 200px; -webkit-transform: rotate(180deg); /* Chrome, Safari, Opera */ transform: rotate(180deg); }
动画
@keyframes规则是创建动画。 @keyframes规则内指定一个CSS样式和动画将逐步从目前的样式更改为新的样式。
当在@keyframe创建动画,把它绑定到一个选择器,否则动画不会有任何效果。
指定至少这两个CSS3的动画属性绑定向一个选择器:
- 规定动画的名称
- 规定动画的时长
div { width:100px; height:100px; background:red; animation:myfirst 5s; -webkit-animation:myfirst 5s; /* Safari and Chrome */ }
@keyframes myfirst { from {background:red;} to {background:yellow;} }
@-webkit-keyframes myfirst /* Safari and Chrome */ { from {background:red;} to {background:yellow;} }
必须定义动画的名称和动画的持续时间。如果省略的持续时间,动画将无法运行,因为默认值是0。
动画是使元素从一种样式逐渐变化为另一种样式的效果。可以改变任意多的样式任意多的次数。请用百分比来规定变化发生的时间,或用关键词 "from" 和 "to",等同于 0% 和 100%。0% 是动画的开始,100% 是动画的完成。为了得到最佳的浏览器支持,应该始终定义 0% 和 100% 选择器。
div { width:100px; height:100px; background:red; animation:myfirst 5s; -moz-animation:myfirst 5s; /* Firefox */ -webkit-animation:myfirst 5s; /* Safari and Chrome */ -o-animation:myfirst 5s; /* Opera */ }
@keyframes myfirst { 0% {background:red;} 25% {background:yellow;} 50% {background:blue;} 100% {background:green;} }
多列
能够创建多个列来对文本进行布局 - 就像报纸那样
多列属性:
- column-count:指定元素的列数,如:column-count:3;
- column-gap:指定的列之间的差距,如:column-gap:40px;
- column-rule:设置列之间的宽度,样式和颜色,如:column-rule:3px outset #ff00ff;
- column-rule-color
- column-rule-style
- column-rule-width
- column-width
用户界面
用户界面属性:
- resize
- box-sizing
- outline-offset
resize
CSS3中,resize属性指定一个元素是否应该由用户去调整大小。这个 div 元素由用户调整大小。如:
div { border:2px solid; padding:10px 40px; width:300px; resize:both; overflow:auto; }
可以拖拉文本框的大小。
box-sizing
box-sizing 属性允许您以确切的方式定义适应某个区域的具体内容。如;box-sizing:border-box;
CSS3 box-sizing
属性在一个元素的 width 和 height 中包含 padding(内边距) 和 border(边框)。
如果在元素上设置了 box-sizing: border-box;
则 padding(内边距) 和 border(边框) 也包含在 width 和 height 中:
两个 div 现在是一样大小的,若去除掉box-sizing: border-box;属性,则div2因为有padding,整个框会更大。
.div1 { width: 300px; height:100px; border: 1px solid blue; box-sizing: border-box; } .div2 { width: 300px; height: 100px; padding: 50px; border: 1px solid red; box-sizing: border-box; }
outline-offset
outline-offset 属性对轮廓进行偏移,并在超出边框边缘的位置绘制轮廓。
轮廓与边框有两点不同:
- 轮廓不占用空间
- 轮廓可能是非矩形
div { border:2px solid black; outline:2px solid red; outline-offset:15px; }
图片
响应式图片会自动适配各种尺寸的屏幕。如果你需要自由缩放图片,且图片放大的尺寸不大于其原始的最大值,则可使用以下代码:
img { max-width: 100%; height: auto; }
卡片式图片
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
filter
属性用为元素添加可视效果 (例如:模糊与饱和度) 。
.blur {-webkit-filter: blur(4px);filter: blur(4px);} .brightness {-webkit-filter: brightness(250%);filter: brightness(250%);} .contrast {-webkit-filter: contrast(180%);filter: contrast(180%);} .grayscale {-webkit-filter: grayscale(100%);filter: grayscale(100%);} .huerotate {-webkit-filter: hue-rotate(180deg);filter: hue-rotate(180deg);} .invert {-webkit-filter: invert(100%);filter: invert(100%);} .opacity {-webkit-filter: opacity(50%);filter: opacity(50%);} .saturate {-webkit-filter: saturate(7); filter: saturate(7);} .sepia {-webkit-filter: sepia(100%);filter: sepia(100%);} .shadow {-webkit-filter: drop-shadow(8px 8px 10px green);filter: drop-shadow(8px 8px 10px green);} </style>
弹性盒子
CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。
引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。
弹性盒子由弹性容器(Flex container)和弹性子元素(Flex item)组成。通过设置 display 属性的值为 flex 或 inline-flex将其定义为弹性容器。弹性容器内包含了一个或多个弹性子元素。
弹性容器外及弹性子元素内是正常渲染的。弹性盒子只定义了弹性子元素如何在弹性容器内布局。弹性子元素通常在弹性盒子内一行显示。默认情况每个容器只有一行。
以下元素展示了弹性子元素在一行内显示,从左到右:
.flex-container { display: -webkit-flex; display: flex; width: 400px; height: 250px; background-color: lightgrey; }
.flex-item{ background-color: cornflowerblue; width: 100px; height: 100px; margin: 10px; }
<div class="flex-container"> <div class="flex-item">flex item 1</div> <div class="flex-item">flex item 2</div> <div class="flex-item">flex item 3</div> </div>
当然我们可以修改排列方式。如果我们设置 direction
属性为 rtl
(right-to-left),弹性子元素的排列方式也会改变,页面布局也跟着改变
body { direction: rtl; }
flex-direction
顺序指定了弹性子元素在父容器中的位置。
flex-direction
的值有:
- row:横向从左到右排列(左对齐),默认的排列方式。
- row-reverse:反转横向排列(右对齐,从后往前排,最后一项排在最前面。
- column:纵向排列。
- column-reverse:反转纵向排列,从后往前排,最后一项排在最上面。
多媒体查询
多媒体查询由多种媒体组成,可以包含一个或多个表达式,表达式根据条件是否成立返回 true 或 false。
代码语言:javascript复制@media not|only mediatype and (expressions) {
CSS-Code;
}
如果指定的多媒体类型匹配设备类型则查询结果返回 true,文档会在匹配的设备上显示指定样式效果。
除非你使用了 not 或 only 操作符,否则所有的样式会适应在所有设备上显示效果。
- not: not是用来排除掉某些特定的设备的,比如 @media not print(非打印设备)。
- only: 用来定某种特别的媒体类型。对于支持Media Queries的移动设备来说,如果存在only关键字,移动设备的Web浏览器会忽略only关键字并直接根据后面的表达式应用样式文件。对于不支持Media Queries的设备但能够读取Media Type类型的Web浏览器,遇到only关键字时会忽略这个样式文件。
- all: 所有设备,这个应该经常看到。
也可以在不同的媒体上使用不同的样式文件:
<link rel="stylesheet" media="mediatype and|not|only (expressions)" href="print.css">
在屏幕可视窗口尺寸大于 480 像素的设备上修改背景颜色:
@media screen and (min-width: 480px) { body { background-color: lightgreen; } }
可以在已有的查询媒体后使用逗号分隔来添加其他媒体查询 (类似 OR 操作符):
width在520~699
@media screen and (max-width: 699px) and (min-width: 520px) { ul li a { padding-left: 30px; background: url(email-icon.png) left center no-repeat; } }
width在520~699 或大于1151时
@media screen and (max-width: 699px) and (min-width: 520px), (min-width: 1151px) { ul li a { padding-left: 30px; background: url(email-icon.png) left center no-repeat; } }
CSS工具
为了解决原生 CSS 存在的一些问题,社区中出现了各式各样的样式工具。有覆盖范围比较小,但是解决了最关键问题的 CSS module;也有以 Sass 为代表的,中规中矩的 CSS 预处理器;还有通过插件化形式,具备非常强大的可拓展性的 PostCSS;以及剑走偏锋的 tailwind 和 styled-components。他们各有自己的优势劣势,也不存在一个最好的工具,作为前端工程师,只能根据具体场景,选择最适合的工具。
原生 CSS
从前,车马很慢,书信很远,样式开发也很简单。我们只需要将样式放在 CSS 文件中,并直接引入即可。然而简单也是需要代价的:
- 缺少局部作用域:所有组件使用的所有 CSS 代码,都会全局生效。
- 不支持条件逻辑:比如,我们无法非常方便的实现“第一个元素是红色,其余元素为绿色”,而是需要使用较复杂的伪类选择器。这也是 CSS 被人诟病“不是一种编程语言”的原因之一。
CSS module
CSS Modules 是这样一种效果:CSS 文件中的所有类名都默认具有局部作用域。即使是一个普通的 CSS 文件,只要开发者通过某种方式实现了这种效果。也可以称之为“使用了 CSS module”。
显著的不同是:CSS 文件居然导出了一个变量(style
)。并且,html标签上的类名,并不是普通的字符串,而是从style
变量导出的同名属性。
最主流、应用最广也是最早产生的实现方式,就是通过构建工具来实现。比如 webpack 生态下的 css-loader
。这些工具会为 CSS 文件中的每个类名,生成一个哈希值。并在打包产物中,将哈希值作为类名使用。并且打包工具会保证 ,即使是不同的 CSS 文件中,存在同名的类,生成的哈希值也是不同的。从而保证了局部作用域。
CSS 预处理器
CSS 预处理器可以说是众多样式工具中比较主流的一类,有很多广受欢迎的工具:Less、Sass 以及 Stylus。
CSS 预处理器是一种独有的语法来生成 CSS 代码的程序。也就是说,每种 CSS 预处理器,都会引入一种新的语言,开发者需要使用这种新的语言来编写源码。而预处理器会负责将源码编译成 CSS 代码。并且,虽然说会引入一种新的语言,但为了方便开发者使用,这种新的语言一般不会和 CSS 相差太多,基本上是 CSS 的一个超集。 从这个意义上来说,CSS 预处理器其实和 Typescript 有些相似之处。
这些超集内容提供了很多的语法,比如支持定义变量和嵌套写法等, 为我们的开发带来了很大的助力。
PostCSS
PostCSS 的名称可能会让人误解,认为这个工具是进行 CSS 后处理(对用户编写的标准 CSS 代码进行处理)的。从而与一些 CSS 预处理工具(比如上面提到的 Sass)区分开。实际上,PostCSS 依靠其简单的核心功能以及丰富的插件体系,能够同时完成 CSS 后处理,以及 CSS 预处理的工作。
PostCSS 的插件体系是极其丰富的,对于常见的需求,我们都能找到对应的插件。比如 Autoprefixer 是一个十分常用的 PostCSS 插件。它能够在输出的 CSS 中,对于兼容性有问题的 CSS 规则,自动加上不同浏览器的前缀。免去了开发人员手动为每一个规则加上不同前缀的繁琐而无趣的工作。
Tailwind
Tailwind和上面提到的工具,采取了完全不同的思路。因此也有了完全不同的架构。具体来说,tailwind 的思路是:它提供非常多的原子化 CSS 类。用户可以通过组合这些类来实现想要的样式。
总的来说 tailwind 的优点和缺点都十分突出。其缺点显而易见:大多数人都不熟悉这种方式,并且学习起来比较困难。要想熟练地使用 tailwind,需要对其提供的大多数常用的类都比较熟悉,看到某个组件的设计图,就能大概知道需要使用哪些原子化 CSS 类。而在达到这个程度之前,使用 tailwind 编写样式是一个比较痛苦的过程(写两行代码需要看十次文档)。
而优点可能不太容易察觉:
- 在大多数情况下,几乎不用自己编写一行 CSS 代码
- 如果开发者能够对 tailwind 比较熟悉,就能够使用它提供的原子化 CSS 类完成全部样式。
- 当我们需要对第三方组件库(比如 antD)的类添加一些样式时,我们就必须自己编写 CSS 代码了
- 极大的提高开发效率
- 之前需要编写多行 CSS 规则,现在只需要组合几个原子化 CSS 类
- 几乎不需要考虑原子化 CSS 类之间的冲突
- 原子化这个称呼就表明了,每个类只完成一个孤立的功能。所以不同类的 CSS 规则之间,不会有覆盖或重叠
- 以一种非常独特的方式,解决了全局作用域问题
- 如果我们完全使用 tailwind 来编程,我们会发现,我们几乎不需要定义 CSS 类。如此,既然不存在自定义的CSS 类,就根本不会存在 CSS 类污染了全局作用域的问题。
- 但也有例外,比如上文提到的“为第三方组件库的类添加一些样式”时,还是会产生 CSS 类名,从而产生了污染全局作用域的风险
Styled-components
Jeff Atwood 在2007年提出 Atwood 定律:任何能够用 JavaScript 实现的应用系统,最终都必将用 JavaScript 实现。大家或许能想到 JS 在服务器、客户端领域的大放异彩。但大家想不到的是,JS 竟然也想要将样式也纳入统治范围之内。而这个趋势的产物,就是 styled-components。
使用者完全不需要引入 CSS 文件或者类 CSS 文件,也完全不需要定义和使用CSS类名。而是需要将样式代码,放在一个个样式组件中。而样式组件如何定义呢?需要使用暴露出来的styled
api,并且将样式代码放在模板字符串中。
值得一提的是 antd v5 开始使用了 css in js 方案,不过部分开发者认为 styled-components 这种“依赖模板字符串构建样式组件”的方式并没有给他们带来多大收益,但是它让样式组件, 以及样式组件和逻辑组件分离的概念普及给了更多人,这本身就是一件很好的事情。
学习途径
在线学习
CSS教程:https://www.w3cschool.cn/css/index.html
CSS3教程:https://www.w3cschool.cn/css3/index.html
SAAS教程:https://www.w3cschool.cn/sass/
推荐书籍
- 《CSS 世界》:张鑫旭大神的书,十多年的 CSS 经验分享,必买书籍。
- 《CSS 选择器世界》:张鑫旭大神的另一力作,深入讲解 CSS 选择器。
- 《CSS 揭秘》:各种 CSS 奇淫巧技,主要是来开阔视野。
- 《CSS 权威指南》:属于 CSS 的新华字典,很全面,属于一本工具书。
- 《深入解析 CSS》:2020 年的新书,奇虎团工程师翻译,质量有保证。