語意化的 CSS 設定 (Contextual awareness) 減少 side effect

前幾天在 Hacker News 上看到 CSS-Tricks 上的文章「You want enabling CSS selectors, not disabling ones」這篇,在講 CSS 的設計問題,對應的 Hacker News 討論在「You want enabling CSS selectors, not disabling ones (css-tricks.com)」這邊。

文章裡面引用文章裡面提到的文章也都蠻值得看的:「You want enabling CSS selectors, not disabling ones (2021/03/08)」、「Axiomatic CSS and Lobotomized Owls (2014/10/21)」。

其中 2014 年那篇居然是 A List Apart 上的文章,好久沒看到了這個站了... 也發現居然不在 RSS/Atom feed 清單裡面,重新訂起來。

這邊拿 A List Apart 上面的圖來說明,出自「CONTEXTUAL AWARENESS」這個段落的例子。

在很多段落時,我們常使用 margin-top (或是 margin-bottom,例子可以自己變換) 來設定間距,也就是 (a) 的例子。但可以看到第一個元素就會「多出來」:

A List Apart 裡面提到的解法是 * + * (或是 p + p,看你怎麼選 CSS selector),也就是前面有相鄰的元素才需要設定 margin-top

回到 CSS-Tracks 上的文章,有些人會這樣指定 CSS (這邊用 margin-bottom,所以搭搭配的是 :last-child):

.card {
  margin-bottom: 1rem;
}

/* Wait but not on the last one!! */
.parent-of-cards :last-child {
  margin-bottom: 0;
}

也就是全部都先加上 margin-bottom,然後針對最後一個元素拿掉 margin-bottom。而另外的版本則是:

.card:not(:last-child) {
  margin-bottom: 1rem;
}

或是:

/* Only space them out if they stack */
.card + .card {
  margin-top: 1rem;
}

這樣就不用蓋來蓋去,可以降低 side effect:margin-bottom 可能會在其他地方指定,你設為 0 可能是不對的值;另外寫成兩組時 CSS 的優先順序其實是不同的,Mozilla 的 Specificity 可以參考,Specifishity 這個網站給了很有趣的 cheatsheet (你要先了解才能當 cheatsheet 用):

在文章最後面有提到 gap 這個用法,查了一下「CSS property: gap: Supported in Grid Layout」,看起來現代的瀏覽器應該是都支援了,不過如果要支援舊的瀏覽器的話就是問題...

另外順便提一下,早期大家會偏好用 + 是因為 IE7+,而 :last-child 則是 IE9+ 了:「CSS Selectors and Pseudo Selectors and browser support」。雖然現在看起都是時代的眼淚了,但可以了解一下 2014 年的時候為什麼會偏好 + 的設計。

用 CSS Selector 產生 RSS feed

Hacker News 首頁看到「Show HN: RSS feeds for arbitrary websites using CSS selectors (vincenttunru.com)」這個,程式在 GitLab.com 上的「Feed me up, Scotty!」這邊,另外這個專案名稱是在玩 Star Trek 的梗:「Beam me up, Scotty」,然後這邊講的 RSS feed 已經算是通稱了,實際上大家都是輸出 Atom

他用的設定檔格式是 TOML,文章給的範例:

[funfacts]
title = "Wikipedia — did you know?"
url = "https://en.wikipedia.org/wiki/Main_Page"
entrySelector = "#mp-dyk > ul li"
titleSelector = "b"
linkSelector = "b a"

[wikivoyage]
title = "Wikivoyage recommendations"
url = "https://en.wikivoyage.org/wiki/Main_Page"
entrySelector = ".jcarousel-wrapper .jcarousel-item"
titleSelector = "h2"
linkSelector = "h2 a"

feed-me-up-scotty/src/index.ts 這邊看起來是 TypeScript 專案,然後用 browser 帶起 Firefox 來,可以預期會吃不少資源...

另外 Hacker News 的討論裡有另外提到「Feed Creator」,看起來也是個不錯的專案,有免費版與付費版...

