A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>When Our Tools Hold Us Back (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <meta name="robots" content="noindex, nofollow">
  53. <meta content="origin-when-cross-origin" name="referrer">
  54. <!-- Canonical URL for SEO purposes -->
  55. <link rel="canonical" href="https://www.oddbird.net/2022/11/11/platform-tools/">
  56. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  57. <article>
  58. <header>
  59. <h1>When Our Tools Hold Us Back</h1>
  60. </header>
  61. <nav>
  62. <p class="center">
  63. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  64. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  65. </svg> Accueil</a> •
  66. <a href="https://www.oddbird.net/2022/11/11/platform-tools/" title="Lien vers le contenu original">Source originale</a>
  67. </p>
  68. </nav>
  69. <hr>
  70. <p>The
  71. <a href="https://almanac.httparchive.org/en/2022/">2022 Web Almanac</a>
  72. has been out for a while,
  73. and (as always)
  74. it’s an interesting<span class="widont"> </span>read.</p>
  75. <p>There are more than 20 chapters this year,
  76. and I haven’t read them all.
  77. But I did enjoy the chapters on
  78. <a href="https://almanac.httparchive.org/en/2022/css"><span class="caps">CSS</span></a>
  79. (by Rachel Andrew)
  80. and <a href="https://almanac.httparchive.org/en/2022/fonts">webfonts</a>
  81. (by Bram Stein).
  82. Both authors note a similar trend –
  83. <strong>many usage patterns
  84. that refuse to change from year to year
  85. can be explained by popular<span class="widont"> </span>tools</strong>.</p>
  86. <p>I’ve noticed that same effect elsewhere,
  87. and I want to dig into it a bit –
  88. the various ways our tooling
  89. can change (and limit)
  90. the web platform features we<span class="widont"> </span>use.</p>
  91. <p class="anchor-link-wrapper">
  92. <h2 id="the-worst-color-formats" tabindex="-1">The worst color<span class="widont"> </span>formats</h2>
  93. </p>
  94. <p>According to the Almanac data,
  95. the most common color formats on the web
  96. are <span class="caps">HEX</span> (<code>#C71585</code>),
  97. short-form <span class="caps">HEX</span> (<code>#c18</code>),
  98. and then old-school
  99. <code>rgba(199, 21, 133, 0.8)</code>.</p>
  100. <p>But why are we still using
  101. the oldest and least legible
  102. color formats,
  103. when better formats are well-supported?
  104. <span class="caps">HSL</span> is more human-readable than <span class="caps">HEX</span>,
  105. and the <code>rgb()</code> function
  106. now supports alpha transparency
  107. without switching to <code>rgba()</code>.</p>
  108. <p>Alternately, if we like <span class="caps">HEX</span> so much,
  109. why don’t we use the alpha-<span class="caps">HEX</span> syntax
  110. (<code>#C7158599</code>)
  111. that’s been supported for several years.
  112. Why aren’t these options gaining<span class="widont"> </span>popularity?</p>
  113. <p>It’s hard to say for sure,
  114. but I have a multi-part<span class="widont"> </span>guess.</p>
  115. <p class="anchor-link-wrapper">
  116. <h2 id="how-design-tokens-intervene" tabindex="-1">How design tokens<span class="widont"> </span>intervene</h2>
  117. </p>
  118. <p>First, colors are <em>design tokens</em>,
  119. and often get set as custom properties
  120. or build-tool variables
  121. at the start of a project.
  122. Once the tokens are established,
  123. we don’t spend much time looking at
  124. the actual color syntax underneath.
  125. I don’t ever interact directly
  126. with the <span class="caps">HEX</span> code <code>#E60073</code> –
  127. I can just reference
  128. <code>var(--brand-pink)</code>.
  129. So we focus our attention on the naming conventions
  130. rather than the underlying color syntax,
  131. which is hidden from<span class="widont"> </span>view.</p>
  132. <p class="anchor-link-wrapper">
  133. </p>
  134. <p>I think there’s also a tooling component here.
  135. Many graphic design tools are a step removed
  136. from the web platform.
  137. While some do try to export <span class="caps">HTML</span>/<span class="caps">CSS</span>,
  138. only a few consider that
  139. the core goal of the tool.
  140. Even then, there’s been a long-term disconnect
  141. between a web that’s responsive,
  142. and our almost completely static design<span class="widont"> </span>tools.</p>
  143. <p>A few tools have started to provide
  144. <em>flexbox-like</em> ‘responsive’ layouts,
  145. but I haven’t seen anything <em><span class="caps">CSS</span>-grid-like</em>.
  146. Most don’t even have
  147. basic support for relative or fluid units.
  148. Rachel notes in the Almanac
  149. that most lengths on the web
  150. are defined in <code>px</code>.
  151. Is that because authors intentionally avoid <code>em</code>/<code>rem</code>,
  152. or because the mockups that we receive from designers
  153. are all limited to <code>px</code> by our design<span class="widont"> </span>tools?</p>
  154. <p>I’ve <a href="https://twitter.com/TerribleMia/status/1446262147772682260">commented on this before</a>:</p>
  155. <blockquote>
  156. <p>The least responsive part
  157. of Responsive Web Design
  158. is the design tools.
  159. This needs to<span class="widont"> </span>change.</p>
  160. </blockquote>
  161. <p>When it comes to color spaces/gamuts,
  162. design tools vary in support.
  163. Looking at some of the big<span class="widont"> </span>players:</p>
  164. <ul>
  165. <li><strong>Adobe <span class="caps">XD</span></strong>
  166. supports <span class="caps">HEX</span>, <span class="caps">RGB</span>, and <span class="caps">HSB</span>.
  167. <strong>Illustrator</strong> adds <span class="caps">CMYK</span> and a grayscale option,
  168. while <strong>Photoshop</strong> also supports extended gamuts
  169. such as Display P3,
  170. and perceptually-uniform<span class="widont"> </span><span class="caps">LAB</span>.</li>
  171. <li><strong>Figma</strong>
  172. (now also owned by Adobe)
  173. provides <span class="caps">HEX</span>, <span class="caps">RGB</span>,
  174. ‘<span class="caps">CSS</span>’ (which is <code>rgba()</code>),
  175. <span class="caps">HSL</span>, and<span class="widont"> </span><span class="caps">HSB</span>.</li>
  176. <li><strong>Sketch</strong>
  177. shows <span class="caps">HSB</span>, <span class="caps">HEX</span>, and<span class="widont"> </span><span class="caps">RGB</span>(a).</li>
  178. </ul>
  179. <p>I don’t know of any popular design tools
  180. that provide <span class="caps">LCH</span>,
  181. or the newer okLAB/okLCH variants,
  182. let alone <em>relative</em> colors
  183. defined as a function of mixing or adjusting
  184. other underlying<span class="widont"> </span>colors.</p>
  185. <p>And when it comes to copying our colors
  186. out of a design tool,
  187. the options are generally 6-digit <span class="caps">HEX</span>,
  188. or copying individual channel values,
  189. one at a time.
  190. Either way,
  191. converting our colors
  192. into a more human-friendly syntax
  193. would often be an extra step,
  194. and may not be worth the<span class="widont"> </span>effort.</p>
  195. <p>Since all legacy colors on the web
  196. rely on a single color model (<span class="caps">RGB</span>)
  197. and gamut (sRGB),
  198. there has been little <em>meaningful</em> difference
  199. between formats (until now).
  200. Once we used a graphic interface
  201. to pick the color we want,
  202. it maybe didn’t matter
  203. what format we copy-pasted into
  204. a variable<span class="widont"> </span>somewhere.</p>
  205. <p>But what’s the designer path
  206. towards using new, extended color spaces in <span class="caps">CSS</span>?
  207. Can they ever gain traction on the web
  208. without first finding support in our design tools?
  209. I’m not<span class="widont"> </span>sure.</p>
  210. <p class="anchor-link-wrapper">
  211. </p>
  212. <p>Code tools also play a role in<span class="widont"> </span>this.</p>
  213. <p>Sass, for example,
  214. relies on the same
  215. <em>interchangeability</em> of legacy web formats.
  216. No matter what syntax an author chooses,
  217. Sass will store the value as <span class="caps">RGB</span>,
  218. and then allow manipulation
  219. in any other <span class="caps">CSS</span> format.
  220. But at the end of the day,
  221. <em><span class="caps">CSS</span> output is always generated
  222. in whatever format has the widest browser<span class="widont"> </span>support</em>.</p>
  223. <p>It doesn’t matter to Sass
  224. what syntax authors use
  225. for their <em>input value</em>,
  226. the <em>output value</em> is always
  227. either <span class="caps">HEX</span> or a color name when opaque,
  228. with <code>rgba()</code> for handling transparency.
  229. Very few people need that level
  230. of legacy browser support,
  231. but it’s not hurting anything<span class="widont"> </span>either.</p>
  232. <p>Not yet, at least.
  233. This will all change going forward,
  234. as we add
  235. <a href="https://sass-lang.com/blog/request-for-comments-color-spaces">Sass support for more color spaces and<span class="widont"> </span>gamuts</a>.</p>
  236. <p>In this case,
  237. the Almanac may give us misleading info
  238. about what syntax authors <em>prefer</em>.
  239. For all we know,
  240. authors might be <em>working primarily in <span class="caps">HSL</span></em>,
  241. and we wouldn’t see that
  242. in the production code at all.
  243. In fact,
  244. one of the most popular complaints
  245. on the Sass issue tracker is
  246. a request for <span class="caps">HSL</span><span class="widont"> </span>output.</p>
  247. <p>But this is a distinction
  248. with very little at stake.
  249. So long as authors can use their favorite format –
  250. and the output really does
  251. provide the same <em>meaning</em> as the input –
  252. it’s not a barrier for authors
  253. using the latest color formats.
  254. We’re just making that harder to<span class="widont"> </span>see.</p>
  255. <p class="anchor-link-wrapper">
  256. <h2 id="extending-vs-replacing-a-language" tabindex="-1">Extending vs replacing a<span class="widont"> </span>language</h2>
  257. </p>
  258. <p>In Sass,
  259. we have a strict policy
  260. that <em>valid <span class="caps">CSS</span> is always valid Sass</em>.
  261. If authors use syntax that we don’t recognize,
  262. we pass that along to <span class="caps">CSS</span>.
  263. We can check for obvious parsing errors,
  264. but only the browser can determine
  265. if it’s a supported feature.
  266. While we provide <em>extra</em> Sass support
  267. for colors that we understand,
  268. authors can use new <span class="caps">CSS</span> color formats in Sass
  269. without us releasing any new features.
  270. Sass may not understand those colors for a time,
  271. but it will leave them untouched in the <span class="caps">CSS</span><span class="widont"> </span>output.</p>
  272. <p>Similarly,
  273. Sass hasn’t added support
  274. for either <code>@layer</code> or <code>@container</code> –
  275. and there may not be any reason to.
  276. I’m already using both in my Sass,
  277. without any<span class="widont"> </span>issue.</p>
  278. <p>There have been unfortunate exceptions on occasion
  279. (see <code>min()</code> and <code>max()</code> for example),
  280. but we’ve worked very hard to remove those limitations
  281. when they crop up.
  282. The tool should never stand between
  283. authors and the underlying<span class="widont"> </span>language.</p>
  284. <p>Last month,
  285. I spoke about <code>@layer</code> for
  286. <a href="https://aneventapart.com/event/denver-2022">An Event Apart Denver</a>.
  287. During the Q&amp;A session after my talk,
  288. someone asked,
  289. “How can I use this with <span class="caps">CSS</span>-in-<span class="caps">JS</span> tools?”
  290. And the truth is…
  291. <em>I don’t know</em>.
  292. It depends entirely on the<span class="widont"> </span>tool.</p>
  293. <p>Single-file components in tools like Svelte <span class="amp">&amp;</span> Vue
  294. are <em>technically</em> <span class="caps">CSS</span>-in-<span class="caps">JS</span>,
  295. but allow writing arbitrary/plain <span class="caps">CSS</span>.
  296. I would expect (hope?) that
  297. <code>@layer</code> should <em>just work</em> in that context
  298. (similar to using<span class="widont"> </span>Sass).</p>
  299. <p>But many <span class="caps">CSS</span>-in-<span class="caps">JS</span> tools
  300. and utility frameworks
  301. are more invasive –
  302. replacing some or most <span class="caps">CSS</span> with a proprietary syntax.
  303. They don’t provide <em>additions</em> to the language,
  304. but a whole new language
  305. that stands directly between us
  306. and the basic <span class="caps">CSS</span> functionality we need.
  307. There’s no option to write <span class="caps">CSS</span> directly,
  308. we have to rely on the tool to do it for us.
  309. <em>If the tool can’t do something,
  310. neither can the authors using it.
  311. All we can do is<span class="widont"> </span>wait</em>.</p>
  312. <p>I even ran into this issue
  313. by simply hosting my personal site
  314. on Netlify,
  315. which provides minification
  316. for deployed assets like <span class="caps">CSS</span>.
  317. That seems like a great feature!
  318. But the specific <span class="caps">CSS</span> minifier that they use
  319. is somewhat overeager,
  320. and began stripping out all my new
  321. <a href="https://css-tricks.com/css-cascade-layers/"><code>@layer</code></a> rules.
  322. I had to turn off the minification step
  323. in order to publish my entirely-valid<span class="widont"> </span><span class="caps">CSS</span>.</p>
  324. <p>That shouldn’t be the case.
  325. Minifiers shouldn’t need to understand
  326. all the new features that land in <span class="caps">CSS</span>.
  327. This is similar to the issue with
  328. <a href="/2022/08/04/zero-units/">removing units from zero</a>,
  329. or Harry Roberts’ recent warnings around
  330. <a href="https://csswizardry.com/2022/09/critical-css-not-so-fast/">Critical <span class="caps">CSS</span></a>.
  331. In a language like <span class="caps">CSS</span> –
  332. where order is meaningful,
  333. and duplicate properties are a useful feature –
  334. it’s risky for automated build tools
  335. to try and be <em>clever</em> about minification.
  336. I don’t know that a <span class="caps">CSS</span> minifier
  337. should do much more than white-space<span class="widont"> </span>management.</p>
  338. <p class="anchor-link-wrapper">
  339. </p>
  340. <p>In regard to web fonts,
  341. Bram points out
  342. that authors are not taking full advantage
  343. of variable fonts –
  344. we’re mostly changing the font weights,
  345. and selecting from standard<span class="widont"> </span>values.</p>
  346. <p>As someone who has spent hours
  347. searching through lists of variable fonts,
  348. that doesn’t surprise me much.
  349. Most variable fonts are either experimental display fonts
  350. without a lot of practical use,
  351. or they only provide a single weight axis.
  352. While I love having all my weights in a single file
  353. and smoothly transitioning from one weight to another,
  354. <em>specialty weights</em> are not a high priority for me.
  355. I’ll start using more powerful font variables
  356. once there are more fonts available
  357. with more interesting variables to<span class="widont"> </span>manipulate.</p>
  358. <p>Most of us are also using
  359. the over-complicated <code>font-feature-settings</code> property,
  360. instead of the simpler <code>font-variant</code>.
  361. I’ve been doing that on my site as<span class="widont"> </span>well!</p>
  362. <p>Why did I think that was the best approach?
  363. Likely because that’s the generated output
  364. recommended by
  365. <a href="https://wakamaifondue.com/">Wakamai Fondue</a> –
  366. a popular tool for inspecting font capabilities.
  367. It’s a great tool,
  368. filling a much-needed gap,
  369. but I wonder how the usage stats would change
  370. if they updated their output<span class="widont"> </span><span class="caps">CSS</span>?</p>
  371. <p>Maybe even more common,
  372. much of the web is built using <span class="caps">CSS</span> libraries
  373. like Bootstrap,
  374. or third-party themes
  375. provided by a site-builder or <span class="caps">CMS</span>.
  376. The influence of both
  377. WordPress and Bootstrap is clear
  378. throughout the Almanac data.
  379. When Rachel notes the popularity of
  380. flexbox (very popular) vs grid (not so much),
  381. I wonder how much of that
  382. can be traced back to
  383. Bootstrap ‘grids’
  384. <a href="https://getbootstrap.com/docs/5.2/layout/grid/">being built in<span class="widont"> </span>flexbox</a>.</p>
  385. <p>I don’t think that’s the only factor.
  386. It’s possible authors have settled on flexbox as <em>good-enough</em>,
  387. and they don’t think it’s worth their time
  388. learning another technique.
  389. I can understand that,
  390. but it’s unfortunate.
  391. I think people are missing out
  392. on one of the coolest features
  393. added to <span class="caps">CSS</span> <em>ever</em>.</p>
  394. <p class="anchor-link-wrapper">
  395. </p>
  396. <p>When we talk about web trends,
  397. I often hear people refer back to
  398. the idea of ‘pace layers’ on the<span class="widont"> </span>web:</p>
  399. <p><figure class="embed">
  400. <figcaption class="caption">Described by <a href="https://adactio.com/">Jeremy Keith</a>
  401. in his <a href="https://speaking.adactio.com/87IIn1">Building talk</a>
  402. a few years<span class="widont"> </span>back.</figcaption></figure></p>
  403. <p>In context,
  404. Jeremy is not just referring to
  405. the web languages themselves –
  406. <span class="caps">JS</span> isn’t necessarily changing faster than <span class="caps">CSS</span> –
  407. but also the <em>ecosystems</em> of these languages.
  408. The closer we get to the core functionality of the web,
  409. the slower each language/ecosystem is likely to change.
  410. Even within a given language,
  411. we expect our tools and conventions (<em>fashion</em>)
  412. to move faster than the languages<span class="widont"> </span>themselves.</p>
  413. <p>But that can only happen
  414. if the tools are designed to
  415. sit on top of their underlying languages.
  416. Once the tools stand <em>between</em> us and the language,
  417. we become entirely reliant on tool-builders
  418. to determine what features are<span class="widont"> </span>available.</p>
  419. <p>When our primary tools
  420. intervene so strongly
  421. between us and our ‘materials’ –
  422. the core web languages –
  423. we can accidentally flip the pace layers of the web
  424. on their head.
  425. Suddenly <span class="caps">CSS</span> is able to move faster than the ecosystem,
  426. and we’re stuck waiting on our tools to catch up
  427. with well-supported platform<span class="widont"> </span>features.</p>
  428. <p>That’s not how a healthy ecosystem should<span class="widont"> </span>behave.</p>
  429. <p class="anchor-link-wrapper">
  430. </p>
  431. <p>I am asked quite often
  432. what I think about <span class="caps">CSS</span>-in-<span class="caps">JS</span>
  433. or utility-first frameworks,
  434. or even <span class="caps">CSS</span> libraries <span class="amp">&amp;</span> conventions
  435. more generally.
  436. And I try to stay out of any spicy flame wars,
  437. or gate-keeping<span class="widont"> </span>nonsense.</p>
  438. <p>For myself?
  439. I don’t find many of these tools useful.
  440. They don’t solve a problem that I have.
  441. But different projects and different teams
  442. have different needs,
  443. and might find different tools useful.
  444. There’s no single ‘correct’ approach
  445. for writing all <span class="caps">CSS</span><span class="widont"> </span>everywhere.</p>
  446. <p>As long as it results in an
  447. accessible, resilient,
  448. and performant experience for users:
  449. <em>use whatever tools work best for<span class="widont"> </span>you</em>.</p>
  450. <p>(Anyone marketing their product
  451. as <em>The Only Solution™️</em> to some
  452. <em>Essential Problem with <span class="caps">CSS</span>™️</em>
  453. is selling you a religion,
  454. not a<span class="widont"> </span>tool.)</p>
  455. <p>It’s not my job to judge
  456. what tools are useful for other web developers.
  457. But it is my job to
  458. help people think about the <span class="caps">CSS</span> choices they make.
  459. So in that spirit, please<span class="widont"> </span>consider:</p>
  460. <p>⚠️🚨⚠️
  461. When tools intervene
  462. between you and your access to the web platform,
  463. <strong>proceed with caution</strong>.
  464. Ask not only: <em>How well does it work?</em>
  465. But also: <em>How well does it fail?</em>
  466. Not only: <em>What features do they provide?</em>
  467. But also: <em>What features do they prevent?</em><span class="widont"> </span>⚠️🚨⚠️</p>
  468. </article>
  469. <hr>
  470. <footer>
  471. <p>
  472. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  473. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  474. </svg> Accueil</a> •
  475. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  476. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  477. </svg> Suivre</a> •
  478. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  479. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  480. </svg> Pro</a> •
  481. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  482. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  483. </svg> Email</a> •
  484. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  485. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  486. </svg> Légal</abbr>
  487. </p>
  488. <template id="theme-selector">
  489. <form>
  490. <fieldset>
  491. <legend><svg class="icon icon-brightness-contrast">
  492. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  493. </svg> Thème</legend>
  494. <label>
  495. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  496. </label>
  497. <label>
  498. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  499. </label>
  500. <label>
  501. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  502. </label>
  503. </fieldset>
  504. </form>
  505. </template>
  506. </footer>
  507. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  508. <script>
  509. function loadThemeForm(templateName) {
  510. const themeSelectorTemplate = document.querySelector(templateName)
  511. const form = themeSelectorTemplate.content.firstElementChild
  512. themeSelectorTemplate.replaceWith(form)
  513. form.addEventListener('change', (e) => {
  514. const chosenColorScheme = e.target.value
  515. localStorage.setItem('theme', chosenColorScheme)
  516. toggleTheme(chosenColorScheme)
  517. })
  518. const selectedTheme = localStorage.getItem('theme')
  519. if (selectedTheme && selectedTheme !== 'undefined') {
  520. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  521. }
  522. }
  523. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  524. window.addEventListener('load', () => {
  525. let hasDarkRules = false
  526. for (const styleSheet of Array.from(document.styleSheets)) {
  527. let mediaRules = []
  528. for (const cssRule of styleSheet.cssRules) {
  529. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  530. continue
  531. }
  532. // WARNING: Safari does not have/supports `conditionText`.
  533. if (cssRule.conditionText) {
  534. if (cssRule.conditionText !== prefersColorSchemeDark) {
  535. continue
  536. }
  537. } else {
  538. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  539. continue
  540. }
  541. }
  542. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  543. }
  544. // WARNING: do not try to insert a Rule to a styleSheet you are
  545. // currently iterating on, otherwise the browser will be stuck
  546. // in a infinite loop…
  547. for (const mediaRule of mediaRules) {
  548. styleSheet.insertRule(mediaRule.cssText)
  549. hasDarkRules = true
  550. }
  551. }
  552. if (hasDarkRules) {
  553. loadThemeForm('#theme-selector')
  554. }
  555. })
  556. </script>
  557. </body>
  558. </html>