2023年10月7日 星期六

css checkbox hack

我在製作一個公車到站時刻的 html 表格, 其中有兩個欄位顯示一些 x/y 座標數字。 多數訪客對這些數字可能沒興趣, 說不定看了還會頭昏嫌煩。 所以我想用一個 checkbox 讓訪客可以自行決定要顯示還是隱藏那兩個欄位。 可是我又希望我的網頁不需要啟用 javascript 也可以看。

於是搜尋到一個方法, 叫做 "(css) checkbox hack": 精簡範例中文教學豐富教學。 簡單地說, 你需要一個 checkbox (叫它 C 好了)、 一個與 C 連動 (按它等同於按 C) 且顯示說明文字的 label (叫它 L 好了)、 以及一個外觀會隨著 C 的狀態而改變、 被 C 控制的標的物 (叫它 T 好了)。 像這樣:

<head>
<style>
.affected-Target {
  background: #ffc;
}

#bgControl:checked ~ .affected-Target {
  background: #cff;
}
</style>
</head>

<body>
<input type="checkbox" id="bgControl">
<label for="bgControl">改變背景顏色</label>
<span class="affected-Target">Hello world!</span>
</body>

我喜歡較簡潔的語法, 於是小改一下: 把 label 包在 checkbox 外面, 結果它就失效了。 因為關鍵語法裡的 "~" 表示 sibling, 也就是 T 的某祖先必須是 C (在 html 裡面) 的弟弟。 (C 一定要比 T 及它的祖先先出現!) 可是把 C 放到 L 外面, 如果想排版, 總還是必須把兩者包在同一個 div 裡面; 如果包在一起, T 又變成 C 的叔叔而不是它弟弟的子孫, checkbox hack 又會失效。 就是兩難。 難怪很多教學文都教大家乾脆把 C 變不見。

可以打破這個限制嗎? 找到 這個解答: 用 (平常用於超連結的) "a"。 可是我要用一個 C 來控制整個表格的兩欄裡面的很多格; 而這個方法每個 C 只能控制單獨一個 T, 所以這也不符合我的需求。

事實上, 也有其他人反應: checkbox hack 在 table 裡面會失效。 不過最終總算試出來: C 可以控制兄弟弟弟 的子孫, 即使是表格裡面的東西也可以: 最終成果。 重點是 css 裡面的這一段:

input[type=checkbox] { display: none }
.for-checkbox {
    background-color: #eec;
    /* color: green; */
    cursor: pointer;
}

.pos {
    text-align: right;
    font-size: 0%;
}

#pos-tgl:checked ~ table td.pos ,
#pos-tgl:checked ~ table th.pos {
    /* background: #8ff; */
    font-size: 100%;
}

#pos-tgl:checked ~ p #lb-pos-tgl { background-color: #fff; }
  1. 把所有的 checkbox 通通變不見。
  2. 滑鼠一進入 L (所有 class 值包含 for-checkbox 的元件) 就要改變形狀, 提醒訪客 「這可以按」。
  3. T (所有 class 值包含 pos 的元件) 的預設字型大小為 0。
  4. 每當 C (id 為 pos-tgl 的那個元件) 被按下時, 它弟弟當中若有 table, 這表格裡凡是被設成 T 的 td 跟 th 子元件, 它們的字型都恢復正常大小。
  5. 每當 C 被按下時, 它的 p 類型弟弟裡面名為 #lb-pos-tgl 的子孫 (就是 L 啦) 的顏色也同時改變。

不是非常漂亮, 但我要的功能有做到就好了, 那就收工吧。 是說我對 css 超級沒興趣, 從來沒認真學過, 小格也連一個 css tag 都沒有, 反而偶有一點心得就筆記這麼多 :-)

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。