em & rem
em
在 CSS 中,em 是相对于“当前元素”的字体大小而言的。其中,1em 就等于“当前元素” 字体大小。这里的字体大小指的是以 px 为单位的 font-size 值。
em 的使用又三个小技巧:使用 text-indent:2em
实现首行缩进;使用 em 作为统一单位,所有浏览器的默认字体大小都为 16px;使用 em 作为单位定义字体大小,当需要改变页面文字大小时,只需要改变根元素大小即可。
rem
rem,全称 font size of the root element,是指相对于根元素(即 html 元素)的字体大小,区别于 em,em 是相对当前元素的字体的大小,而 rem 是相对根元素的字体的大小。
CSS 特性
继承性
继承性是指子元素继承了父元素的某些样式属性。在 CSS 中,具有继承性的属性有三类:
▶ 文本相关属性:font-family、font-size、font-style、font-weight、font、line-height、 text-align、text-indent、word-spacing。
▶ 列表相关属性: list-style-image、list-style-position、list-style-type、list-style。
▶ 颜色相关属性:color。
层叠性
CSS 的层叠性,指的就是样式的覆盖。对于同一个元素来说,如果我们重复定义多个相同的属性,并且这些样式具有相同的权重时,CSS 会以最后定义的属性值为准,也就是遵循“后来者居上”原则。 其意义在于:当一个元素受到多方面影响时,最终使用哪种样式。
这里的“后来居上”要满足三个条件:元素相同,属性相同,权重相同。
优先级
当样式的覆盖发生冲突时,以优先级高的为准,当“同一 个元素”的“同一个样式属性”被运用上多个属性值时,我们就需要遵循一定的优先级规则来选择一个属性值了。有五种常见的样式覆盖引发的冲突。
引用方式冲突
已知 CSS 有 3 种常用的引用方式:外部样式、内部样式和行内样式。CSS 因引用方式的不同,也会产生冲突。三种方式优先级如下:
如果内部样式与外部样式同时存在,以最后引用的样式为准。
<link rel="stylesheet" href="index.css">
<style>...</style>
两行前后顺序对结果造成的影响。
继承方式冲突
如果是由于继承方式引起的冲突,则“最近的祖先元素”获胜。
<div id="grandfather">
<div id="father">
<div id="son">...</div>
</div>
</div>
指定样式冲突
所谓的指定样式,指的是指定“当前元素”的样式。当直接指定的样式发生冲突时,样式权重高者获胜。
常见的伪元素只有 4 个:::before、::after、::first-letter 和 ::first-line。伪类我们经常见到, 如 hover、:first-child 等。常用的选择器优先级如下。之前提到过,当选择器权重相同时,遵循后来者居上原则。
::before p::before 在每个 <p> 的内容之前插入内容。
::after p::after 在每个 <p> 的内容之后插入内容。
::first-letter p::first-letter 选择每个 <p> 元素的首字母。
::first-line p::first-line 选择每个 <p> 元素的首行。
注:选择器权重的计算只针对指定样式(当前元素),并不能用于继承样式。 该先判断指定样式,然后再去考虑继承样式
扩展链接:[**CSS 选择器参考手册**](https://www.w3school.com.cn/cssref/css_selectors.asp)
继承样式和指定样式冲突
继承样式和指定样式发生冲突时,指定样式获胜。
!important
在 CSS 中,我 们 可 以 使 用 !important 规则改变样式的优先级。 如果一个样式使用“!important”来声明,则这个样式会覆盖 CSS 中其他的任何样式声明 。
如果你一定要使用某个样式属性值,为了不让它被覆盖,则可以使用 !important 来实现。换句话说,如果想要覆盖其他所有样式,可以使用 !important 来实现 。
<div id="outer">
<p class="inner">
<span><strong>绿叶学习网</strong></span>
</p>
</div>
#outer strong
{
/*权重=100+1=101*/
color:red;
}
#outer .inner strong
{
/*权重=100+10+1=111*/
color:green;
}
.inner strong
{
/*权重=10+1=11*/
color:blue;
}
.inner span strong
{
/*权重=10+1+1=12*/
color:purple;
}
strong
{
color:black !important;
}
!important 用法
#someID p{color:red}
p{color:green}
外层有 #someID 的情况下,如果不适用 !important,第一条样式永远比第二条样式优先级更高。
另外就是直接覆盖一些效果不好的行内样式。(回顾行内样式:行内样式就是直接把CSS代码添加到HTML的标记中,即作为HTML标记的属性标记存在。通过这种方法,可以很简单地对某个元素单独定义样式。)
覆盖 !important
▶ 使用相同的选择器,在后面添加一条 !important 语句。
▶ 使用更高优先级的选择器,再添加一条 !important 语句。
小结
纸上得来终觉浅,绝知此事要躬行。先理解一遍,以后的编写页面的过程中在慢慢体会,不必死记硬背。这里可以总结为两点:
▶ 优先级高的样式覆盖优先级低的样式。
▶ 同一优先级的样式,后定义的覆盖先定义的,即“后来者居上原则”。
CSS 引用方式
已知的三种引用方式:外部样式表,内部样式表,行内样式表。除此之外,还有一种 @import 方式(导入样式表)。该方式与外部样式表很相似,但实际开发中很少使用该方式,更多的使用 link 方式,原因是 @import 方式先加载 HTML 后加载 CSS,而 link 刚好相反,如果先加载 HTML,页面用户体验会非常差。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!--这是外部样式,CSS样式在外部文件中定义-->
<link href="index.css" rel="stylesheet" type="text/css" />
<!--这是内部样式,CSS样式在style标签中定义-->
<style type="text/css">
p{color:Red;}
</style>
</head>
<body>
<!--这是行内样式,CSS样式在元素style属性中定义-->
<p style="color:Blue;">绿叶学习网</p>
<p>绿叶学习网</p>
<p>绿叶学习网</p>
</body>
</html>
内外部样式表以及行内样式表并非非此即彼,而是相互搀扶,共同作用于页面: **外部样式表多用于公有样式,内部样式表多用于私有样式,而行内样式表则多用于小修改或者优先级方面。**
CSS 选择器
CSS 选择器就是把你想要的标签选中的一种方式。把它选中了,才能操作标签的 CSS 样式。CSS 中提供了很多将标签选中的方式,这些不同的方式就是不同的选择器 。
已知的简单的选择器包括元素选择器,id 选择器,class 选择器,群组选择器。
层次选择器,指的是通过元素之间的层次关系来选择元素,在实际开发中非常重要,常见的层次关系包括父子,后代,兄弟,相邻等关系。
后代选择器
后代选择器用于选中元素内部的某一个元素,包括子元素和其他的后代元素。语法:M N{}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#first p
{
color: red;
}
</style>
</head>
<body>
<div id="first">
<p>lvye的子元素</p>
<p>lvye的子元素</p>
<div id="second">
<p>lvye子元素的子元素</p>
<p>lvye子元素的子元素</p>
</div>
<p>lvye的子元素</p>
<p>lvye的子元素</p>
</div>
</body>
</html>
所有的语句都被标为红色
#first p 表示选中 id="first" 的元素内部所有的 p 元素,因此不管是子元素还是其他后代元素,全部都会被选中。
子代选择器
用于选中元素内部的某一个子元素,语法:M>N{}
。与后代选择器相似,但两者也有区别:
▶ 后代选择器选中的是元素内部的所有元素(包括子元素)
▶ 子代选择器,选中的是元素内部的某一个子元素(只限子元素)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#first>p
{
color: red;
}
</style>
</head>
<body>
<div id="first">
<p>lvye的子元素</p>
<p>lvye的子元素</p>
<div id="second">
<p>lvye子元素的子元素</p>
<p>lvye子元素的子元素</p>
</div>
<p>lvye的子元素</p>
<p>lvye的子元素</p>
</div>
</body>
</html>
只有“lvye的子元素”语句被标记为红色
first>p 表示选中 id=”first” 的元素下的子元素 p。可以清楚的看到与后代选择器相比,子代选择器只选择子元素,不包括其他后代。
兄弟选择器
用于选中元素后面(不包括前面)的所有某一类兄弟元素,语法:M~N{}
。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#second~p
{
color: red;
}
</style>
</head>
<body>
<div id="first">
<p>lvye的子元素</p>
<p>lvye的子元素</p>
<div id="second">
<p>lvye子元素的子元素</p>
<p>lvye子元素的子元素</p>
</div>
<p>lvye的子元素</p> /*注意这里 p 和 div 是兄弟元素*/
<p>lvye的子元素</p>
</div>
</body>
</html>
只有最后两行语句为红色
second~p 表示选中 id=”second” 的元素后面的所有兄弟元素 p。兄弟选择器只选中后面的所有兄弟元素,不包括前面的所有兄弟元素。
相邻选择器
用于选中元素后面的某一个相邻的兄弟元素,语法:M+N{}
,相邻选择器跟兄弟选择器非常相似,不过也有明显区别:
▶ 兄弟选择器选择元素后面所有的某一类元素。
▶ 相邻选择器选中元素后面相邻的某一个元素。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#second+p
{
color: red;
}
</style>
</head>
<body>
<div id="first">
<p>lvye的子元素</p>
<p>lvye的子元素</p>
<div id="second">
<p>lvye子元素的子元素</p>
<p>lvye子元素的子元素</p>
</div>
<p>lvye的子元素</p>
<p>lvye的子元素</p>
</div>
</body>
</html>
倒数第二行被改为红色
second+p 表示选中 id=”second” 的元素后面的“相邻”的兄弟元素 p。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
/*去除所有元素默认的padding和margin*/
* {padding: 0;margin: 0}
/*去除列表项默认符号*/
ul {list-style-type: none;}
li+li {border-top: 2px solid red;}
</style>
</head>
<body>
<ul>
<li>第1个元素</li>
<li>第2个元素</li>
<li>第3个元素</li>
<li>第4个元素</li>
<li>第5个元素</li>
<li>第6个元素</li>
</ul>
</body>
</html>
除了第一行,每一行顶部都有红线
li+li 使用的是相邻选择器,表示选中 li 元素相邻的下一个 li 元素,由于第一个 li 元素上面没有兄弟,所以不含边框。
first - letter / line
first - line{}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div:first-line
{
color:hotpink;
}
</style>
</head>
<body>
<div>撑伞接落花,<br/>看那西风骑瘦马。</div>
</body>
</html>
“撑伞接落花,”为粉色,后面为黑
first - letter{}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div:first-letter
{
font-size:30px;
color:hotpink;
}
</style>
</head>
<body>
<div>奔跑吧,骄傲的少年</div>
</body>
</html>
只有“奔”被加上效果
小结
以上便是 CSS2.1 中关于选择器的部分常用内容,除此之外还有很多其他方式的选择器使用,不过多为 CSS3 新增,在之后还会遇到。
扩展链接:CSS 选择器参考手册