iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0

https://i.imgur.com/5l78IuW.jpg

組件實作 : Demo

一、前言

在寫某些專案或者是練習,時不時會看到::before::after這類元素的用法,在第一次接觸時,總是會感到困惑,不清楚這些元素該如何使用,畢竟加了個兩個冒號很難明白它的用途。為了更加了解這類的「冒號家族」,以及有哪些成員,本篇文章要來初探偽元素偽類的相關用法。

只要將變數名稱前後加上各種符號,大腦就會難以理解。例如:↙煞氣a小明↗


二、偽元素

2.1 偽元素種類

偽元素的用法參考了 MDN 的介紹【1】,下方列出(測試中的不實作)。

偽元素 功能
::before 在該元素之前加入元素。
::after 在該元素之後加入元素。
::first-letter 選取該元素的第一個字元。
::first-line 選取該元素的第一行。
::selection 文字選取時作用。

2.1 Before 和 After

Before 和 After 是使用頻率最高的偽元素,並且它們的用法也十分相似,只是擺放的位置不一樣,所以它們也可以放在一起討論。 Before 和 After 的用法其實原理很簡單,就是選擇要放在左邊(Before)或是右邊(Before)的概念,這是什麼意思?舉個例子,假設老闆要你設計一張有 100 道料理的電子菜單,於是你把菜單大致架構建立好:

https://i.imgur.com/uoDYS0h.jpg

當你把做好的架構拿去給老闆看,老闆跟你說需要把價格的部分,加上 「$ 」的符號與「元」字,也就是「 200」 變成「$200 元」,這時候你發現資料那麼多,一個一個 key 字也太慢了,有沒有更快的方法呢?

於是你觀察了一下你的 HTML 結構,發現你在數字的地方有加入 span 標籤元素(這個好習慣就了你一命),有了 span 標籤,這代表了我可以直接針對數字的部分去做處理,那麼現在問題來了:「我該如何將文字插入到我的 Menu 之中呢?」這時候就可以使用 before 和 after 元素來完成啦~

HTML:(Menu 假設有 100 筆料理)

<div class="menu">
	<ul>
		<li>
			<p>好吃的飯 <span>120</span></p>
		</li>
		<li>
			<p>好吃的麵 <span>120</span></p>
		</li>
		<li>
			<p>好吃的肉 <span>180</span></p>
		</li>
		<li>
			<p>超好吃的飯 <span>150</span></p>
		</li>
		<li>
			<p>超好吃的麵 <span>150</span></p>
		</li>
		<li>
			<p>超好吃的肉 <span>220</span></p>
		</li>
		<li>
			<p>最好吃的飯 <span>120</span></p>
		</li>
		<li>
			<p>最好吃的麵 <span>120</span></p>
		</li>
		<li>
			<p>最好吃的肉 <span>180</span></p>
		</li>
		<li>
			<p>普通的飯 <span>500</span></p>
		</li>
		. . .
	</ul>
</div>

CSS:

span::before {
	content: "$";
}

span::after {
	content: " 元";
}

顯示結果:

https://i.imgur.com/I9HqXn3.jpg

要使用 Before 和 After,一定要記得加上content屬性,否則這兩個偽元素會沒有作用,若是你想加入圖片,沒有任何的字需要加入,這時的content屬性只要加入空字串即可。

值得注意的一個特性是:「必須要有結束標籤的 HTML 元素才可以使用 Before 和 After」。原因是因為content必須是要能插入內容的元素才能使用,舉例來說,像是 p 標籤、h2 標籤這種有結束標籤的元素才能存放內容,而像 input 這種標籤則無法使用 before、after 偽元素。

before、after 介紹可以參考這篇【2】

2.2 first-letter 和 first-line

這兩個偽元素,都是用於選取文字的範圍,例如,first-letter 是指選取字首的第一個字。而 first-line 則是選取第一行文字。我們使用上一個小節的 Menu 例子來舉例說明。

假設今天要升級 Menu,消費者想知道料理的材料是什麼,才能安心的食用。於是我們把 Menu 補上了食材的相關資訊,其修改的程式碼如下。

HTML:

