想要取消繼承來的 CSS 設定? 這種想法有點瘋狂! 這原本是不會出現的. 因為絶大部份的狀況下, 我們總是可以精細的調整 CSS 的 Selector, 來達成區分 CSS 的作用範圍. 除非... CSS 的繼承來源你動不了. 又或者像是我在 "CSS: Double Strikeout 雙刪除線" 這一篇貼文裡遇到的狀況: 想要在同一個頁面展示二種雙刪除線的 CSS 設定效果 (不動用 <iframe> tag). 這個時候正是本篇的主角 all: revert 這種另類 CSS 大展身手的時候.

前情提要


首先, 狀況是我原本有一套雙刪除線的 CSS 設定套用在所有貼文裡. 這套雙刪除線作法是: 設定 <del> tag 的 border-top, 並向下位移此 <del> tag 的位置, 然後再用一個 <span> tag 把文字位置移回來.

這套雙刪除線我用的 CSS Selector 是:

  • .article-content-inner del
  • .article-content-inner del > span.del

CSS 如下(註一):

.article-content-inner del {
	padding:0; margin:0;
	position: relative;
	top:calc(0.75em + 1px);
	left: 0;
	text-decoration:none;
	display: inline;
	border-top:calc(0.25em - 1px) double red
}
.article-content-inner del > span.del {
	padding:0; margin:0;
	position: relative;
	top:calc(-0.75em - 1px);
	left: 0;
}

可是, 後來發現, 這個 CSS 所產生的雙刪除線和我的放大圖片功能產生衝突: 排列在圖片段落後面的文字段落若有刪除線的文字片段, 當圖片放大時, 雙刪除線會出現在最上層 (即: 疊在圖片上). 我試著改變 z-index 也無法改善 (這個現象應該和我用 position: relative; 有關).

莫法度, 搬出谷歌大神, 另外找到了一個可用的設定: text-decoration-style: double. 而為了相容於舊貼文, 於是有以下的 CSS:

.article-content-inner del {
	text-decoration:red line-throught double;
	-webkit-text-decoration-line:line-through;
	-webkit-text-decoration-color:red;
	-webkit-text-decoration-style:double
}
.article-content-inner del > span.del { }

初步檢查沒有什麼問題, 於是大膽的在 2024/09/04 啟用新設定. 結果, 二週後發現新的設定在遇到上標字及下標字時就毀了, 而且在 PC 桌機上還與 Mobile 效果不同. 幾經求助谷歌大神及測試, 無果. 於是 2024/09/25 再度更動 CSS, 將設定倒回去原本的舊設定.

不過, 另外一個問題隨即產生: 我想在 "CSS: Double Strikeout 雙刪除線" 這一篇貼文裡記錄並展現這二套雙刪除線設定的效果. 於是有了本文.

註一: 這個不是最終版本, 最終版本請參考 "CSS: Double Strikeout 雙刪除線" 這一篇貼文的 "更新 2024/10/04"

解決方法


由於這二套 CSS 的 Selector 完全一致, 而且又有原本要套用在全部貼文的 CSS 設定(註一), 於是第一步就是先將二個展示段落各自指定一個 id 屬性 (我用 id='demo1'id='demo2'). 然後, 我們就可以修改一下原本的 CSS selector, 用於展示第一套 CSS 設定的 Selector:

  • #demo1 del
  • #demo1 del > span.del

用於展示第二套 CSS 設定的 Selector:

  • #demo2 del
  • #demo2 del > span.del

然後該 all: revert 出瑒了.

#demo1 *,
#demo2 * { all: revert }

最後用於該篇文章 (CSS: Double Strikeout 雙刪除線) 的 CSS 如下:

#demo1 *,
#demo2 * { all: revert }
#demo1 del {
	padding:0; margin:0;
	position: relative;
	top:calc(0.75em + 1px);
	left: 0;
	text-decoration:none;
	display: inline;
	border-top:calc(0.25em - 1px) double red
}
#demo1 del > span.del {
	padding:0; margin:0;
	position: relative;
	top:calc(-0.75em - 1px);
	left: 0;
}
#demo2 del {
	text-decoration:red line-throught double;
	-webkit-text-decoration-line:line-through;
	-webkit-text-decoration-color:red;
	-webkit-text-decoration-style:double
}
#demo2 del > span.del { }

下面的 CodePen 顯示四種效果: 1st Set 及 2nd Set 使用第一套雙刪除線設定, 但 2nd Set 改為使用 'border-bottom', 3rd Set 用第二組雙刪除線設定, 4th Set 沒有套用雙刪除線設定.

另外, 這個 demo 的 1st Set 和 2nd Set 我用了 CSS 變數, 方便我觀察/測試雙刪除線的 border 的內緣高度. 經過實驗及計算, 這個數值是 1.11em, 計算公式是: 2 x offset中心 - border-width = 1.11em. 你如果不滿意我設定的位置, 可以自行用 calc() 去微調它.

See the Pen Double Strikeout by Jack Ting (@magicjack) on CodePen.

註一: 即使其中一套是現有的選擇, 但是萬一日後雙刪除線的設定又有所更動, 總不能又要回到 "CSS: Double Strikeout 雙刪除線" 這一篇貼文裡重新檢查並更正一遍吧?

Bonus 1


後來順便研讀了一下 mdn web docs 有關 z-index 的文章: Stacking context. 於是有了解決第一套雙刪除線問題的思路: 由於 position:relative 的元件堆疊位置僅次於 root 位於第二層, 所以修改其他元件的 z-index 並無法修正此一問題. 但是, 如果把圖片本身也改為: position:relative, 那麼設定 z-index:100 圖片就一定會疊在雙刪除線的上頭. 嗯~~不錯, 完美!

完整的解決方案請參看: "CSS: Double Strikeout 雙刪除線" 這一篇貼文的 "更新 2024/10/04".

Bonus 2


順帶一提: unsetrevert 的差異:

  • revert: 是用來取消 CSS 的設定, 回復至 browser 的初始設定(註二). 可以取消個別設定, 也可以用 all: 來將全部的設定取消.
  • unset: 功能與 revert 相似 (絕大多數的情境下是相同的), 但對於某些元件和某些屬性這二者是不同的. 例如: 下面這個來自 mdn web docs:revevert 的例子 (有稍微修改了一下):
    我們設定了 font-weight, 但試著在 <h3> tag 上使用 inline 的方式將之清除掉.
    <h3>
      This should have font-weight:normal and but color: green
    </h3>
    <p>Just some text</p>
    <h3 style="font-weight: revert; color: revert;">
      This should have its original font-weight (bold) and color: blue
    </h3>
    <p>Just some text</p>
    <h3 style="font-weight: unset; color: unset;">
      This will still have font-weight: normal, but color: blue
    </h3>
    <p>Just some text</p>
    
    結果如例子本身說明: 第一個 <h3> tag 只套用 CSS 的設定, 沒有使用 revertunset. 第二個 <h3> tag 使用 revert 結果回復到 browser 預設值, 所以字型是粗體的. 第三個 <h3> tag 使用 unset 結果它的設定值被消除了, 但依舊會由 <body> tag 繼承 font-weight, 所以字型不是粗體的.
    但二者的顏色可都會繼承自 <body> tag.

    See the Pen Untitled by Jack Ting (@magicjack) on CodePen.

註二: 原文是: it resets the property either to user agent set value, to user set value, to its inherited value (if it is inheritable), or to initial value.

arrow
arrow
    創作者介紹
    創作者 MagicJackTing 的頭像
    MagicJackTing

    傑克! 真是太神奇了!

    MagicJackTing 發表在 痞客邦 留言(0) 人氣()