Chromium 的 :has() 實做進展

前陣子在「Chromiu 看起來正在實做 CSS4 的 :has()」這邊提到了 Chromium:has() 實做,對應的票在「Issue 669058: CSS selectors Level 4: support :has()」這邊,不過看起來當時沒有實做完整,而且有測出問題:

The following css/selectors  web tests are failing on below platform:

css/selectors/has-basic.html - Failing on chrome/edge/firefox/safari/webkit
css/selectors/parsing/parse-has.html - Failing on chrome/edge/firefox/safari/webkit

昨天又看到新進度了:「Supports all ':has' relative argument cases」。

Supports all ':has' relative argument cases

Currently the relative selector is not supported yet, so this CL
provides the relative argument cases as follows.
 - :has(:scope > <complex-selector>)
 - :has(:scope ~ <complex-selector>)
 - :has(:scope + <complex-selector>)

看起來補上了之前沒實做的部份。更完整的討論過程可以參考 Gerrit 的「Supports all ':has' relative argument cases」這邊。

沒問題的話應該就是時間的問題了,也許三個月到半年左右?

Chromium 看起來正在實做 CSS4 的 :has()

先前一直都有在盯著「Issue 669058: CSS selectors Level 4: support :has()」這個,主要是有這個功能會對於很多應用很方便,無論是對 designer 在設計上,或是對 javascript developer 的操作。

Chromium 上對應的 commit 在「Supports :has() pseudo class matching」這邊,可以看到目前只實做了一部分:

So this CL only supports :has argument selectors starting with
descendant combinator. Argument selectors starting with other
combinators are not supported yet.
 - .a:has(.b)    : Supported
 - .a:has(> .b)  : Not supported yet
 - .a:has(~ .b)  : Not supported yet
 - .a:has(+ .b)  : Not supported yet

但至少是個進展了...

簡易的 jQuery CSS Selector 替代品

在追 refined-twitter 程式碼的時候,在「refined-twitter/extension/content.js」這邊看到:

const $ = document.querySelector.bind(document);

這樣就可以拿 CSS Selector 掃出元件,程式變得比較好讀... 當然,這個方式不是 fluent interface,沒辦法再依樣串下去。

Google 查了一些資料,看起來至少從 2013 年就有這個技巧了。

jQuery 1.11.2 與 2.1.3 修正 iOS 8 上 Safari 7.1/8 的嚴重 bug

看到 jQuery 官方放出一個特別更新,專門為了 iOS 8 + Safari 7.1/8 的修正:「jQuery 1.11.2 and 2.1.3 Released – Safari Fail-Safe Edition」。

依據「Test failure on iOS 8: child and adjacent -> p#firstp + p」的說明,死在 document.querySelectorAll("p#firstp + p") 這邊,另外以下的 selector 也都掛掉:

p#a + p
p#a ~ p
.b#a ~ [id]
[style]#a ~ p

由於這個用法太基本,讓 jQuery 官方決定在 library 放 workaround 修正這個問題...

微軟推出 IE6 Countdown 網站

微軟推出了 IE6 Countdown 網站,希望可以把 IE6 的佔有率壓到 1% 以下。以目前網站上更新的數字,台灣是 10.7%...

不過上面的數字是以 2011/2/28 的數據產生出來的,這天雖然是星期一,但台灣剛好是國定假日,使用公司電腦的人少很多,這使得使用 IE 的人也少很多 (可以參考 StatCounter 的數據)。如果抓平常日的數字,大約在 14% 上下,超過印度的 12.3%。

IE6 是 2001 年 8 月 27 日出版,快要滿十年了,不知道有沒有機會在十週年生日前 (七月的報表) 看到他 5% 以下...

如果可以不用管 IE6 的話,有什麼好處呢?先不論 bug 的問題,光是網頁設計時的 css selector 就多出許多可以用:(圖片來自「CSS selectors and pseudo selectors browser compatibility」)