文件结构选择器
CSS 文件结构选择器是非常基本的选择器,除了可以利用 HTML 文件结构的亲子关系选取元素,也能透过子代选择器“>”、兄弟选择器“~”或相邻兄弟选择器“+”的交互应用,快速找到 HTML 文件里的特定元素,这篇教学会介绍 CSS 文件结构选择器。
快速导览:
教学影片
搭配教学影片一起阅读,效果会更好!欢迎大家订阅 STEAM 教育学习网的 Youtube 频道。
HTML 文件结构的亲子关系
HTML 是个层层包覆的“树状结构”,在树状结构里,处于外层的元素称作“父元素”,内层元素称为“子元素”,父元素和子元素是一个“相对关系”,在身为别人的父元素的同时,可能也是另外一个元素的子元素,然而除了父元素和子元素,还有“子孙元素”、“祖先元素”和“兄弟元素”...等相对元素,而 CSS 文件结构选择器也就会根据 HTML 的结构,选取到对应的元素。
下图呈现一个简单的 HTML 树状结构:
后代选择器 ( 空白分隔 )
后代选择器撰写时“由左到右”列出每一代元素,元素之间使用“空白”分隔,并选取“最右侧”的元素,此处的空白称之为“结合子 combinator”,意思为“是...的一部分”,下方展示基本的撰写方式:
p a {color: red;} /* 選取 p 元素裡的「所有 a 元素」 */
nav ul li em a {color: red;} /* 選取 nav 元素裡的 ul 元素裡的 li 元素裡的「所有 em 元素」 */
除了单纯使用元素名称,也可以搭配 id、class 或属性等其他选择器使用,不过因为 id 选择器有其特殊性,通常会摆在最前方或独立撰写,下方的写法,会选取 id 为 oxxo 的元素里 class 为 fruit 元素里的“所有 a 元素”。
#oxxo .class a {color: red;}
如果搭配通用选择器“*”就代表“所有的”元素,下方的写法,会将 div 里所有的元素 ( 不包含 div 自己 ),不论在哪一层,都会变成红色文字。
div * {color: red;}
下方的网页有五个超链接 a 元素在 ul 清单元素里,也有另外一个 a 元素在 footer 元素中,虽然一开始透过 CSS 元素选择器定义了所有 a 的样式为绿色文字,但摆在清单里的 a 元素利用了 CSS 后代选择器定义样式,由于使用三个元素选择器,权重变成“0-0-3”,所呈现的样式就会是红色文字。
<!-- HTML 程式碼 -->
<ul>
<li><a href="http://oxxo.studio">oxxo.studio</a></li>
<li><a href="https://steam.oxxostudio.tw">STEAM</a></li>
<li><a href="https://www.google.com">Google</a></li>
<li><a href="https://www.apple.com">Apple</a></li>
<li><a href="https://www.github.io">Github</a></li>
</ul>
<footer>
<a href="about.html">about us</a>
</footer>
<!-- CSS 程式碼 -->
<style>
a {color: green;} /* 所有 a 的文字都是綠色,權重 0-0-1 */
ul li a {color: red;} /* ul 裡的 li 裡的所有 a 都是紅色,權重 0-0-3 */
</style>
子代选择器 ( > )
有别于后代选择器,子代选择器只会选择“下一层元素”( 也就是“儿子”概念 ),子代选择器使用“>”符号分隔,> 前后可以加上空白,加上的空白不具任何意义。例如下方的写法,会选取 p 元素里的“下一层 a 元素”。
p > a {color: red;}
因为 > 是选取“子元素”,如果位于“下一层之后”的元素,就不会被选取,例如下方网页执行后,前两个 a 元素位在第一层是子元素,所以会变成红色,而后两个 a 位在第四层,属于后代元素,所以就会呈现绿色。
<!-- HTML 程式碼 -->
<nav>
<a href="http://oxxo.studio">oxxo.studio</a>
<br/>
<a href="https://steam.oxxostudio.tw">STEAM</a>
<div>
<a href="https://www.google.com">Google</a>
<br/>
<a href="https://www.apple.tw">Apple</a>
</div>
</nav>
<!-- CSS 程式碼 -->
<style>
a {color: green;} /* 所有 a 的文字都是綠色 */
nav > a {color: red;} /* nav 的子元素 a 是紅色 */
</style>
子代选择器也可以搭配 class 选择器和属性选择器,做出更多的组合,但因为 id 选择器有其特殊性,通常会摆在最前方或独立撰写,不会穿插在结构选择器里,例如下方的写法,只有 div 子元素具有指定的 class 名称或属性才会变色。
<!-- HTML 程式碼 -->
<div>
<h2>oxxo.studio</h2>
<span>
<em class="name">oxxo</em>
</span>
<h3 class="name">hello world!!</h3>
<h3 name="oxxo">Good morning!!</h3>
</div>
<!-- CSS 程式碼 -->
<style>
.name {color: gray;} /* 所有 .name 都是灰色,權重 0-1-0 */
div > .name {color: red;} /* div 子元素的 .name 為紅色,權重 0-1-1 */
div > [name="oxxo"] {color: orange;} /* div 子元素屬性 name 為 oxxo 的元素為橘色,權重 0-1-1 */
</style>
搭配通用选择器“*”时表示“选取下一层的所有元素”,但因为文字相关样式具有“继承特性”,可能会影响下下层的样式,如果不希望下下一层的文字变色,就需要额外设定,下方范例虽然只作用于下一层元素,但因为文字颜色继承特性,导致下下层的文字也变色了。
<!-- HTML 程式碼 -->
<ul>
<li>
<span><em>我應該不會變色吧?</em></span>
</li>
<li>
<span> <em>想太多了,一定變色的呀</em></span>
</li>
</ul>
<!-- CSS 程式碼 -->
<style>
ul > * {color: red;}
</style>
兄弟选择器 ( ~ )
兄弟选择器表示“同一层并位于后方的特定元素”,兄弟选择器使用“~”符号分隔,~ 前后可以加上空白,加上的空白不具任何意义。例如下方的写法,会选取所有跟 h2 元素“同一层且位于后方”的 a 元素。
题外话,如果以中文文法来说,应该要叫“弟妹选择器”,而不是“兄弟选择器”。
h2 ~ a {color: red;}
因为 ~ 是选取“同一层且位于后方的元素”,如果位于“其他层”或“位于前方”的元素,就不会被选取,例如下方网页执行后,只有跟 h2 同层且在后方的 a 元素会变成红色,其他层的 a 元素以及在 h2 前方的 a 元素则会呈现绿色。
<!-- HTML 程式碼 -->
<nav>
<a href="#">因為我在 h2 前面,所以我是綠色~</a>
<h2>OXXO.STUDIO</h2>
<a href="http://oxxo.studio">oxxo blog</a>
<br/>
<a href="https://steam.oxxostudio.tw">STEAM</a>
<div>
<a href="https://www.google.com">Google</a>
<br/>
<a href="https://www.apple.tw">Apple</a>
</div>
</nav>
<!-- CSS 程式碼 -->
<style>
a {color: green;} /* 所有 a 的文字都是綠色 */
h2 ~ a {color: red;} /* 跟 h2 同層且位於後方的 a 是紅色 */
</style>
兄弟选择器也可以搭配通用选择器“*”,搭配后就会选择“同一层且位于后方的所有元素”,以下方网页为例,网页打开后,跟 h2 同层且位于 h2 后方的所有元素都会变成红色,但在其他层的元素以及位于 h2 前方的元素就不会变色。
<!-- HTML 程式碼 -->
<nav>
<a href="https://www.google.com">因為我在 h2 前方,所以我不會變色</a>
<h2>OXXO.STUDIO</h2>
<a href="http://oxxo.studio">oxxo blog</a>
<div>
<a href="https://www.google.com">我不會變色</a>
<br/>
</div>
<h3>我應該不會變色吧?</h3>
<h4>你一定變色的呀!</h4>
<span>天呀我變色啦!</span>
</nav>
<!-- CSS 程式碼 -->
<style>
a {color: green;} /* 所有 a 的文字都是綠色 */
h2 ~ * {color: red;} /* 跟 h2 同層且位於後方的所有元素都是紅色 */
</style>
相邻兄弟选择器 ( + )
相邻兄弟选择器表示“同一层的后一个元素”,相邻兄弟选择器使用“+”符号分隔,+ 前后可以加上空白,加上的空白不具任何意义。例如下方的写法,会选 h2 元素“同一层且下一个”的 a 元素。
h2 + a {color: red;}
因为 + 是选取“同一层的下一个元素”,如果位于“其他层”或“不属于下一个”的元素,就不会被选取,例如下方网页执行后,只有跟 h2 同层且下一个的 a 元素会变成红色,其他所有的 a 元素则会呈现绿色。
<!-- HTML 程式碼 -->
<div>
<a>我不會變色</a>
<h2>OXXO.STUDIO</h2>
<a>我會變色</a>
<br/>
<a>我不會變色哇哈哈</a>
<ul>
<li><a>我也不會變色</a></li>
<li><a>我也不會變色</a></li>
</ul>
</div>
<!-- CSS 程式碼 -->
<style>
h2 + a {color: red;}
</style>
如果选取的下一个元素“不是指定的元素”,就会找不到元素,例如下方范例中下个元素是 h3 而不是 a,就不会套用任何样式,最后就会呈现全部都是黑色文字的状况。
<!-- HTML 程式碼 -->
<div>
<a>我不會變色</a>
<h2>OXXO.STUDIO</h2>
<h3>我會變色嗎?</h3>
<a>我會變色嗎?</a>
<br/>
<a>我不會變色哇哈哈</a>
<ul>
<li><a>我也不會變色</a></li>
<li><a>我也不會變色</a></li>
</ul>
</div>
<!-- CSS 程式碼 -->
<style>
h2 + a {color: red;}
</style>
如果使用通用选择器“*”搭配相邻兄弟选择器,作用的范围就是选取“同层的下一个任意元素”,不论下一个元素是谁,选到了就会变色,如果将下方的 CSS 套用到刚刚的网页,就会发现 h3 变成了红色文字。
h2 + * {color: red;} /* 選取同層的下一個任意元素 */
小结
文件结构选择器是一个很方便的选择器,可以在不撰写任何 id、class 或属性的状况下,快速选择特定的元素,而相关的选取技术不仅限于 CSS,许多爬虫语法也都使用结构树的方式进行选取,因此这是必学的选取器喔。
微信扫码关注
抖音扫码关注