<div class="menu">
	<ul>
		<li>
			<p>好吃的飯 <span>120</span>
				<br>食材:飯 + 鹽巴 + 好吃
			</p>

		</li>
		<li>
			<p>好吃的麵 <span>120</span>
				<br>食材:麵 + 鹽巴 + 好吃
			</p>
		</li>
		<li>
			<p>好吃的肉 <span>180</span>
				<br>食材:肉 + 鹽巴 + 好吃
			</p>
		</li>
		<li>
			<p>超好吃的飯 <span>150</span>
				<br>食材:飯 + 鹽巴 + 超好吃
			</p>
		</li>
		<li>
			<p>超好吃的麵 <span>150</span>
				<br>食材:麵 + 鹽巴 + 超好吃
			</p>
		</li>
		<li>
			<p>超好吃的肉 <span>220</span>
				<br>食材:肉 + 鹽巴 + 超好吃
			</p>
		</li>
		<li>
			<p>最好吃的飯 <span>288</span>
				<br>食材:飯 + 鹽巴 + 最好吃
			</p>
		</li>
		<li>
			<p>最好吃的麵 <span>288</span>
				<br>食材:麵 + 鹽巴 + 最好吃
			</p>
		</li>
		<li>
			<p>最好吃的肉 <span>388</span>
				<br>食材:肉 + 鹽巴 + 最好吃
			</p>
		</li>
		<li>
			<p>普通的飯 <span>500</span>
				<br>食材:飯 + 一片牛肉 + 普通
			</p>
		</li>
		. . .
	</ul>
</div>

這時老闆看了看 Menu,覺得料理名稱不夠顯眼,希望能將料理名稱的字設為綠色,而且每道料理名稱的第一個字體要放大並且要更改文字背景顏色。

看完了上述的需求,這裡想直接採用 first-letter 和 first-line 來實作會比較方便,因為使用偽元素,不用更改HTML的架構,只要加上 CSS 即可修飾元素,這樣實作起來比較方便,而使用的程式碼如下。

CSS:

p::first-line {
	color: green;
}

p::first-letter {
	font-size: 1.5rem;
	color: rgb(255, 255, 185);
	background: #000;
}

顯示結果:

https://i.imgur.com/gPFGuuj.jpg


三、偽類

偽類和偽元素在使用符號上會讓人感到困惑,原因是因為偽類使用一個冒號,偽元素使用兩個冒號。這裡先列出偽類相關的表格。

偽類
:hover
:focus
:checked
:first
:first-child
:last-child
:nth-child()
:nth-last-child()
:root
:target
:visited

還沒實作,先保留下來,實際上還有其它的偽類【3】,慢慢摸索用法。

如果你忘記那個冒號對應偽類和偽元素,這裡提供一個區分口訣:「偽類,會累,單邊眼淚」,所以偽類是一個冒號。或是你知道獵人裡的西索,看他的臉上的假圖案(星星和水滴圖案是用畫的、是假的」,這樣就能聯想:「偽元素是假的,而且有兩個冒號。」


四、推薦資源

  1. 偽類和偽元素
  2. CSS | 全都是假的!關於那些偽類和偽元素 - 基本用法
  3. CSS 虛擬 (偽) 類別選擇器 (Selector) 教學範例
  4. 【自學程式】好用的 CSS 偽類選擇器 :nth-child() 與 :nth-of-type()
  5. 關於 CSS 偽元素的那些小事

五、結論

本篇的架構使用一個 Menu 的例子來說明,在第二章介紹了各種偽元素的使用時機,而第三章這是區分了偽類和偽元素的方法,希望看完這篇文章,可以清楚的明白:「偽元素不是只有 Before 和 After,偽類也不是只有 hover 可以使用」,還有其他的類和元素也是可以利用的,有機會的話再補上其他的用法,今天內容到這邊結束,感謝收看!


六、參考資料

  1. 標準偽元素索引
  2. 全都是假的,一起來認識偽元素!
  3. 虛擬類別- CSS

上一篇
Day 14:JS ES6 學習筆記
下一篇
Day 16:Gulp 學習筆記
系列文
手刻武器庫,30 天前端學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言