@@ -0,0 +1,338 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="en"> | |||
<!-- Has to be within the first 1024 bytes, hence before the `title` element | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>The Stack: Every Layout (archive) — David Larlet</title> | |||
<meta name="description" content="Publication mise en cache pour en conserver une trace."> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f7f7f7"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)"> | |||
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)"> | |||
<!-- Is that even respected? Retrospectively? What a shAItshow… | |||
https://neil-clarke.com/block-the-bots-that-feed-ai-models-by-scraping-your-website/ --> | |||
<meta name="robots" content="noai, noimageai"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://every-layout.dev/layouts/stack/#the-component"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all"> | |||
<article> | |||
<header> | |||
<h1>The Stack: Every Layout</h1> | |||
</header> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use> | |||
</svg> Accueil</a> • | |||
<a href="https://every-layout.dev/layouts/stack/#the-component" title="Lien vers le contenu original">Source originale</a> | |||
<br> | |||
Mis en cache le 2024-02-22 | |||
</p> | |||
</nav> | |||
<hr> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<div role="complementary" aria-labelledby="line-height-and-modular-scale" class="docs-note"> | |||
<h3 id="line-height-and-modular-scale" aria-hidden="true"> | |||
<svg class="docs-icon" focusable="false"> | |||
false | |||
<use xlink:href="/images/all.svg#icon-info"></use> | |||
</svg> | |||
Line height and modular scale | |||
</h3> | |||
<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> | |||
<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> | |||
<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> | |||
</div> | |||
<h3 id="recursion">Recursion</h3> | |||
<p>In the previous example, the child combinator (<code>></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> | |||
<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> | |||
<p>This can be useful where you want to affect elements at any nesting level, while retaining white space regularity.</p> | |||
<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> | |||
<noscript> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-warning"></use> | |||
</svg> | |||
This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality. | |||
</noscript> | |||
<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> | |||
<h3 id="nested-variants">Nested variants</h3> | |||
<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> | |||
<pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">[class^='stack'] > *</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 > * + *</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 > * + *</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> | |||
<noscript> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-warning"></use> | |||
</svg> | |||
This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality. | |||
</noscript> | |||
<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> | |||
<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><label></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> | |||
<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> | |||
<h3 id="exceptions">Exceptions</h3> | |||
<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> | |||
<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> <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> | |||
<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> | |||
<p>This works because <code>*</code> has <em>zero</em> specificity, so <code>.stack > * + *</code> and <code>.stack-exception</code> are the same specificity and <code>.stack-exception</code> overrides <code>.stack > * + *</code> in the cascade (by appearing further down in the stylesheet).</p> | |||
<h3 id="splitting-the-stack">Splitting the stack</h3> | |||
<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> | |||
<p>In the following example, we've chosen to group elements <em>after</em> the second element towards the bottom of the space.</p> | |||
<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 > * + *</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 > :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> | |||
<div role="complementary" aria-labelledby="custom-property-placement" class="docs-note"> | |||
<h3 id="custom-property-placement" aria-hidden="true"> | |||
<svg class="docs-icon" focusable="false"> | |||
false | |||
<use xlink:href="/images/all.svg#icon-info"></use> | |||
</svg> | |||
Custom property placement | |||
</h3> | |||
<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> | |||
</div> | |||
<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> | |||
<noscript> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-warning"></use> | |||
</svg> | |||
This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality. | |||
</noscript> | |||
<div class="docs-demo-inline"> | |||
<p id="description">A slides editor interface with a sidebar. The sidebar has images towards the | |||
top and an add slide button pushed down to the bottom.</p> | |||
<shrink-grow unit="rem" aria-labelledby="Splitting a stack to push a button to the bottom of the screen in a slide editor layout"> | |||
<sidebar-l contentmin="66.666%" data-i="Sidebar-left66.666%var(--s1)"> | |||
<stack-l splitafter="2" data-i="Stack-var(--s1)false2"> | |||
<image-l ratio="6:9" aria-label="Image with 6:9 ratio" data-i="Image-6:90none" role="img"></image-l> | |||
<image-l ratio="6:9" aria-label="Image with 6:9 ratio" data-i="Image-6:90none" role="img"></image-l> | |||
<button>Add slide +</button> | |||
</stack-l> | |||
<box-l data-i="Box-var(--s1)var(--border-thin)false"> | |||
<cover-l centered=".centered" minheight="66.666vh" nopad="" data-i="Cover-.centeredvar(--s1)66.666vhtrue"> | |||
<stack-l class="centered text-align:center" data-i="Stack-var(--s1)false"> | |||
<h1 role="none">Title of slide</h1> | |||
<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> | |||
</stack-l> | |||
</cover-l> | |||
</box-l> | |||
</sidebar-l> | |||
</shrink-grow> | |||
</div> | |||
<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> | |||
<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> | |||
<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> | |||
<noscript> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-warning"></use> | |||
</svg> | |||
The code generator only works where JavaScript is available and switched on. | |||
</noscript> | |||
<p>Use this tool to help you generate basic <strong>Stack</strong> CSS and HTML.</p> | |||
<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> | |||
<p><a class="cta cta--big" href="/downloads/Stack.zip" download=""> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-download"></use> | |||
</svg> | |||
<span>Download Stack.zip</span> | |||
</a></p> | |||
<h3>Props API</h3> | |||
<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> | |||
<div class="docs-props-table"> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th>Name</th> | |||
<th>Type</th> | |||
<th>Default</th> | |||
<th>Description</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<td>space</td> | |||
<td><code>string</code></td> | |||
<td><code>"var(--s1)"</code></td> | |||
<td>A CSS <code>margin</code> value</td> | |||
</tr> | |||
<tr> | |||
<td>recursive</td> | |||
<td><code>boolean</code></td> | |||
<td><code>false</code></td> | |||
<td>Whether the spaces apply recursively (i.e. regardless of nesting level)</td> | |||
</tr> | |||
<tr> | |||
<td>splitAfter</td> | |||
<td><code>number</code></td> | |||
<td><code></code></td> | |||
<td>The element after which to <em>split</em> the stack with an auto margin</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<h3 id="examples">Examples</h3> | |||
<h4 id="basic">Basic</h4> | |||
<pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>stack-l</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">/></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span></code></pre> | |||
<h4 id="nested">Nested</h4> | |||
<pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span></code></pre> | |||
<h4 id="recursive">Recursive</h4> | |||
<pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>stack-l</span> <span class="token attr-name">recursive</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span></code></pre> | |||
<h4 id="list-semantics">List semantics</h4> | |||
<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> | |||
<pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span></code></pre> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use> | |||
</svg> Accueil</a> • | |||
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use> | |||
</svg> Suivre</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use> | |||
</svg> Pro</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use> | |||
</svg> Email</a> • | |||
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use> | |||
</svg> Légal</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend><svg class="icon icon-brightness-contrast"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use> | |||
</svg> Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script> | |||
<script> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,174 @@ | |||
title: The Stack: Every Layout | |||
url: https://every-layout.dev/layouts/stack/#the-component | |||
hash_url: 6b2b8e2559a07b8d66dac842017b2619 | |||
archive_date: 2024-02-22 | |||
og_image: https://every-layout.dev/images/card.png | |||
description: A composable CSS layout primitive. | |||
favicon: https://every-layout.dev/images/favicon.png | |||
language: en_US | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<div role="complementary" aria-labelledby="line-height-and-modular-scale" class="docs-note"> | |||
<h3 id="line-height-and-modular-scale" aria-hidden="true"> | |||
<svg class="docs-icon" focusable="false"> | |||
false | |||
<use xlink:href="/images/all.svg#icon-info"></use> | |||
</svg> | |||
Line height and modular scale | |||
</h3> | |||
<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> | |||
<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> | |||
<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> | |||
</div> | |||
<h3 id="recursion">Recursion</h3> | |||
<p>In the previous example, the child combinator (<code>></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> | |||
<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> | |||
<p>This can be useful where you want to affect elements at any nesting level, while retaining white space regularity.</p> | |||
<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> | |||
<noscript> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-warning"></use> | |||
</svg> | |||
This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality. | |||
</noscript> | |||
<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> | |||
<h3 id="nested-variants">Nested variants</h3> | |||
<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> | |||
<pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">[class^='stack'] > *</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 > * + *</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 > * + *</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> | |||
<noscript> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-warning"></use> | |||
</svg> | |||
This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality. | |||
</noscript> | |||
<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> | |||
<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><label></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> | |||
<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> | |||
<h3 id="exceptions">Exceptions</h3> | |||
<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> | |||
<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> <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> | |||
<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> | |||
<p>This works because <code>*</code> has <em>zero</em> specificity, so <code>.stack > * + *</code> and <code>.stack-exception</code> are the same specificity and <code>.stack-exception</code> overrides <code>.stack > * + *</code> in the cascade (by appearing further down in the stylesheet).</p> | |||
<h3 id="splitting-the-stack">Splitting the stack</h3> | |||
<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> | |||
<p>In the following example, we've chosen to group elements <em>after</em> the second element towards the bottom of the space.</p> | |||
<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 > * + *</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 > :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> | |||
<div role="complementary" aria-labelledby="custom-property-placement" class="docs-note"> | |||
<h3 id="custom-property-placement" aria-hidden="true"> | |||
<svg class="docs-icon" focusable="false"> | |||
false | |||
<use xlink:href="/images/all.svg#icon-info"></use> | |||
</svg> | |||
Custom property placement | |||
</h3> | |||
<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> | |||
</div> | |||
<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> | |||
<noscript> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-warning"></use> | |||
</svg> | |||
This demo becomes interactive with JavaScript. If you enable JavaScript, you will be able to use the interactive functionality. | |||
</noscript> | |||
<div class="docs-demo-inline"> | |||
<p id="description">A slides editor interface with a sidebar. The sidebar has images towards the | |||
top and an add slide button pushed down to the bottom.</p> | |||
<shrink-grow unit="rem" aria-labelledby="Splitting a stack to push a button to the bottom of the screen in a slide editor layout"> | |||
<sidebar-l contentmin="66.666%" data-i="Sidebar-left66.666%var(--s1)"> | |||
<stack-l splitafter="2" data-i="Stack-var(--s1)false2"> | |||
<image-l ratio="6:9" aria-label="Image with 6:9 ratio" data-i="Image-6:90none" role="img"></image-l> | |||
<image-l ratio="6:9" aria-label="Image with 6:9 ratio" data-i="Image-6:90none" role="img"></image-l> | |||
<button>Add slide +</button> | |||
</stack-l> | |||
<box-l data-i="Box-var(--s1)var(--border-thin)false"> | |||
<cover-l centered=".centered" minheight="66.666vh" nopad="" data-i="Cover-.centeredvar(--s1)66.666vhtrue"> | |||
<stack-l class="centered text-align:center" data-i="Stack-var(--s1)false"> | |||
<h1 role="none">Title of slide</h1> | |||
<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> | |||
</stack-l> | |||
</cover-l> | |||
</box-l> | |||
</sidebar-l> | |||
</shrink-grow> | |||
</div> | |||
<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> | |||
<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> | |||
<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> | |||
<noscript> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-warning"></use> | |||
</svg> | |||
The code generator only works where JavaScript is available and switched on. | |||
</noscript> | |||
<p>Use this tool to help you generate basic <strong>Stack</strong> CSS and HTML.</p> | |||
<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> | |||
<a class="cta cta--big" href="/downloads/Stack.zip" download=""> | |||
<svg class="docs-icon" focusable="false"> | |||
<use xlink:href="/images/all.svg#icon-download"></use> | |||
</svg> | |||
<span>Download Stack.zip</span> | |||
</a> | |||
<h3>Props API</h3> | |||
<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> | |||
<div class="docs-props-table"> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th>Name</th> | |||
<th>Type</th> | |||
<th>Default</th> | |||
<th>Description</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<td>space</td> | |||
<td><code>string</code></td> | |||
<td><code>"var(--s1)"</code></td> | |||
<td>A CSS <code>margin</code> value</td> | |||
</tr> | |||
<tr> | |||
<td>recursive</td> | |||
<td><code>boolean</code></td> | |||
<td><code>false</code></td> | |||
<td>Whether the spaces apply recursively (i.e. regardless of nesting level)</td> | |||
</tr> | |||
<tr> | |||
<td>splitAfter</td> | |||
<td><code>number</code></td> | |||
<td><code></code></td> | |||
<td>The element after which to <em>split</em> the stack with an auto margin</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<h3 id="examples">Examples</h3> | |||
<h4 id="basic">Basic</h4> | |||
<pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>stack-l</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">/></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span></code></pre> | |||
<h4 id="nested">Nested</h4> | |||
<pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span></code></pre> | |||
<h4 id="recursive">Recursive</h4> | |||
<pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>stack-l</span> <span class="token attr-name">recursive</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span></code></pre> | |||
<h4 id="list-semantics">List semantics</h4> | |||
<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> | |||
<pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>stack-l</span><span class="token punctuation">></span></span></span></code></pre> |
@@ -0,0 +1,217 @@ | |||
<!doctype html><!-- This is a valid HTML5 document. --> | |||
<!-- Screen readers, SEO, extensions and so on. --> | |||
<html lang="fr"> | |||
<!-- Has to be within the first 1024 bytes, hence before the `title` element | |||
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> | |||
<meta charset="utf-8"> | |||
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> | |||
<!-- The viewport meta is quite crowded and we are responsible for that. | |||
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> | |||
<meta name="viewport" content="width=device-width,initial-scale=1"> | |||
<!-- Required to make a valid HTML5 document. --> | |||
<title>TousAntiCovid : vu depuis Codeureuses en Liberté (archive) — David Larlet</title> | |||
<meta name="description" content="Publication mise en cache pour en conserver une trace."> | |||
<!-- That good ol' feed, subscribe :). --> | |||
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> | |||
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> | |||
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> | |||
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> | |||
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#f7f7f7"> | |||
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> | |||
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)"> | |||
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)"> | |||
<!-- Is that even respected? Retrospectively? What a shAItshow… | |||
https://neil-clarke.com/block-the-bots-that-feed-ai-models-by-scraping-your-website/ --> | |||
<meta name="robots" content="noai, noimageai"> | |||
<!-- Documented, feel free to shoot an email. --> | |||
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css"> | |||
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> | |||
<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> | |||
<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> | |||
<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> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> | |||
<script> | |||
function toggleTheme(themeName) { | |||
document.documentElement.classList.toggle( | |||
'forced-dark', | |||
themeName === 'dark' | |||
) | |||
document.documentElement.classList.toggle( | |||
'forced-light', | |||
themeName === 'light' | |||
) | |||
} | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme !== 'undefined') { | |||
toggleTheme(selectedTheme) | |||
} | |||
</script> | |||
<meta name="robots" content="noindex, nofollow"> | |||
<meta content="origin-when-cross-origin" name="referrer"> | |||
<!-- Canonical URL for SEO purposes --> | |||
<link rel="canonical" href="https://www.codeursenliberte.fr/blog/tous_anti_covid/"> | |||
<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all"> | |||
<article> | |||
<header> | |||
<h1>TousAntiCovid : vu depuis Codeureuses en Liberté</h1> | |||
</header> | |||
<nav> | |||
<p class="center"> | |||
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use> | |||
</svg> Accueil</a> • | |||
<a href="https://www.codeursenliberte.fr/blog/tous_anti_covid/" title="Lien vers le contenu original">Source originale</a> | |||
<br> | |||
Mis en cache le 2024-02-22 | |||
</p> | |||
</nav> | |||
<hr> | |||
<p>TousAntiCovid a refait récemment l’<a href="https://www.huffingtonpost.fr/justice/article/application-stopcovid-la-justice-enquete-sur-des-soupcons-de-favoritisme_181078.html">actualité</a> sur les montants de l’hébergement et les modalités d’attribution du marché. À l’époque, Codeureuses en Liberté avait été approchée pour envisager la réalisation de cette application. On vous livre ici nos reflexions de l’époque.</p> | |||
<p>Au début de l’épidémie de covid-19, il y a eu la croyance qu’une solution informatique pourrait être utile pour atténuer l’engorgement des hôpitaux grace au <a href="https://fr.wikipedia.org/wiki/Recherche_des_contacts">contact tracing (recherche de contacts)</a>. L’état français a donc voulu une application qui deviendrait <a href="https://fr.wikipedia.org/wiki/TousAntiCovid">TousAntiCovid</a> (initialement <em>StopCovid</em>).</p> | |||
<p>En 2020, Codeureuses en Liberté est co-attributaire<sup id="fnref:1"></sup> d’un contrat cadre avec la <a href="https://www.numerique.gouv.fr/dinum/">Direction interministérielle du numérique (DINUM)</a><sup id="fnref:2"></sup>. Dans ce cadre, nous étions souvent intermédiaires d’autres indépendant·e·s qui intervenaient sur des <a href="https://beta.gouv.fr/startups/">startup d’état</a> de <em>beta.gouv.fr</em><sup id="fnref:3"></sup>.</p> | |||
<p>Le 11 avril 2020, la DINUM nous contacte et s’ensuivent des discussions sur notre messagerie :</p> | |||
<blockquote> | |||
<p><cite>Tristram</cite><br> | |||
Question assez importante : [notre contact à beta] demande quelle serait notre position sur porter les développement de l’app stop covid.<br> | |||
À première vue, j’ai du mal à me convaincre qu’on obtiendra des garanties suffisantes sur le respect de la vie privée, de l’autre c’est peut-être l’occasion de forcer (dans le devis, vis-à-vis des sous-traitants) de s’assurer qu’il n’y aura aucune donnée stockée, que le développement soit libre depuis le jour 1.<br> | |||
<code>@here</code> je me permet une notif, vu la complexité éthique du sujet et l’urgence (une réponse mardi serait souhaitée)</p> | |||
<p><cite>Vincent</cite><br> | |||
En fait j’aimerai bien avoir l’avis d’un infectiologue, je vois passer beaucoup de personnes sur les libertés publiques mais rien de l’avis de médecin.</p> | |||
<p><cite>Pierre</cite><br> | |||
Je pense qu’on peut peut-être faire légèrement moins pire que d’autres, mais que de toute manière, entre Google/Apple et le gouvernement, on aura une marge de manœuvre à peu près nulle.</p> | |||
<p><cite>Vincent</cite><br> | |||
J’ai l’impression qu’en refusant on se donne le beau rôle de «non ça c’est pas pour moi» mais bon on sait très bien qu’[une ESN] va le prendre derrière.</p> | |||
<p><cite>Tristram</cite><br> | |||
Il y a un risque de dérive et c’est là qu’on pourra ralentir, surtout en posant à chaque bon de commande des clauses et en étant très clair qu’on arrête tout si on dérive. Ce qui aurait l’avantage de ralentir pas mal, car ils devront retrouver d’autres personnes pour le faire.</p> | |||
<p><cite>Nicolas</cite><br> | |||
Si on fait juste du portage, on aura pas notre mot à dire sur le produit; est-ce que vous proposez qu’on lâche nos projets actuels pour nous consacrer à ça?</p> | |||
<p><cite>Kheops</cite><br> | |||
J’ai presque l’impression que le simple fait qu’on soit mis devant ce choix mérite déjà qu’on publie quelque chose à ce propos.</p> | |||
<p><cite>Thibaut</cite><br> | |||
L’application ne sera pas suffisante en elle-même pour juguler l’épidémie, ça serait trop beau. Mais elle peut être un outil efficace pour éviter des décès.<br> | |||
L’application ne pourra pas ne pas exister, donc donnons lui le meilleur cadre de développement possible.<br> | |||
Si elle devient obligatoire pour les possésseurs de smartphone, et que c’est finalement le consortium qui la développe, j’imagine qu’on aura des regrets.</p> | |||
</blockquote> | |||
<p>Après plein d’autres débats, de visios, nous avions fini par décider de participer en posant nos conditions. Voici l’email que nous nous préparions à envoyer.</p> | |||
<blockquote> | |||
<p>Nous exigeons de pouvoir communiquer publiquement (blog post sur notre site)sur ce projet dès la fin des débats parlementaires.</p> | |||
<p>Le blog post reprendra les lignes rouges suivantes, qui amènerait à ne pas reconduire le portage et a publier le refus de continuer : L’application et le serveur ne doivent servir qu’à lutter contre l’épidémie de coronavirus.</p> | |||
<p>On ne doit récolter que le minimum nécessaire de données. Aucun moyen de géolocalisation ne sera utilisé (par exemple GPS).</p> | |||
<p>Aucun identifiant ni identité ne sera associée à l’application.</p> | |||
<p>Les données sur le téléphone et sur le serveur ne seront conservées qu’une durée définie explicitement et argumentée (justifiée tant par l’état des connaissances médicales que par le besoin de respect de la vie privée).</p> | |||
<p>Les données utilisateurs ne seront transmises sur le serveur central qu’avec une action explicite et informée de l’utilisateur.</p> | |||
<p>Le code source intégral est publié sous une licence libre avant le déploiement et par la suite l’intégralité du processus de développement sera public.</p> | |||
<p>L’installation de l’application ne doit pas être discriminante et donc ne doit ni être un devoir ni conditionner l’accès à des droits (tel que le droit de se déplacer librement, ou donner l’exclusivité de l’accès aux tests du CoVid-19).</p> | |||
<p>L’appli ne doit pas embarquer de SDK d’analytics.</p> | |||
<p>Elle passera le crible d’exodus privacy sans problème.</p> | |||
</blockquote> | |||
<p>Ces discussions — comme toute discussion collective sur un sujet complexe — ont pris du temps. Cela n’a pas été facilité par la coordination avec le groupement, la DINUM et surtout l’évocation d’un accord de confidentialité. Au moment où nous allions envoyer cet email, nous apprenions que le projet était finalement confié au <a href="https://www.capgemini.com/fr-fr/actualites/communiques-de-presse/stopcovid/">consortium de l’angoisse</a> qui inclut Capgemini, Orange, Dassault Systèmes, Withing, d’autres structures privées et publiques, et, « dans l’écosystème », Atos, Accenture, Thalès ou encore Sopra Steria.</p> | |||
<p>Il n’y a pas vraiment de conclusion à tout ça. Nous avons été témoins, par le petit bout de la lorgnette, du tout début de cette histoire; nous avons imaginé un instant avoir l‘opportunité, ou le devoir, d’y faire quelque chose. Finalement, nous n’avons jamais vraiment donné notre avis. 🤷</p> | |||
</article> | |||
<hr> | |||
<footer> | |||
<p> | |||
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use> | |||
</svg> Accueil</a> • | |||
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use> | |||
</svg> Suivre</a> • | |||
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use> | |||
</svg> Pro</a> • | |||
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use> | |||
</svg> Email</a> • | |||
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use> | |||
</svg> Légal</abbr> | |||
</p> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend><svg class="icon icon-brightness-contrast"> | |||
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use> | |||
</svg> Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
</footer> | |||
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script> | |||
<script> | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
localStorage.setItem('theme', chosenColorScheme) | |||
toggleTheme(chosenColorScheme) | |||
}) | |||
const selectedTheme = localStorage.getItem('theme') | |||
if (selectedTheme && selectedTheme !== 'undefined') { | |||
form.querySelector(`[value="${selectedTheme}"]`).checked = true | |||
} | |||
} | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
} | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -0,0 +1,50 @@ | |||
title: TousAntiCovid : vu depuis Codeureuses en Liberté | |||
url: https://www.codeursenliberte.fr/blog/tous_anti_covid/ | |||
hash_url: ddc3ee3603be2702cef745c180b87776 | |||
archive_date: 2024-02-22 | |||
og_image: https://www.codeursenliberte.fr/logo.svg | |||
description: TousAntiCovid a refait récemment l’actualité sur les montants de l’hébergement et les modalités d’attribution du marché. | |||
favicon: https://www.codeursenliberte.fr/favicon.png | |||
language: fr_FR | |||
<p>TousAntiCovid a refait récemment l’<a href="https://www.huffingtonpost.fr/justice/article/application-stopcovid-la-justice-enquete-sur-des-soupcons-de-favoritisme_181078.html">actualité</a> sur les montants de l’hébergement et les modalités d’attribution du marché. À l’époque, Codeureuses en Liberté avait été approchée pour envisager la réalisation de cette application. On vous livre ici nos reflexions de l’époque.</p> | |||
<p>Au début de l’épidémie de covid-19, il y a eu la croyance qu’une solution informatique pourrait être utile pour atténuer l’engorgement des hôpitaux grace au <a href="https://fr.wikipedia.org/wiki/Recherche_des_contacts">contact tracing (recherche de contacts)</a>. L’état français a donc voulu une application qui deviendrait <a href="https://fr.wikipedia.org/wiki/TousAntiCovid">TousAntiCovid</a> (initialement <em>StopCovid</em>).</p> | |||
<p>En 2020, Codeureuses en Liberté est co-attributaire<sup id="fnref:1"></sup> d’un contrat cadre avec la <a href="https://www.numerique.gouv.fr/dinum/">Direction interministérielle du numérique (DINUM)</a><sup id="fnref:2"></sup>. Dans ce cadre, nous étions souvent intermédiaires d’autres indépendant·e·s qui intervenaient sur des <a href="https://beta.gouv.fr/startups/">startup d’état</a> de <em>beta.gouv.fr</em><sup id="fnref:3"></sup>.</p> | |||
<p>Le 11 avril 2020, la DINUM nous contacte et s’ensuivent des discussions sur notre messagerie :</p> | |||
<blockquote> | |||
<p><cite>Tristram</cite><br> | |||
Question assez importante : [notre contact à beta] demande quelle serait notre position sur porter les développement de l’app stop covid.<br> | |||
À première vue, j’ai du mal à me convaincre qu’on obtiendra des garanties suffisantes sur le respect de la vie privée, de l’autre c’est peut-être l’occasion de forcer (dans le devis, vis-à-vis des sous-traitants) de s’assurer qu’il n’y aura aucune donnée stockée, que le développement soit libre depuis le jour 1.<br> | |||
<code>@here</code> je me permet une notif, vu la complexité éthique du sujet et l’urgence (une réponse mardi serait souhaitée)</p> | |||
<p><cite>Vincent</cite><br> | |||
En fait j’aimerai bien avoir l’avis d’un infectiologue, je vois passer beaucoup de personnes sur les libertés publiques mais rien de l’avis de médecin.</p> | |||
<p><cite>Pierre</cite><br> | |||
Je pense qu’on peut peut-être faire légèrement moins pire que d’autres, mais que de toute manière, entre Google/Apple et le gouvernement, on aura une marge de manœuvre à peu près nulle.</p> | |||
<p><cite>Vincent</cite><br> | |||
J’ai l’impression qu’en refusant on se donne le beau rôle de «non ça c’est pas pour moi» mais bon on sait très bien qu’[une ESN] va le prendre derrière.</p> | |||
<p><cite>Tristram</cite><br> | |||
Il y a un risque de dérive et c’est là qu’on pourra ralentir, surtout en posant à chaque bon de commande des clauses et en étant très clair qu’on arrête tout si on dérive. Ce qui aurait l’avantage de ralentir pas mal, car ils devront retrouver d’autres personnes pour le faire.</p> | |||
<p><cite>Nicolas</cite><br> | |||
Si on fait juste du portage, on aura pas notre mot à dire sur le produit; est-ce que vous proposez qu’on lâche nos projets actuels pour nous consacrer à ça?</p> | |||
<p><cite>Kheops</cite><br> | |||
J’ai presque l’impression que le simple fait qu’on soit mis devant ce choix mérite déjà qu’on publie quelque chose à ce propos.</p> | |||
<p><cite>Thibaut</cite><br> | |||
L’application ne sera pas suffisante en elle-même pour juguler l’épidémie, ça serait trop beau. Mais elle peut être un outil efficace pour éviter des décès.<br> | |||
L’application ne pourra pas ne pas exister, donc donnons lui le meilleur cadre de développement possible.<br> | |||
Si elle devient obligatoire pour les possésseurs de smartphone, et que c’est finalement le consortium qui la développe, j’imagine qu’on aura des regrets.</p> | |||
</blockquote> | |||
<p>Après plein d’autres débats, de visios, nous avions fini par décider de participer en posant nos conditions. Voici l’email que nous nous préparions à envoyer.</p> | |||
<blockquote> | |||
<p>Nous exigeons de pouvoir communiquer publiquement (blog post sur notre site)sur ce projet dès la fin des débats parlementaires.</p> | |||
<p>Le blog post reprendra les lignes rouges suivantes, qui amènerait à ne pas reconduire le portage et a publier le refus de continuer : L’application et le serveur ne doivent servir qu’à lutter contre l’épidémie de coronavirus.</p> | |||
<p>On ne doit récolter que le minimum nécessaire de données. Aucun moyen de géolocalisation ne sera utilisé (par exemple GPS).</p> | |||
<p>Aucun identifiant ni identité ne sera associée à l’application.</p> | |||
<p>Les données sur le téléphone et sur le serveur ne seront conservées qu’une durée définie explicitement et argumentée (justifiée tant par l’état des connaissances médicales que par le besoin de respect de la vie privée).</p> | |||
<p>Les données utilisateurs ne seront transmises sur le serveur central qu’avec une action explicite et informée de l’utilisateur.</p> | |||
<p>Le code source intégral est publié sous une licence libre avant le déploiement et par la suite l’intégralité du processus de développement sera public.</p> | |||
<p>L’installation de l’application ne doit pas être discriminante et donc ne doit ni être un devoir ni conditionner l’accès à des droits (tel que le droit de se déplacer librement, ou donner l’exclusivité de l’accès aux tests du CoVid-19).</p> | |||
<p>L’appli ne doit pas embarquer de SDK d’analytics.</p> | |||
<p>Elle passera le crible d’exodus privacy sans problème.</p> | |||
</blockquote> | |||
<p>Ces discussions — comme toute discussion collective sur un sujet complexe — ont pris du temps. Cela n’a pas été facilité par la coordination avec le groupement, la DINUM et surtout l’évocation d’un accord de confidentialité. Au moment où nous allions envoyer cet email, nous apprenions que le projet était finalement confié au <a href="https://www.capgemini.com/fr-fr/actualites/communiques-de-presse/stopcovid/">consortium de l’angoisse</a> qui inclut Capgemini, Orange, Dassault Systèmes, Withing, d’autres structures privées et publiques, et, « dans l’écosystème », Atos, Accenture, Thalès ou encore Sopra Steria.</p> | |||
<p>Il n’y a pas vraiment de conclusion à tout ça. Nous avons été témoins, par le petit bout de la lorgnette, du tout début de cette histoire; nous avons imaginé un instant avoir l‘opportunité, ou le devoir, d’y faire quelque chose. Finalement, nous n’avons jamais vraiment donné notre avis. 🤷</p> |
@@ -162,6 +162,8 @@ | |||
<li><a href="/david/cache/2024/c3272392d462da90874d32841e5caac8/" title="Accès à l’article dans le cache local : Where have all the websites gone?">Where have all the websites gone?</a> (<a href="https://www.fromjason.xyz/p/notebook/where-have-all-the-websites-gone/" title="Accès à l’article original distant : Where have all the websites gone?">original</a>)</li> | |||
<li><a href="/david/cache/2024/6b2b8e2559a07b8d66dac842017b2619/" title="Accès à l’article dans le cache local : The Stack: Every Layout">The Stack: Every Layout</a> (<a href="https://every-layout.dev/layouts/stack/#the-component" title="Accès à l’article original distant : The Stack: Every Layout">original</a>)</li> | |||
<li><a href="/david/cache/2024/89dbef9daef24f311b6401cef62f5855/" title="Accès à l’article dans le cache local : Des Oloés">Des Oloés</a> (<a href="https://tw5.immateriel.fr/wiki/immateriel/b/YXGEDFB" title="Accès à l’article original distant : Des Oloés">original</a>)</li> | |||
<li><a href="/david/cache/2024/1f40a33f9c57a16d420eb0868a129e96/" title="Accès à l’article dans le cache local : Notes from “An approach to computing and sustainability inspired from permaculture” by Devine LuLinvega">Notes from “An approach to computing and sustainability inspired from permaculture” by Devine LuLinvega</a> (<a href="https://blog.jim-nielsen.com/2024/notes-from-computing-sustainably/" title="Accès à l’article original distant : Notes from “An approach to computing and sustainability inspired from permaculture” by Devine LuLinvega">original</a>)</li> | |||
@@ -172,6 +174,8 @@ | |||
<li><a href="/david/cache/2024/30b40ff8034212e070dc7daf2b9406e9/" title="Accès à l’article dans le cache local : an "archives first" approach to mailing lists">an "archives first" approach to mailing lists</a> (<a href="https://public-inbox.org/README.html" title="Accès à l’article original distant : an "archives first" approach to mailing lists">original</a>)</li> | |||
<li><a href="/david/cache/2024/ddc3ee3603be2702cef745c180b87776/" title="Accès à l’article dans le cache local : TousAntiCovid : vu depuis Codeureuses en Liberté">TousAntiCovid : vu depuis Codeureuses en Liberté</a> (<a href="https://www.codeursenliberte.fr/blog/tous_anti_covid/" title="Accès à l’article original distant : TousAntiCovid : vu depuis Codeureuses en Liberté">original</a>)</li> | |||
<li><a href="/david/cache/2024/87c468a4eddabe5d2c28e902d7f17504/" title="Accès à l’article dans le cache local : je ne sais pas pourquoi">je ne sais pas pourquoi</a> (<a href="https://www.la-grange.net/2024/01/11/pourquoi" title="Accès à l’article original distant : je ne sais pas pourquoi">original</a>)</li> | |||
<li><a href="/david/cache/2024/3ea27fca4fabb81676fc1b98264f3bd8/" title="Accès à l’article dans le cache local : It’s OK to call it Artificial Intelligence">It’s OK to call it Artificial Intelligence</a> (<a href="https://simonwillison.net/2024/Jan/7/call-it-ai/" title="Accès à l’article original distant : It’s OK to call it Artificial Intelligence">original</a>)</li> |