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 38KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="en">
  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>The Stack: Every Layout (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. <!-- Is that even respected? Retrospectively? What a shAItshow…
  28. https://neil-clarke.com/block-the-bots-that-feed-ai-models-by-scraping-your-website/ -->
  29. <meta name="robots" content="noai, noimageai">
  30. <!-- Documented, feel free to shoot an email. -->
  31. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  32. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  33. <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>
  34. <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>
  35. <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>
  36. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  37. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  38. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  39. <script>
  40. function toggleTheme(themeName) {
  41. document.documentElement.classList.toggle(
  42. 'forced-dark',
  43. themeName === 'dark'
  44. )
  45. document.documentElement.classList.toggle(
  46. 'forced-light',
  47. themeName === 'light'
  48. )
  49. }
  50. const selectedTheme = localStorage.getItem('theme')
  51. if (selectedTheme !== 'undefined') {
  52. toggleTheme(selectedTheme)
  53. }
  54. </script>
  55. <meta name="robots" content="noindex, nofollow">
  56. <meta content="origin-when-cross-origin" name="referrer">
  57. <!-- Canonical URL for SEO purposes -->
  58. <link rel="canonical" href="https://every-layout.dev/layouts/stack/#the-component">
  59. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  60. <article>
  61. <header>
  62. <h1>The Stack: Every Layout</h1>
  63. </header>
  64. <nav>
  65. <p class="center">
  66. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  67. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  68. </svg> Accueil</a> •
  69. <a href="https://every-layout.dev/layouts/stack/#the-component" title="Lien vers le contenu original">Source originale</a>
  70. <br>
  71. Mis en cache le 2024-02-22
  72. </p>
  73. </nav>
  74. <hr>
  75. <p>Flow elements require space (sometimes referred to as <em>white space</em>) to physically and conceptually separate them from the elements that come before and after them. This is the purpose of the <code>margin</code> property.</p>
  76. <p>However, design systems conceive elements and components in isolation. At the time of conception, it is not settled whether there will be surrounding content or what the nature of that content will be. One element or component is likely to appear in different contexts, and the requirement for spacing will differ.</p>
  77. <p>We are in the habit of styling elements, or classes of elements, directly: we make style declarations <em>belong</em> to elements. Typically, this does not produce any issues, but <code>margin</code> is really a property of the <em>relationship</em> between two proximate elements. The following code is therefore problematic:</p>
  78. <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">p</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 1.5rem<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
  79. <p>Since the declaration is not context sensitive, any correct application of the margin is a matter of luck. If the paragraph is proceeded by another element, the effect is desirable. But a <code>:last-child</code> paragraph produces a redundant margin. Inside a padded parent element, this redundant margin combines with the parent’s padding to produce double the intended space. This is just one problem this approach produces.</p>
  80. <p>The trick is to style the context, not the individual element(s). The <strong>Stack</strong> layout primitive injects margin between elements via their common parent:</p>
  81. <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">.stack &gt; * + *</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">margin-block-start</span><span class="token punctuation">:</span> 1.5rem<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
  82. <p>Using the adjacent sibling combinator (<code>+</code>), <code>margin-block-start</code> is only applied where the element is preceded by another element: no “left over” margin. The universal (or <em>wildcard</em>) selector (<code>*</code>) ensures any and all elements are affected. The key <code>* + *</code> construct is known as the <a href="https://alistapart.com/article/axiomatic-css-and-lobotomized-owls">owl</a>.</p>
  83. <div role="complementary" aria-labelledby="line-height-and-modular-scale" class="docs-note">
  84. <h3 id="line-height-and-modular-scale" aria-hidden="true">
  85. <svg class="docs-icon" focusable="false">
  86. false
  87. <use xlink:href="/images/all.svg#icon-info"></use>
  88. </svg>
  89. Line height and modular scale
  90. </h3>
  91. <p>In the previous example, we used a <code>margin-block-start</code> value of <code>1.5rem</code>. We’re in the habit of using this value because it reflects our (usually preferred) body text <code>line-height</code> of <code>1.5</code>.</p>
  92. <p>The vertical spacing of your design should be based on your standard <code>line-height</code> because text dominates most pages’ layout, making one line of text a natural denominator.</p>
  93. <p>If the body text <code>line-height</code> is <code>1.5</code> (i.e. <code>1.5</code> ⨉ the <code>font-size</code>), it makes sense to use <code>1.5</code> as the ratio for your modular scale. Read the <a href="/rudiments/modular-scale">introduction to modular scale</a>, and how it can be expressed with CSS custom properties.</p>
  94. </div>
  95. <h3 id="recursion">Recursion</h3>
  96. <p>In the previous example, the child combinator (<code>&gt;</code>) ensures the margins only apply to children of the <code>.stack</code> element. However, it’s possible to inject margins recursively by removing this combinator from the selector.</p>
  97. <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">.stack * + *</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">margin-block-start</span><span class="token punctuation">:</span> 1.5rem<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
  98. <p>This can be useful where you want to affect elements at any nesting level, while retaining white space regularity.</p>
  99. <p>In the following demonstration (using the <a href="#the-component">Stack component</a> to follow) there are a set of box-shaped elements. Two of these are nested within another. Because recursion is applied, each box is evenly spaced using just one parent <strong>Stack</strong>.</p>
  100. <noscript>
  101. <svg class="docs-icon" focusable="false">
  102. <use xlink:href="/images/all.svg#icon-warning"></use>
  103. </svg>
  104. This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality.
  105. </noscript>
  106. <p>You’re likely to find the recursive mode affects unwanted elements. For example, generic list items that are typically not separated by margins will become unexpectedly <em>spread out</em>.</p>
  107. <h3 id="nested-variants">Nested variants</h3>
  108. <p>Recursion applies the same margin no matter the nesting depth. A more deliberate approach would be to set up alternative non-recursive <strong>Stacks</strong> with different margin values, and nest them where suitable. Consider the following.</p>
  109. <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">[class^='stack'] &gt; *</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> </span><br><span class="highlight-line"> <span class="token property">margin-block</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token selector">.stack-large &gt; * + *</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">margin-block-start</span><span class="token punctuation">:</span> 3rem<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token selector">.stack-small &gt; * + *</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">margin-block-start</span><span class="token punctuation">:</span> 0.5rem<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
  110. <noscript>
  111. <svg class="docs-icon" focusable="false">
  112. <use xlink:href="/images/all.svg#icon-warning"></use>
  113. </svg>
  114. This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality.
  115. </noscript>
  116. <p>The first declaration block’s selector resets the vertical margin for all <strong>Stack</strong>-like elements (by matching class values that <em>begin</em> with <code>stack</code>). Importantly, only the vertical margins are reset, because the stack only <em>affects</em> vertical margin, and we don't want it to reach outside its remit. You may not need this reset if a universal reset for <code>margin</code> is already in place (see <a href="/rudiments/global-and-local-styling"><strong>Global and local styling</strong></a>).</p>
  117. <p>The following two blocks set up alternative <strong>Stacks</strong>, with different margin values. These can be nested to produce—for example—the illustrated form layout. Be aware that the <code>&lt;label&gt;</code> elements would need to have <code>display: block</code> applied to appear above the inputs, and for their margins to actually produce spaces (the vertical margin of inline elements has no effect; see <a href="/rudiments/boxes#the-display-property"><strong>The display property</strong></a>).</p>
  118. <p>In <strong>Every Layout</strong>, custom elements are used to implement layout components/primitives like the <strong>Stack</strong>. In <a href="#the-component">the <strong>Stack</strong> component</a>, the <code>space</code> prop (property; attribute) is used to define the spacing value. The modified classes example above is just for illustration. See the <a href="#nested">nested example</a>.</p>
  119. <h3 id="exceptions">Exceptions</h3>
  120. <p>CSS works best as an exception-based language. You write far-reaching rules, then use the cascade to override these rules in special cases. As written in <a href="https://24ways.org/2018/managing-flow-and-rhythm-with-css-custom-properties/">Managing Flow and Rhythm with CSS Custom Properties</a>, you can create per-element exceptions within a single <strong>Stack</strong> context (i.e. at the same nesting level).</p>
  121. <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">.stack &gt; * + *</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">margin-block-start</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--space, 1.5em<span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token selector">.stack-exception,</span><br><span class="highlight-line">.stack-exception + *</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">--space</span><span class="token punctuation">:</span> 3rem<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
  122. <p>Note that we are applying the increased spacing above <em>and</em> below the <code>.exception</code> element, where applicable. If you only wanted to increase the space above, you would remove <code>.exception + *</code>.</p>
  123. <p>This works because <code>*</code> has <em>zero</em> specificity, so <code>.stack &gt; * + *</code> and <code>.stack-exception</code> are the same specificity and <code>.stack-exception</code> overrides <code>.stack &gt; * + *</code> in the cascade (by appearing further down in the stylesheet).</p>
  124. <h3 id="splitting-the-stack">Splitting the stack</h3>
  125. <p>By making the <strong>Stack</strong> a Flexbox context, we can give it one final power: the ability to add an <code>auto</code> margin to a chosen element. This way, we can group elements to the top and bottom of the vertical space. Useful for card-like components.</p>
  126. <p>In the following example, we've chosen to group elements <em>after</em> the second element towards the bottom of the space.</p>
  127. <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">.stack</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span></span><br><span class="highlight-line"> <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span></span><br><span class="highlight-line"> <span class="token property">justify-content</span><span class="token punctuation">:</span> flex-start<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token selector">.stack &gt; * + *</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">margin-block-start</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--space, 1.5rem<span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token selector">.stack &gt; :nth-child(2)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token property">margin-block-end</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
  128. <div role="complementary" aria-labelledby="custom-property-placement" class="docs-note">
  129. <h3 id="custom-property-placement" aria-hidden="true">
  130. <svg class="docs-icon" focusable="false">
  131. false
  132. <use xlink:href="/images/all.svg#icon-info"></use>
  133. </svg>
  134. Custom property placement
  135. </h3>
  136. <p>Importantly, despite now setting some properties on the parent <code>.stack</code> element, we’re still setting the <code>--space</code> value on the children, not “hoisting” it up. If the parent is where the property is set, it will get overridden if the parent becomes a child in nesting (see <a href="#nested-variants"><strong>Nested variants</strong></a>, above).</p>
  137. </div>
  138. <p>This can be seen working in context in the following demo depicting a presentation/slides editor. The <a href="/layouts/cover"><strong>Cover</strong></a> element on the right has a minimum height of <code>66.666vh</code>, forcing the left sidebar's height to be taller than its content. This is what produces the gap between the slide images and the <em>"Add slide"</em> button.</p>
  139. <noscript>
  140. <svg class="docs-icon" focusable="false">
  141. <use xlink:href="/images/all.svg#icon-warning"></use>
  142. </svg>
  143. This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality.
  144. </noscript>
  145. <div class="docs-demo-inline">
  146. <p id="description">A slides editor interface with a sidebar. The sidebar has images towards the
  147. top and an add slide button pushed down to the bottom.</p>
  148. <shrink-grow unit="rem" aria-labelledby="Splitting a stack to push a button to the bottom of the screen in a slide editor layout">
  149. <sidebar-l contentmin="66.666%" data-i="Sidebar-left66.666%var(--s1)">
  150. <stack-l splitafter="2" data-i="Stack-var(--s1)false2">
  151. <image-l ratio="6:9" aria-label="Image with 6:9 ratio" data-i="Image-6:90none" role="img"></image-l>
  152. <image-l ratio="6:9" aria-label="Image with 6:9 ratio" data-i="Image-6:90none" role="img"></image-l>
  153. <button>Add slide +</button>
  154. </stack-l>
  155. <box-l data-i="Box-var(--s1)var(--border-thin)false">
  156. <cover-l centered=".centered" minheight="66.666vh" nopad="" data-i="Cover-.centeredvar(--s1)66.666vhtrue">
  157. <stack-l class="centered text-align:center" data-i="Stack-var(--s1)false">
  158. <h1 role="none">Title of slide</h1>
  159. <text-l words="50"><p><span>sed</span> <span>ultrices</span> <span>efficitur</span> <span>faucibus</span> <span>erat</span> <span>id</span> <span>sapien</span> <span>sapien</span> <span>nisl</span> <span>in</span> <span>ornare</span> <span>mi</span> <span>felis</span> <span>fusce</span> <span>vestibulum</span> <span>semper</span> <span>cras</span> <span>tellus</span> <span>justo</span> <span>eget</span> <span>pellentesque</span> <span>ipsum</span> <span>donec</span> <span>pretium</span> <span>bibendum</span> <span>auctor</span> <span>vitae</span> <span>porttitor</span> <span>tristique</span> <span>mauris</span> <span>ante</span> <span>quam</span> <span>orci</span> <span>ac</span> <span>mattis</span> <span>morbi</span> <span>urna</span> <span>eu</span> <span>in</span> <span>leo</span> <span>vestibulum</span> <span>arcu</span> <span>tempus</span> <span>nibh</span> <span>eget</span> <span>non</span> <span>morbi</span> <span>vitae</span> <span>neque</span> <span>arcu</span></p></text-l>
  160. </stack-l>
  161. </cover-l>
  162. </box-l>
  163. </sidebar-l>
  164. </shrink-grow>
  165. </div>
  166. <p>Where the <strong>Stack</strong> is the only child of its parent, nothing forces it to <em>stretch</em> as in the last example/demo. A height of <code>100%</code> ensures the <strong>Stack's</strong> height <em>matches</em> the parent's and the split can occur.</p>
  167. <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">.stack:only-child</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> </span><br><span class="highlight-line"> <span class="token property">block-size</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
  168. <p>The potential remit of the <strong>Stack</strong> layout can hardly be overestimated. Anywhere elements are stacked one atop another, it is likely a <strong>Stack</strong> should be in effect. Only adjacent elements (such as grid cells) should not be subject to a <strong>Stack</strong>. The grid cells <em>are</em> likely to be <strong>Stacks</strong>, however, and the grid itself a member of a <strong>Stack</strong>.</p>
  169. <noscript>
  170. <svg class="docs-icon" focusable="false">
  171. <use xlink:href="/images/all.svg#icon-warning"></use>
  172. </svg>
  173. The code generator only works where JavaScript is available and switched on.
  174. </noscript>
  175. <p>Use this tool to help you generate basic <strong>Stack</strong> CSS and HTML.</p>
  176. <p>A custom element implementation of the <strong>Stack</strong> is provided for download. Consult the API and examples to follow for more information.</p>
  177. <p><a class="cta cta--big" href="/downloads/Stack.zip" download="">
  178. <svg class="docs-icon" focusable="false">
  179. <use xlink:href="/images/all.svg#icon-download"></use>
  180. </svg>
  181. <span>Download Stack.zip</span>
  182. </a></p>
  183. <h3>Props API</h3>
  184. <p>The following props (attributes) will cause the <strong>Stack</strong> component to re-render when altered. They can be altered by hand—in browser developer tools—or as the subjects of inherited application state.</p>
  185. <div class="docs-props-table">
  186. <table>
  187. <thead>
  188. <tr>
  189. <th>Name</th>
  190. <th>Type</th>
  191. <th>Default</th>
  192. <th>Description</th>
  193. </tr>
  194. </thead>
  195. <tbody>
  196. <tr>
  197. <td>space</td>
  198. <td><code>string</code></td>
  199. <td><code>"var(--s1)"</code></td>
  200. <td>A CSS <code>margin</code> value</td>
  201. </tr>
  202. <tr>
  203. <td>recursive</td>
  204. <td><code>boolean</code></td>
  205. <td><code>false</code></td>
  206. <td>Whether the spaces apply recursively (i.e. regardless of nesting level)</td>
  207. </tr>
  208. <tr>
  209. <td>splitAfter</td>
  210. <td><code>number</code></td>
  211. <td><code></code></td>
  212. <td>The element after which to <em>split</em> the stack with an auto margin</td>
  213. </tr>
  214. </tbody>
  215. </table>
  216. </div>
  217. <h3 id="examples">Examples</h3>
  218. <h4 id="basic">Basic</h4>
  219. <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>stack-l</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>path/to/some/image.svg<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>stack-l</span><span class="token punctuation">&gt;</span></span></span></code></pre>
  220. <h4 id="nested">Nested</h4>
  221. <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>stack-l</span> <span class="token attr-name">space</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>3rem<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>stack-l</span> <span class="token attr-name">space</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>1.5rem<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>stack-l</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>stack-l</span> <span class="token attr-name">space</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>1.5rem<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>stack-l</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>stack-l</span><span class="token punctuation">&gt;</span></span></span></code></pre>
  222. <h4 id="recursive">Recursive</h4>
  223. <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>stack-l</span> <span class="token attr-name">recursive</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>stack-l</span><span class="token punctuation">&gt;</span></span></span></code></pre>
  224. <h4 id="list-semantics">List semantics</h4>
  225. <p>In some cases, browsers should interpret the <strong>Stack</strong> as a list for screen reader software. You can use the following ARIA attribution to achieve this.</p>
  226. <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>stack-l</span> <span class="token attr-name">role</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">role</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>listitem<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">role</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>listitem<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">role</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>listitem<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>stack-l</span><span class="token punctuation">&gt;</span></span></span></code></pre>
  227. </article>
  228. <hr>
  229. <footer>
  230. <p>
  231. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  232. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  233. </svg> Accueil</a> •
  234. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  235. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  236. </svg> Suivre</a> •
  237. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  238. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  239. </svg> Pro</a> •
  240. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  241. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  242. </svg> Email</a> •
  243. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  244. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  245. </svg> Légal</abbr>
  246. </p>
  247. <template id="theme-selector">
  248. <form>
  249. <fieldset>
  250. <legend><svg class="icon icon-brightness-contrast">
  251. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  252. </svg> Thème</legend>
  253. <label>
  254. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  255. </label>
  256. <label>
  257. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  258. </label>
  259. <label>
  260. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  261. </label>
  262. </fieldset>
  263. </form>
  264. </template>
  265. </footer>
  266. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  267. <script>
  268. function loadThemeForm(templateName) {
  269. const themeSelectorTemplate = document.querySelector(templateName)
  270. const form = themeSelectorTemplate.content.firstElementChild
  271. themeSelectorTemplate.replaceWith(form)
  272. form.addEventListener('change', (e) => {
  273. const chosenColorScheme = e.target.value
  274. localStorage.setItem('theme', chosenColorScheme)
  275. toggleTheme(chosenColorScheme)
  276. })
  277. const selectedTheme = localStorage.getItem('theme')
  278. if (selectedTheme && selectedTheme !== 'undefined') {
  279. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  280. }
  281. }
  282. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  283. window.addEventListener('load', () => {
  284. let hasDarkRules = false
  285. for (const styleSheet of Array.from(document.styleSheets)) {
  286. let mediaRules = []
  287. for (const cssRule of styleSheet.cssRules) {
  288. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  289. continue
  290. }
  291. // WARNING: Safari does not have/supports `conditionText`.
  292. if (cssRule.conditionText) {
  293. if (cssRule.conditionText !== prefersColorSchemeDark) {
  294. continue
  295. }
  296. } else {
  297. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  298. continue
  299. }
  300. }
  301. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  302. }
  303. // WARNING: do not try to insert a Rule to a styleSheet you are
  304. // currently iterating on, otherwise the browser will be stuck
  305. // in a infinite loop…
  306. for (const mediaRule of mediaRules) {
  307. styleSheet.insertRule(mediaRule.cssText)
  308. hasDarkRules = true
  309. }
  310. }
  311. if (hasDarkRules) {
  312. loadThemeForm('#theme-selector')
  313. }
  314. })
  315. </script>
  316. </body>
  317. </html>