Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
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 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  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>
  13. Flow
  14. — David Larlet</title>
  15. <script>
  16. function toggleTheme(themeName) {
  17. document.documentElement.classList.toggle(
  18. 'forced-dark',
  19. themeName === 'dark'
  20. )
  21. document.documentElement.classList.toggle(
  22. 'forced-light',
  23. themeName === 'light'
  24. )
  25. }
  26. const selectedTheme = localStorage.getItem('theme')
  27. if (selectedTheme !== 'undefined') {
  28. toggleTheme(selectedTheme)
  29. }
  30. </script>
  31. <!-- Documented, feel free to shoot an email. -->
  32. <link rel="stylesheet" href="/static/david/css/style_2024-03-09.css">
  33. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  34. <link rel="preload"
  35. href="/static/david/css/fonts/century_supra_ot_a_regular.woff2"
  36. as="font"
  37. type="font/woff2"
  38. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  39. crossorigin>
  40. <link rel="preload"
  41. href="/static/david/css/fonts/century_supra_ot_a_bold.woff2"
  42. as="font"
  43. type="font/woff2"
  44. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  45. crossorigin>
  46. <link rel="preload"
  47. href="/static/david/css/fonts/century_supra_ot_a_italic.woff2"
  48. as="font"
  49. type="font/woff2"
  50. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  51. crossorigin>
  52. <link rel="preload"
  53. href="/static/david/css/fonts/century_supra_ot_b_regular.woff2"
  54. as="font"
  55. type="font/woff2"
  56. media="(prefers-color-scheme: dark)"
  57. crossorigin>
  58. <link rel="preload"
  59. href="/static/david/css/fonts/century_supra_ot_b_bold.woff2"
  60. as="font"
  61. type="font/woff2"
  62. media="(prefers-color-scheme: dark)"
  63. crossorigin>
  64. <link rel="preload"
  65. href="/static/david/css/fonts/century_supra_ot_b_italic.woff2"
  66. as="font"
  67. type="font/woff2"
  68. media="(prefers-color-scheme: dark)"
  69. crossorigin>
  70. <meta name="description" content="Le flow n’est pas seulement un état où j’ai besoin de calme, il s’agit d’un contexte à part entière. Il me faut une problématique connue, qui est définie avec des contours relativement flous, davantage une intention qu’une direction. Si j’ai déjà eu l’occasion d’être précédemment frustré par l’implémentation en cours, cela me donne beaucoup de motivation pour plonger. Parfois la zone est atteinte en n’étant pas devant un écran (en courant, sous la douche, etc), une forme d’Eurêka ! qui annonce la libération du flow à venir.">
  71. <!-- That good ol' feed, subscribe :). -->
  72. <link rel="alternate"
  73. type="application/atom+xml"
  74. title="Feed"
  75. href="/david/log/">
  76. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  77. <link rel="apple-touch-icon"
  78. sizes="180x180"
  79. href="/static/david/icons2/apple-touch-icon.png">
  80. <link rel="icon"
  81. type="image/png"
  82. sizes="32x32"
  83. href="/static/david/icons2/favicon-32x32.png">
  84. <link rel="icon"
  85. type="image/png"
  86. sizes="16x16"
  87. href="/static/david/icons2/favicon-16x16.png">
  88. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  89. <link rel="mask-icon"
  90. href="/static/david/icons2/safari-pinned-tab.svg"
  91. color="#07486c">
  92. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  93. <meta name="msapplication-TileColor" content="#f7f7f7">
  94. <meta name="msapplication-config"
  95. content="/static/david/icons2/browserconfig.xml">
  96. <meta name="theme-color"
  97. content="#f7f7f7"
  98. media="(prefers-color-scheme: light)">
  99. <meta name="theme-color"
  100. content="#272727"
  101. media="(prefers-color-scheme: dark)">
  102. <!-- Is that even respected? Retrospectively? What a shAItshow…
  103. https://neil-clarke.com/block-the-bots-that-feed-ai-models-by-scraping-your-website/ -->
  104. <meta name="robots" content="noai, noimageai">
  105. <style type="text/css">
  106. .tippy-content {
  107. min-width: 280px;
  108. padding: .5rem;
  109. font-size: calc(var(--fluid-0) * 0.8);
  110. font-family: var(--labor-font);
  111. letter-spacing: initial;
  112. text-align: left;
  113. }
  114. .tippy-content h3 {
  115. margin-top: 0;
  116. }
  117. .tippy-content h3 img {
  118. max-width: 2rem;
  119. max-height: 2rem;
  120. display: inline-block;
  121. }
  122. .tippy-content .tippy-links {
  123. display: flex;
  124. justify-content: space-around;
  125. }
  126. .tippy-content a {
  127. padding: .4rem;
  128. color: #F06048;
  129. }
  130. </style>
  131. <body data-instant-intensity="viewport-all">
  132. <article>
  133. <header>
  134. <hgroup>
  135. <h1>Flow</h1>
  136. <p>Le <time datetime="2024-03-08">8 mars 2024</time></p>
  137. </hgroup>
  138. </header>
  139. <nav>
  140. <p>
  141. <a rel="prev"
  142. href="/david/2024/03/07/"
  143. title="Publication précédente : Sondages">← Précédent</a> •
  144. <a href="/david/" title="Aller à l’accueil" rel="up">Accueil</a>
  145. <a href="/david/recherche/"
  146. title="Aller à la page de recherche"
  147. rel="search" data-no-instant>Recherche</a>
  148. • <a rel="next"
  149. href="/david/2024/03/09/"
  150. title="Publication suivante : Marque">Suivant →</a>
  151. </p>
  152. </nav>
  153. <p>Le <a data-link-domain="fr.wikipedia.org" href="https://fr.wikipedia.org/wiki/Flow_(psychologie)">flow</a> n’est pas seulement un état où j’ai besoin de calme, il s’agit d’un contexte à part entière. Il me faut une problématique connue, qui est définie avec des contours relativement flous, davantage une intention qu’une direction. Si j’ai déjà eu l’occasion d’être précédemment frustré par l’implémentation en cours, cela me donne beaucoup de motivation pour plonger. Parfois la zone est atteinte en n’étant pas devant un écran (en courant, sous la douche, etc), une forme d’<em>Eurêka&#8239;!</em> qui annonce la libération du <em>flow</em> à&nbsp;venir.</p>
  154. <p>La crue monte et butte contre des digues techniques, plusieurs fois, avant de créer la brèche qui va tout libérer d’un coup et se répandre dans l’ensemble du code. Reste la tâche de <em>ressuyage</em>&nbsp;: <q lang="fr">l’évacuation des eaux qui se sont déversées dans les terres après une inondation et ainsi de diminuer le temps de submersion</q> nous dit le <a data-link-domain="symadrem.fr" href="https://www.symadrem.fr/anticiper-intervenir/evacuation-des-eaux-post-crue/quest-ce-que-le-ressuyage/">Symadrem</a>. Ce n’est pas une tâche ingrate car c’est celle qui rend le code pérenne et compréhensible, l’objet du <em>flow</em> accessible au plus grand nombre. Le temps de la décrue permet d’identifier les cas aux limites&nbsp;également.</p>
  155. <p>Ce contexte ne m’est atteignable que 3&nbsp;ou 4&nbsp;fois par an en moyenne. Et heureusement, car il est vraiment peu soutenable (mais tellement&nbsp;satisfaisant&#8239;!).</p>
  156. <a href="#hr-104" title="Lien vers cette section de la page"><hr id="hr-104" /></a>
  157. <blockquote lang="en">
  158. <p>CSS is a programming language because that’s what you’re doing when you write it; you’re <em>programming</em> the application’s presentation logic. And that’s important, because CSS has power enough to either maximize the useability of software, or to ruin it beyond all utility. (Really; you’d probably be astounded how many ways there are to utterly destroy anything on the web with hardly any&nbsp;CSS.)</p>
  159. <p>In many ways, <mark>CSS has greater impact than any other language</mark> on a user’s experience, which often directly influences success. Why, then, is its role so&nbsp;belittled?</p>
  160. <p><cite><em><a data-link-domain="joshcollinsworth.com" href="https://joshcollinsworth.com/blog/devaluing-frontend" hreflang="en"
  161. title="Consultation de l’article (anglais)">The quiet, pervasive devaluation of frontend</a>
  162. <a href="/david/cache/2024/64ec164fc6c5c23ede3fba6006a47f36/" hreflang="en"
  163. data-tippy data-description="I keep noticing those of us in the frontend field being treated much the same as nurses, paralegals, and executive assistants. Our work is seen as important, certainly, but just not the same as, or as important as, the “real” work."
  164. data-source="https://joshcollinsworth.com/blog/devaluing-frontend"
  165. data-date="2024-03-09"
  166. data-favicon="https://joshcollinsworth.com/favicon.png"
  167. data-domain="joshcollinsworth.com"
  168. ><svg xmlns="http://www.w3.org/2000/svg"
  169. width="24" height="24" viewBox="0 0 24 24" fill="none"
  170. stroke="currentColor" stroke-width="2" stroke-linecap="square"
  171. stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle>
  172. <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
  173. <line x1="12" y1="17" x2="12.01" y2="17"></line>
  174. </svg>
  175. <span class="sr-only">[archive]</span></a></em></cite></p>
  176. </blockquote>
  177. <p>J’aurais pu citer beaucoup de parties de cet article. Je choisis celle vraiment centrée sur CSS car les avancées récentes en font encore davantage un outil qui demande une grande connaissance du domaine, une veille active et une réflexion importante. Ce langage exprime la complexité de nos interfaces et de notre évolution collective en terme d’exploration d’affordances. Les <em>patterns</em>, ces façons de résoudre des problèmes similaires, évoluent et les personnes qui arrivent à suivre ces évolutions vont être de plus en plus sollicitées (j’en parlais <a href="/david/2024/02/28/#hr-94">par ici</a>) — notamment lorsqu’il va falloir nettoyer 10&nbsp;ans de&nbsp;CSS-in-JS/Tailwind/YouNameIt.</p>
  178. <p>Je n’ai pas la même considération pour ces personnes, <strong>j’en ai bien davantage</strong>.</p>
  179. <a href="#hr-105" title="Lien vers cette section de la page"><hr id="hr-105" /></a>
  180. <blockquote lang="en">
  181. <p>So far we have designed our component to be a function of the host. We can go further and ensure that the rendering routine is actually private to the host, so that the rendering code is encapsulated inside along with any potential behaviour enhancements (the <code>countClickable</code> mixin for example), while both remain&nbsp;reusable.</p>
  182. <p><cite><em><a data-link-domain="lorenzofox.dev" href="https://lorenzofox.dev/posts/component-as-infinite-loop/" hreflang="en"
  183. title="Consultation de l’article (anglais)">Coroutines and web components</a>
  184. <a href="/david/cache/2024/6f3cb3c0c6c580407b1cfaa2d7d9005b/" hreflang="en"
  185. data-tippy data-description="Custom elements (web components) modelling with coroutines"
  186. data-source="https://lorenzofox.dev/posts/component-as-infinite-loop/"
  187. data-date="2024-03-09"
  188. data-favicon="https://lorenzofox.dev/posts/component-as-infinite-loop/public/favicon.ico"
  189. data-domain="lorenzofox.dev"
  190. ><svg xmlns="http://www.w3.org/2000/svg"
  191. width="24" height="24" viewBox="0 0 24 24" fill="none"
  192. stroke="currentColor" stroke-width="2" stroke-linecap="square"
  193. stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle>
  194. <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
  195. <line x1="12" y1="17" x2="12.01" y2="17"></line>
  196. </svg>
  197. <span class="sr-only">[archive]</span></a></em></cite></p>
  198. </blockquote>
  199. <p>Je n’ai pas tout compris (et j’en suis à la seconde lecture) mais ça a l’air&nbsp;fun&#8239;!&nbsp;😜</p>
  200. <nav>
  201. <p>
  202. <a href="/david/2024/experience/"
  203. title="Liste de tous les articles 2024 associés à cette étiquette"
  204. rel="tag">#expérience</a>
  205. <a href="/david/2024/psychologie/"
  206. title="Liste de tous les articles 2024 associés à cette étiquette"
  207. rel="tag">#psychologie</a>
  208. <a href="/david/2024/technique/"
  209. title="Liste de tous les articles 2024 associés à cette étiquette"
  210. rel="tag">#technique</a>
  211. <a href="/david/2024/#tags" title="Liste de toutes les étiquettes 2024">tous ?</a>
  212. </p>
  213. </nav>
  214. <nav>
  215. <p>
  216. <a rel="prev"
  217. href="/david/2024/03/07/"
  218. title="Publication précédente : Sondages">← Précédent</a> •
  219. <a href="/david/2024/" title="Liste des publications récentes">↑ En 2024</a>
  220. • <a rel="next"
  221. href="/david/2024/03/09/"
  222. title="Publication suivante : Marque">Suivant →</a>
  223. </p>
  224. </nav>
  225. <form action="/david/recherche/" method="get">
  226. <fieldset>
  227. <legend>Recherche</legend>
  228. <label for="input-search">Termes de votre recherche :</label>
  229. <input id="input-search" type="search" name="s" aria-describedby="indexation-infos" required>
  230. <input type="submit" value="Chercher">
  231. <p id="indexation-infos">
  232. <small>
  233. Seuls les contenus de ces 8 dernières années sont indexés.
  234. </small>
  235. </p>
  236. </fieldset>
  237. </form>
  238. <aside>
  239. <theme-toggle></theme-toggle>
  240. </aside>
  241. </article>
  242. <hr>
  243. <footer>
  244. <p>
  245. <a href="/david/" title="Aller à l’accueil">Accueil</a>
  246. <a href="/david/log/" title="Accès au flux RSS">Suivre</a>
  247. <a href="http://larlet.com"
  248. title="Go to my English profile"
  249. data-instant>Pro</a>
  250. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">Email</a>
  251. <abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">Légal</abbr>
  252. </p>
  253. <template id="theme-selector">
  254. <form>
  255. <style type="text/css">
  256. fieldset div {
  257. text-align: center;
  258. }
  259. </style>
  260. <fieldset>
  261. <legend>Thème</legend>
  262. <div>
  263. <label>
  264. <input type="radio" value="auto" name="chosen-color-scheme" checked>
  265. Auto
  266. </label>
  267. <label>
  268. <input type="radio" value="dark" name="chosen-color-scheme">
  269. Foncé
  270. </label>
  271. <label>
  272. <input type="radio" value="light" name="chosen-color-scheme">
  273. Clair
  274. </label>
  275. </div>
  276. </fieldset>
  277. </form>
  278. </template>
  279. </footer>
  280. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  281. <script>
  282. class ThemeToggle extends HTMLElement {
  283. constructor() {
  284. super()
  285. const themeSelectorTemplate = document.querySelector('#theme-selector')
  286. const form = themeSelectorTemplate.content.firstElementChild
  287. this.attachShadow({ mode: 'open' })
  288. this.shadowRoot.appendChild(form.cloneNode(true))
  289. }
  290. connectedCallback() {
  291. const form = this.shadowRoot.querySelector('form')
  292. form.addEventListener('change', (e) => {
  293. const chosenColorScheme = e.target.value
  294. localStorage.setItem('theme', chosenColorScheme)
  295. toggleTheme(chosenColorScheme)
  296. })
  297. const selectedTheme = localStorage.getItem('theme')
  298. if (selectedTheme && selectedTheme !== 'undefined') {
  299. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  300. }
  301. }
  302. }
  303. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  304. window.addEventListener('load', () => {
  305. let colorsLayer = undefined
  306. let hasDarkRules = false
  307. for (const styleSheet of Array.from(document.styleSheets)) {
  308. let mediaRules = []
  309. for (const layerRule of styleSheet.cssRules) {
  310. if (!(layerRule instanceof CSSLayerBlockRule)) {
  311. continue
  312. }
  313. if (layerRule.name === 'colors') {
  314. colorsLayer = layerRule
  315. }
  316. for (const cssRule of layerRule.cssRules) {
  317. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  318. continue
  319. }
  320. // WARNING: Safari does not have/supports `conditionText`.
  321. if (cssRule.conditionText) {
  322. if (cssRule.conditionText !== prefersColorSchemeDark) {
  323. continue
  324. }
  325. } else {
  326. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  327. continue
  328. }
  329. }
  330. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  331. }
  332. }
  333. // WARNING: do not try to insert a Rule to a styleSheet you are
  334. // currently iterating on, otherwise the browser will be stuck
  335. // in a infinite loop…
  336. for (const mediaRule of mediaRules) {
  337. // Safari requires the `0` second parameter (even if default).
  338. colorsLayer.insertRule(mediaRule.cssText, 0)
  339. hasDarkRules = true
  340. }
  341. }
  342. if (hasDarkRules) {
  343. if ('customElements' in window && !customElements.get('theme-toggle')) {
  344. customElements.define('theme-toggle', ThemeToggle)
  345. }
  346. }
  347. })
  348. </script>
  349. <script src="/static/david/js/popper-2.11.8.min.js"></script>
  350. <script src="/static/david/js/tippy-bundle-6.3.7.umd.min.js"></script>
  351. <script>
  352. tippy('[data-tippy]', {
  353. content(reference) {
  354. reference.addEventListener('click', (e) => e.preventDefault())
  355. return `
  356. <h3 lang="fr">
  357. <img src="${reference.dataset.favicon}" loading="lazy">
  358. <a href="${reference.dataset.source}"
  359. >Article sur ${reference.dataset.domain}</a></h3>
  360. <p lang="${reference.hreflang}"><em>${reference.dataset.description}</em></p>
  361. <div class="tippy-links" lang="fr">
  362. <a href="${reference.href}">Archive au ${reference.dataset.date}</a>
  363. </div>
  364. `
  365. },
  366. allowHTML: true,
  367. interactive: true,
  368. delay: [150, 700],
  369. hideOnClick: false
  370. })
  371. </script>
  372. <script type="module">
  373. import { annotate } from '/static/david/js/rough-notation-0.5.1.esm.min.js'
  374. const observer = new IntersectionObserver(elements => {
  375. const computedStyle = getComputedStyle(document.documentElement)
  376. const markBackground = computedStyle.getPropertyValue('--mark-background')
  377. for (const element of elements) {
  378. if (element.intersectionRatio === 0) continue
  379. const markElement = element.target
  380. if (markElement.dataset.annotated) continue
  381. const annotation = annotate(
  382. markElement, {
  383. type: 'highlight',
  384. multiline: true,
  385. color: markBackground,
  386. animate: !window.matchMedia('(prefers-reduced-motion: reduce)').matches
  387. }
  388. )
  389. annotation.show()
  390. // Avoid the rough notation to be applied multiple times.
  391. markElement.dataset.annotated = true
  392. }
  393. }, {threshold: 1.0})
  394. for (const markElement of document.querySelectorAll('mark')) {
  395. markElement.style.backgroundColor = 'inherit'
  396. observer.observe(markElement)
  397. }
  398. </script>
  399. </body>
  400. </html>