Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

index.html 20KB

před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 3 týdny
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
před 8 měsíci
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  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. <!-- To get attribution when linking on mastodon. -->
  106. <meta name="fediverse:creator" content="@david@larlet.fr">
  107. <style type="text/css">
  108. .tippy-content {
  109. min-width: 280px;
  110. padding: .5rem;
  111. font-size: calc(var(--fluid-0) * 0.8);
  112. font-family: var(--labor-font);
  113. letter-spacing: initial;
  114. text-align: left;
  115. }
  116. .tippy-content h3 {
  117. margin-top: 0;
  118. }
  119. .tippy-content h3 img {
  120. max-width: 2rem;
  121. max-height: 2rem;
  122. display: inline-block;
  123. }
  124. .tippy-content .tippy-links {
  125. display: flex;
  126. justify-content: space-around;
  127. }
  128. .tippy-content a {
  129. padding: .4rem;
  130. color: #F06048;
  131. }
  132. </style>
  133. <body data-instant-intensity="viewport-all">
  134. <article>
  135. <header>
  136. <hgroup>
  137. <h1>Flow</h1>
  138. <p>Le <time datetime="2024-03-08">8 mars 2024</time></p>
  139. </hgroup>
  140. </header>
  141. <nav>
  142. <p>
  143. <a rel="prev"
  144. href="/david/2024/03/07/"
  145. title="Publication précédente : Sondages">← Précédent</a> •
  146. <a href="/david/" title="Aller à l’accueil" rel="up">Accueil</a>
  147. <a href="/david/recherche/"
  148. title="Aller à la page de recherche"
  149. rel="search" data-no-instant>Recherche</a>
  150. • <a rel="next"
  151. href="/david/2024/03/09/"
  152. title="Publication suivante : Marque">Suivant →</a>
  153. </p>
  154. </nav>
  155. <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>
  156. <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>
  157. <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>
  158. <a href="#hr-104" title="Lien vers cette section de la page"><hr id="hr-104" /></a>
  159. <blockquote lang="en">
  160. <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>
  161. <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>
  162. <p><cite><em><a data-link-domain="joshcollinsworth.com" href="https://joshcollinsworth.com/blog/devaluing-frontend" hreflang="en"
  163. title="Consultation de l’article (anglais)">The quiet, pervasive devaluation of frontend</a>
  164. <a href="/david/cache/2024/64ec164fc6c5c23ede3fba6006a47f36/" hreflang="en"
  165. 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."
  166. data-source="https://joshcollinsworth.com/blog/devaluing-frontend"
  167. data-date="2024-03-09"
  168. data-favicon="https://joshcollinsworth.com/favicon.png"
  169. data-domain="joshcollinsworth.com"
  170. ><svg xmlns="http://www.w3.org/2000/svg"
  171. width="24" height="24" viewBox="0 0 24 24" fill="none"
  172. stroke="currentColor" stroke-width="2" stroke-linecap="square"
  173. stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle>
  174. <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
  175. <line x1="12" y1="17" x2="12.01" y2="17"></line>
  176. </svg>
  177. <span class="sr-only">[archive]</span></a></em></cite></p>
  178. </blockquote>
  179. <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>
  180. <p>Je n’ai pas la même considération pour ces personnes, <strong>j’en ai bien davantage</strong>.</p>
  181. <a href="#hr-105" title="Lien vers cette section de la page"><hr id="hr-105" /></a>
  182. <blockquote lang="en">
  183. <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>
  184. <p><cite><em><a data-link-domain="lorenzofox.dev" href="https://lorenzofox.dev/posts/component-as-infinite-loop/" hreflang="en"
  185. title="Consultation de l’article (anglais)">Coroutines and web components</a>
  186. <a href="/david/cache/2024/6f3cb3c0c6c580407b1cfaa2d7d9005b/" hreflang="en"
  187. data-tippy data-description="Custom elements (web components) modelling with coroutines"
  188. data-source="https://lorenzofox.dev/posts/component-as-infinite-loop/"
  189. data-date="2024-03-09"
  190. data-favicon="https://lorenzofox.dev/posts/component-as-infinite-loop/public/favicon.ico"
  191. data-domain="lorenzofox.dev"
  192. ><svg xmlns="http://www.w3.org/2000/svg"
  193. width="24" height="24" viewBox="0 0 24 24" fill="none"
  194. stroke="currentColor" stroke-width="2" stroke-linecap="square"
  195. stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle>
  196. <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
  197. <line x1="12" y1="17" x2="12.01" y2="17"></line>
  198. </svg>
  199. <span class="sr-only">[archive]</span></a></em></cite></p>
  200. </blockquote>
  201. <p>Je n’ai pas tout compris (et j’en suis à la seconde lecture) mais ça a l’air&nbsp;fun&#8239;!&nbsp;😜</p>
  202. <nav>
  203. <p>
  204. <a href="/david/2024/experience/"
  205. title="Liste de tous les articles 2024 associés à cette étiquette"
  206. rel="tag">#expérience</a>
  207. <a href="/david/2024/psychologie/"
  208. title="Liste de tous les articles 2024 associés à cette étiquette"
  209. rel="tag">#psychologie</a>
  210. <a href="/david/2024/technique/"
  211. title="Liste de tous les articles 2024 associés à cette étiquette"
  212. rel="tag">#technique</a>
  213. <a href="/david/2024/#tags" title="Liste de toutes les étiquettes 2024">tous ?</a>
  214. </p>
  215. </nav>
  216. <nav>
  217. <p>
  218. <a rel="prev"
  219. href="/david/2024/03/07/"
  220. title="Publication précédente : Sondages">← Précédent</a> •
  221. <a href="/david/2024/" title="Liste des publications récentes">↑ En 2024</a>
  222. • <a rel="next"
  223. href="/david/2024/03/09/"
  224. title="Publication suivante : Marque">Suivant →</a>
  225. </p>
  226. </nav>
  227. <form action="/david/recherche/" method="get">
  228. <fieldset>
  229. <legend>Recherche</legend>
  230. <label for="input-search">Termes de votre recherche :</label>
  231. <input id="input-search" type="search" name="s" aria-describedby="indexation-infos" required>
  232. <input type="submit" value="Chercher">
  233. <p id="indexation-infos">
  234. <small>
  235. Seuls les contenus de ces 8 dernières années sont indexés.
  236. </small>
  237. </p>
  238. </fieldset>
  239. </form>
  240. <aside>
  241. <theme-toggle></theme-toggle>
  242. </aside>
  243. </article>
  244. <hr>
  245. <footer>
  246. <p>
  247. <a href="/david/" title="Aller à l’accueil">Accueil</a>
  248. <a href="/david/log/" title="Accès au flux RSS">Suivre</a>
  249. <a href="http://larlet.com"
  250. title="Go to my English profile"
  251. data-instant>Pro</a>
  252. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">Email</a>
  253. <abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">Légal</abbr>
  254. </p>
  255. <template id="theme-selector">
  256. <form>
  257. <style type="text/css">
  258. fieldset div {
  259. text-align: center;
  260. }
  261. </style>
  262. <fieldset>
  263. <legend>Thème</legend>
  264. <div>
  265. <label>
  266. <input type="radio" value="auto" name="chosen-color-scheme" checked>
  267. Auto
  268. </label>
  269. <label>
  270. <input type="radio" value="dark" name="chosen-color-scheme">
  271. Foncé
  272. </label>
  273. <label>
  274. <input type="radio" value="light" name="chosen-color-scheme">
  275. Clair
  276. </label>
  277. </div>
  278. </fieldset>
  279. </form>
  280. </template>
  281. </footer>
  282. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  283. <script>
  284. class ThemeToggle extends HTMLElement {
  285. constructor() {
  286. super()
  287. const themeSelectorTemplate = document.querySelector('#theme-selector')
  288. const form = themeSelectorTemplate.content.firstElementChild
  289. this.attachShadow({ mode: 'open' })
  290. this.shadowRoot.appendChild(form.cloneNode(true))
  291. }
  292. connectedCallback() {
  293. const form = this.shadowRoot.querySelector('form')
  294. form.addEventListener('change', (e) => {
  295. const chosenColorScheme = e.target.value
  296. localStorage.setItem('theme', chosenColorScheme)
  297. toggleTheme(chosenColorScheme)
  298. })
  299. const selectedTheme = localStorage.getItem('theme')
  300. if (selectedTheme && selectedTheme !== 'undefined') {
  301. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  302. }
  303. }
  304. }
  305. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  306. window.addEventListener('load', () => {
  307. let colorsLayer = undefined
  308. let hasDarkRules = false
  309. for (const styleSheet of Array.from(document.styleSheets)) {
  310. let mediaRules = []
  311. for (const layerRule of styleSheet.cssRules) {
  312. if (!(layerRule instanceof CSSLayerBlockRule)) {
  313. continue
  314. }
  315. if (layerRule.name === 'colors') {
  316. colorsLayer = layerRule
  317. }
  318. for (const cssRule of layerRule.cssRules) {
  319. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  320. continue
  321. }
  322. // WARNING: Safari does not have/supports `conditionText`.
  323. if (cssRule.conditionText) {
  324. if (cssRule.conditionText !== prefersColorSchemeDark) {
  325. continue
  326. }
  327. } else {
  328. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  329. continue
  330. }
  331. }
  332. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  333. }
  334. }
  335. // WARNING: do not try to insert a Rule to a styleSheet you are
  336. // currently iterating on, otherwise the browser will be stuck
  337. // in a infinite loop…
  338. for (const mediaRule of mediaRules) {
  339. // Safari requires the `0` second parameter (even if default).
  340. colorsLayer.insertRule(mediaRule.cssText, 0)
  341. hasDarkRules = true
  342. }
  343. }
  344. if (hasDarkRules) {
  345. if ('customElements' in window && !customElements.get('theme-toggle')) {
  346. customElements.define('theme-toggle', ThemeToggle)
  347. }
  348. }
  349. })
  350. </script>
  351. <script src="/static/david/js/popper-2.11.8.min.js"></script>
  352. <script src="/static/david/js/tippy-bundle-6.3.7.umd.min.js"></script>
  353. <script>
  354. tippy('[data-tippy]', {
  355. content(reference) {
  356. reference.addEventListener('click', (e) => e.preventDefault())
  357. return `
  358. <h3 lang="fr">
  359. <img src="${reference.dataset.favicon}" loading="lazy">
  360. <a href="${reference.dataset.source}"
  361. >Article sur ${reference.dataset.domain}</a></h3>
  362. <p lang="${reference.hreflang}"><em>${reference.dataset.description}</em></p>
  363. <div class="tippy-links" lang="fr">
  364. <a href="${reference.href}">Archive au ${reference.dataset.date}</a>
  365. </div>
  366. `
  367. },
  368. allowHTML: true,
  369. interactive: true,
  370. delay: [150, 700],
  371. hideOnClick: false
  372. })
  373. </script>
  374. <script type="module">
  375. import { annotate } from '/static/david/js/rough-notation-0.5.1.esm.min.js'
  376. const markObserver = new IntersectionObserver((entries, observer) => {
  377. const computedStyle = getComputedStyle(document.documentElement)
  378. const markBackground = computedStyle.getPropertyValue('--mark-background')
  379. for (const entry of entries) {
  380. if (entry.intersectionRatio === 0) continue
  381. const markElement = entry.target
  382. markElement.style.backgroundColor = 'inherit'
  383. const annotation = annotate(
  384. markElement, {
  385. type: 'highlight',
  386. multiline: true,
  387. color: markBackground,
  388. // animate: !window.matchMedia('(prefers-reduced-motion: reduce)').matches
  389. animate: false
  390. }
  391. )
  392. annotation.show()
  393. observer.unobserve(markElement)
  394. }
  395. }, {threshold: 1.0})
  396. for (const markElement of document.querySelectorAll('mark')) {
  397. markObserver.observe(markElement)
  398. }
  399. </script>
  400. </body>
  401. </html>