规则结构
每个CSS规则都有两个基本部分: 选择器和声明块
元素选择器
类型选择器
最常见的选择器是HTML元素(类型)选择器。
div {
color: blue;
}
选择器分组
当我莪们想要将多个元素一个用同一个样式的时候,可以使用选择器分组。div, span {
color: blue;
}
将div和span选择器放在规则的左边,并用一个逗号来分隔,此时的规则如下:
声明块中的内容将应用到前面的两个选择器所引用的元素。逗号高速浏览器,规则中包含两个不同的选择器。后面会讲解没有逗号的后代选择器。
声明分组
如果对同一个选择器具有多个声明块,那么我们可以将生命块成族。如下:div {
color: blue;
}
div {
margin: 10px;
}
成组:
div {
color: blue;
margin: 10px;
}
* 尽管技术上没有让规则的最后一个声明加上分号,但是最好加上分号,使用好的代码规范要求自己。通配选择器
css2引入了新的简单选择器,通配选择器。在这个选择器可以与任何元素匹配。这二个生命等于列出了文档中所有元素的一个分组选择器。* {
color: blue;
}
类选择器
要应用样式而不考虑具体的元素,最常用的方法是使用类选择器。使用选择器之前,需要先给文档元素添加class属性。
规则:类名前有一个点号(.),而且可以结合简单选择器(元素选择器或者通配选择器)。如下面的例子div.title会将选择器的范围限定到“Class属性包含title的div标签”。.main等同于通配选择器(*.main).
.main {
color: blue;
}
div.title {
background: yellow;
}
<div class="main title">
Test css rel.
</div>
* 多类选择器的说明:
上面的例子就是一个多类选择器。类名的顺序不限,以空格隔开。如果我们想要将同时具有main title 类属性的div设置特有的属性值字体为粗体字符。则可以如下:
.main {
color: blue;
}
div.title {
background: yellow;
}
div.main.title {
font-weight: bold;
}
ID选择器
ID选择器类似类选择器,二者之间有一些差别。ID选择器前面有一个#号(棋盘号)而不是一个点号(同样的也可以结合通配符选择器或者元素选择器)。#main-content {
color: blue;
}
div#main-content {
color: blue;
}
*#main-content {
color: blue;
}
类选择器和ID选择器的选择?
(1) 类可以分配给任意多的元素,ID在一个 HTML 文档中使用且仅使用一次。因此如果有了一个id值为main-content的元素,该文档中的其他元素都不能有main-content的id值。(2) 与类选择器不同,ID 选择器不能联合使用,因为 ID 属性不允许使用空白分隔的单词列表。
(3) class和id名称的另一个区别是,当决定某个元素应该应用哪个样式时,ID有更高的权重。
延伸
(1) 在实际中,浏览器并不总会检查 HTML 中 ID 的唯一性。如果你为多个元素设置了相同的 ID 属性值,它们可能都会被设置为相同的样式。这是不正确的实现,但这种情况很普遍。在一个文档中存在多个 ID 值相同的元素还会导致 DOM 脚本的问题,因为像getElementById()这样的函数依赖于文档中只存在一个 ID 为特定值的元素。(2) 还要注意类和 ID 可能是大小写敏感的,这取决于文档的语言。HTML和XHTML语言把类和ID定义为大小写敏感的,因此类和ID选择器的大小写要和文档中的匹配。
属性选择器
类和ID选择器实际上是在选择属性的值。因为class和ID都是属于属性的。属性选择器有四种基本类型:简单属性选择器、准确属性值选择器、部分匹配属性选择器和头值属性选择器。
简单属性选择器
如果想选择具有某个特定属性的元素,而无论属性的值是什么,可以使用简单属性选择器。
/*选择所有具有class属性的div元素*/
div[class] {
color: blue;
}
/*选择所有具有class属性的元素*/
*[class] {
color: blue;
}
/*选择class属性包含main并且具有title属性的元素*/
.main[title] {
color: blue;
}
/*选择有title属性并且同时具有href属性的元素*/
*[title][href] {
color: blue;
}
根据具体属性值选择
在属性选择器的基础上可以进一步缩小选择器范围选择那些某个属性为某个确定值的元素。
div[class="main title"] {
color: blue;
}
<div class="main title">
Test css rel.
</div>
与属性选择一样,使用多个元素-值选择器也可以选择单个元素。
a[href="http://www.w3.org/"][title="W3C Home"] {font-size: 200%;}
* 这种方式需要属性值的精确匹配。样式表中的属性值必须和元素中的属性值相同。根据部分属性值匹配
如果属性能接受词列表(词之间用空格分隔),可以根据其中的人一个词斤西瓜选择。最经典的例子就是class属性了。用上面的例子来说:如果使用属性选择器达成部分属性值匹配,则需要如下:
div[class~="main"] {
color: blue;
}
再举一个普通例子:
div[title~="main"] {
color: blue;
}
<div title="main title">
Test css rel.
</div>
~: 这个符号就是边界(空白分割的单词就是边界,详情可以访问文章)匹配的效果。请看下面子串匹配属性选择器
延伸:忽略大小写标识符
知道正则表达式的都知道修饰符i的意义:执行对大小写不敏感的匹配。CSS Selectors level 4 为属性选择器引入了忽略大小写选项。在中括号关闭之前使用i允许选择器匹配属性值的时候忽略大小写,无视文档语言的规则。
div[title~="Main" i] {
color: blue;
}
请看下图chorme的示例:
从图中红框内的内容可以看出当前的main执行的是忽略大小写的匹配。
* 至 2017 年底,Opera Mini、Android 浏览器和 Edge 不支持此能力。
关系选择器
CSS 之强大在于它利用文档结构决定(元素的)样式和样式作用于元素的方式。结构确实在样式作用于文档时扮演了非常重要的角色。后代选择器
h1 em {color: gray;}
这条规则会把所有是h1元素后代的em元素中的文本设置为灰色。
解释:选择器之间的空格是一个组合器的例子。每个空格组合器都可以被译作“在……中”、“是……的一部分”或“是……的后代”,前提是选择器从右向左读。因此,h1 em可以被译作“把样式作用于任何em元素,如果它是h1元素的后代”。(如果选择器从左向右读,则是:“选择任何h1,如果它包含一个em元素,规则将会作用于它包含的em”)。
子元素选择器
选择元素的范围在子元素中。可以使用子元素选择器,它是一个大括号(>)。
h1 > strong {color: red;}
<h1>This is <strong>very</strong> important.</h1>
<h1>This is <em>really <strong>very</strong></em> important.</h1>
这条规则将会把下面的第一个h1元素中的strong元素设置为红色,第二个h1元素中的strong元素则不会被设置为红色。
选择相邻兄弟元素
选择紧接在另一个元素后的元素,且二者具有相同的父元素。相邻兄弟选择器使用了加好(+),即相邻兄弟结合符
li + li {
font-weight:bold;
}
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
li元素后面的第一个兄弟li元素。用一个结合符只能选择两个相邻兄弟中的第二个元素。第二个与第三个li元素的font-weight的属性都应用上了,因为对于第二个li元素,第三li元素也是li的紧接着的并且具有相同父元素的li元素。
兄弟选择符
与相邻选择符不同的是,兄弟选择符会命中所有符合条件的兄弟元素,而不强制是紧邻的元素。使用符号(~)
div ~ p {
font-weight:bold;
}
<div>第一个div</div>
<p>第一个p</p>
<span>第一个span</span>
<p>第二个p</p>
上面例子中的两个P都会加粗。
伪类选择器
伪类选择器非常有趣,它们是一些根据元素状态变化而产生作用的幽灵类。伪类选择器可以根据某些确定元素的状态、文档中的标记模式甚至文档本身的状态选择元素并添加样式。
链接伪类
CSS2.1 定义了两个之应用于超链接的伪类。
:linlk 设置超链接a在未被访问前的样式。
:visited 设置超链接a在其链接地址已被访问过时的样式。
超链接的4种状态,需要有下面的书写顺序才能生效。其他的两个属于动态伪类
a:link {
color: #FF0000; /* 未访问的链接 */
}
a:visited {
color: #00FF00; /* 已访问的链接 */
}
a:hover {
color: #FF00FF; /* 鼠标移动到链接上 */
}
a:active {
color: #0000FF; /* 选定的链接 */
}
动态伪类
CSS2.1 定义了三个动态伪类,可以根据用户行为改变文档的外观。这些动态伪类以前总是用类设置超链接的样式。但是现在动态伪类可以应用到任何元素上,这一点是非常重要的。
:hover 设置元素在其鼠标悬停时的样式。
:focus 设置对象在成为输入焦点(该对象的onfocus事件发生)时的样式。
:active 设置元素在被用户激活(在鼠标点击与释放之间发生的事件)时的样式。
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8" />
<style>
h1 {
font-size: 16px;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
input:focus {
background: #f6f6f6;
}
input:hover {
background: blue;
}
input:active {
background: red;
}
</style>
</head>
<body>
<h1>请聚焦到以下输入框</h1>
<form action="#">
<ul>
<li><input value="姓名" /></li>
<li><input value="单位" /></li>
<li><input value="年龄" /></li>
<li><input value="职业" /></li>
</ul>
</form>
</body>
</html>
如图,当我点击鼠标和释放鼠标之间会显示红色的背景,此时是在active的状态下。
结构性伪类
大部分伪类都是结构性的,既它们是与文档的标记结构相关的。选择第一个子元素
:first-child
匹配父元素的第一个子元素E。要使该属性生效,E元素必须是某个元素的子元素,E的父元素最高是body,即E可以是body的子元素
<ul>
<li>列表项一</li>
<li>列表项二</li>
<li>列表项三</li>
<li>列表项四</li>
</ul>
在上述代码中,如果我们要设置第一个li的样式,那么代码应该写成li:first-child{sRules},而不是ul:first-child{sRules}。child的其他伪类
E:last-child { sRules } 匹配父元素的最后一个子元素E。E:only-child { sRules } 匹配父元素仅有的一个子元素E。
E:nth-child(n) { sRules } 匹配父元素的第n个子元素E,假设该子元素不是E,则选择符无效。
E:nth-last-child(n) { sRules } 匹配父元素的倒数第n个子元素E,假设该子元素不是E,则选择符无效。
匹配语言
:lang(fr)匹配使用特殊语言的元素。
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8" />
<style>
p:lang(zh-cmn-Hans) {
color: #f00;
}
p:lang(en) {
color: #090;
}
</style>
</head>
<body>
<p lang="zh-cmn-Hans">大段测试文字</p>
<p lang="en">english</p>
</body>
</html>
选择根元素
:root这是结构简单性的精髓:伪类选择器:root选择文档的根元素。在 HTML 中,根元素永远是html元素。
:root {border: 10px dotted gray;}
选择空元素
使用伪类:empty,可以选择任何没有子节点的元素——没有任何类型的子元素:不包含文本节点,不包括文字和空白。
<p></p>
<p> </p>
<p>
</p>
<p><!—-a comment--></p>
第二个和第三个段落不会匹配:empty,因为它们不是空的:它们各自包含一个空格和一个换行符,都会被当做文本节点,因此不是空状态。最后一个段落能够匹配,因为注释既不会被当成内容,也不会被当成空白。但是如果在注释的任何一侧添加一个空格或者换行,p:empty将不再匹配它。选择非元素的所有元素
:not(s)匹配不含有s选择符的元素E。
.demo li:not(:last-child) {
border-bottom: 1px solid #ddd;
}
给该列表中除最后一项外的所有列表项加一条底边线选择第一个特定类型的元素
E:first-of-type { sRules }
匹配同类型中的第一个同级兄弟元素E。要使该属性生效,E元素必须是某个元素的子元素,E的父元素最高是html,即E可以是html的子元素,也就是说E可以是body该选择符总是能命中父元素的第1个为E的子元素,不论第1个子元素是否为Etype其他的类型
E:last-of-type { sRules } 匹配同类型中的最后一个同级兄弟元素E。E:only-of-type { sRules } 匹配同类型中的唯一的一个同级兄弟元素E。
E:nth-of-type(n) { sRules } 匹配同类型中的第n个同级兄弟元素E。
E:nth-last-of-type(n) { sRules } 匹配同类型中的倒数第n个同级兄弟元素E。
UI状态伪类
E:checked { sRules }匹配用户界面上处于选中状态的元素E。(用于input type为radio与checkbox时)
E:enabled { sRules }
匹配用户界面上处于可用状态的元素E。(主要用于表单元素)
E:disabled { sRules }
匹配用户界面上处于禁用状态的元素E。(主要用于表单元素)
E:target { sRules }
匹配相关URL指向的E元素。URL后面跟锚点#,指向文档内某个具体的元素。这个被链接的元素就是目标元素(target element),:target选择器用于选取当前活动的目标元素。
打印类伪类 (了解)
@page :first { sRules }设置在打印时页面容器第一页使用的样式。仅用于@page规则。
该伪类选择符只允许定义margin, orphans, widows 和 page breaks相关属性
@page :left { sRules }
设置页面容器位于装订线左边的所有页面使用的样式。仅用于@page规则。
该伪类选择符只允许定义margin, padding, border 和 background属性
@page :right { sRules }
设置页面容器位于装订线右边的所有页面使用的样式。仅用于@page规则。
该伪类选择符只允许定义margin, padding, border 和 background属性
伪元素选择器
E:first-letter/E::first-letter { sRules }
设置对象内的第一个字符的样式。此伪对象仅作用于块对象。内联对象要使用该伪对象,必须先将其设置为块级对象。
该伪类常被用来配合font-size属性和float属性制作首字下沉效果。
IE6在使用该选择符时有个显式的BUG:选择符与包含规则的花括号之间不能紧挨着,需留有空格或换行。同时还存在该BUG的选择符包括:E:first-line
CSS3将伪对象选择符(Pseudo-Element Selectors)前面的单个冒号(:)修改为双冒号(::)用以区别伪类选择符(Pseudo-Classes Selectors),但以前的写法仍然有效。
即E:first-letter可转化为E::first-letter
p:first-letter {float:left;font-size:40px;font-weight:bold;line-height:1;}
p::first-letter {float:left;font-size:40px;font-weight:bold;line-height:1;}
E:first-line/E::first-line { sRules }
设置对象内的第一行的样式。此伪对象仅作用于块对象。内联对象要使用该伪对象,必须先将其设置为块级对象。
IE6在使用该选择符时有个显式的BUG:选择符与包含规则的花括号之间不能紧挨着,需留有空格或换行。同时还存在该BUG的选择符包括:E:first-letter
CSS3将伪对象选择符(Pseudo-Element Selectors)前面的单个冒号(:)修改为双冒号(::)用以区别伪类选择符(Pseudo-Classes Selectors),但以前的写法仍然有效。
即E:first-line可转化为E::first-line
p:first-line {color:#090;}
p::first-line {color:#090;}
E:before/E::before { sRules }
设置在对象前(依据对象树的逻辑结构)发生的内容。用来和content属性一起使用,并且必须定义content属性
CSS3将伪对象选择符(Pseudo-Element Selectors)前面的单个冒号(:)修改为双冒号(::)用以区别伪类选择符(Pseudo-Classes Selectors),但以前的写法仍然有效。
即E:before可转化为E::before
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8" />
<style>
p{
position:relative;
color:#f00;
font-size:14px;
}
p:before{
position:absolute;
background:#fff;
color:#000;
content:"如果你的能看到这段文字,说明你的浏览器只支持E:before";
font-size:14px;
}
p::before{
position:absolute;
background:#fff;
color:#000;
content:"如果你的能看到这段文字,说明你的浏览器支持E:before和E::before";
font-size:14px;
}
</style>
</head>
<body>
<p><span>Sorry, 你的浏览器不支持E:before和E::before</span></p>
</body>
</html>
如图,当浏览器支持before,由于内容设置为float,所以将之前的文件盖住了。
E:after/E::after { sRules }
设置在对象后(依据对象树的逻辑结构)发生的内容。用来和content属性一起使用,并且必须定义content属性
CSS3将伪对象选择符(Pseudo-Element Selectors)前面的单个冒号(:)修改为双冒号(::)用以区别伪类选择符(Pseudo-Classes Selectors),但以前的写法仍然有效。
即E:after可转化为E::after
E::placeholder { sRules }
设置对象文字占位符的样式。::placeholder 伪元素用于控制表单输入框占位符的外观,它允许开发者/设计师改变文字占位符的样式,默认的文字占位符为浅灰色。
当表单背景色为类似的颜色时它可能效果并不是很明显,那么就可以使用这个伪元素来改变文字占位符的颜色。
需要注意的是,除了Firefox是 ::[prefix]placeholder,其他浏览器都是使用 ::[prefix]input-placeholderFirefox支持该伪元素使用text-overflow属性来处理溢出问题。
input::-webkit-input-placeholder {
color: #999;
}
input:-ms-input-placeholder { // IE10+
color: #999;
}
input:-moz-placeholder { // Firefox4-18
color: #999;
}
input::-moz-placeholder { // Firefox19+
color: #999;
}
E::selection { sRules }
设置对象被选择时的样式。需要注意的是,::selection只能定义被选择时的background-color,color及text-shadow(IE11尚不支持定义该属性)。
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8" />
<style>
p::-moz-selection{
background:#000;
color:#f00;
}
p::selection{
background:#000;
color:#f00;
}
</style>
</head>
<body>
<h1>选中下面的文字,看看它的颜色</h1>
<p>你选中这段文字后,看看它们的文本颜色和背景色,就能明白::selection的作用。</p>
</body>
</html>
first-child与:first-of-type的区别
(1) 可以匹配的范围不同
first-of-type 可以匹配body元素,而first-child不行<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8" />
<style>
body:first-of-type {
background:gray;
color:#f00;
}
body:first-child {
background:blue;
color:#f00;
}
</style>
</head>
<body>
<div>
<h1>第二个子元素</h1>
<p>第一个子元素</p>
<h1>第二个子元素</h1>
<span>第三个子元素</span>
<span>第四个子元素</span>
</div>
</body>
</html>
如图可见当前只有first-of-type样式匹配到body元素上。
(2) 结构上的限制
:first-child匹配的同时要求当前元素必须是第一个子元素,而first-of-type则没有这个限制
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8" />
<style>
p:first-of-type {
background:#000;
color:#f00;
}
p:first-child {
background:#000;
color:#f00;
}
</style>
</head>
<body>
<div>
<h1>第二个子元素</h1>
<p>第一个子元素</p>
<h1>第二个子元素</h1>
<span>第三个子元素</span>
<span>第四个子元素</span>
</div>
</body>
</html>
如图p标签由于不是当前p元素的父元素div的第一个子元素,所以只匹配了first-of-type,而没有匹配first-child.