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

index.html 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=fr>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Using Quantity Queries to write content-aware CSS (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="http://www.tomango.co.uk/thinks/using-quantity-queries-to-write-content-aware-css/">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. Using Quantity Queries to write content-aware CSS (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="http://www.tomango.co.uk/thinks/using-quantity-queries-to-write-content-aware-css/">Source originale du contenu</a></h3>
  445. <p>The dawn of <abbr title="HyperText Markup Language">HTML5</abbr> and <abbr title="Cascading Style Sheets">CSS3</abbr> provided a wave of new technologies promising to change the way we build web applications. Web developer reactions to most features were similar, an initial buzz of excitement while we pondered the possibilities brought forth by these shiny new techniques followed by a crushing sense of disappointment when we realised just how long it would be before we could start using them.</p>
  446. <p>Some crest-of-the-wave developers renounced any form of support to older browsers and pressed on with the new features. However, many developers did not have the option to blindly assume that all users ran the latest cutting edge browser, if we were to do that, we’d segregate a significant portion of our users. For this reason, it’s usually a game of patience when it comes to using new frontend features in the wild.</p>
  447. <p>This is why it’s so exciting to discover a feature that is both very useful and can also be used on a live website without large spoonfuls of graceful degradation.</p>
  448. <h2>Enter Quantity Queries</h2>
  449. <p>During the brilliant <a href="http://responsiveconf.com/2015/">Responsive Day Out 2015</a>, there was a stand-out talk that brought to light a concept that opened many possibilities for modular, content-aware design. In his talk on ‘<a href="http://www.fivesimplesteps.com/products/solving-problems-with-selectors">Solving problems with selectors</a>‘, <a href="http://heydonworks.com/">Heydon Pickering</a> demonstrated Quantity Queries.</p>
  450. <p>Quantity Queries are a way of reacting to differing levels of content with pure vanilla, <a href="http://caniuse.com/#search=nth-last-child">well supported</a> <abbr title="Cascading Style Sheets">CSS</abbr>. They are comprised of the following:</p>
  451. <ol>
  452. <li>A shift in the way you think about <abbr title="Cascading Style Sheets">CSS</abbr> selectors</li>
  453. <li>The <code class="language-css">:nth-last-child</code> selector</li>
  454. <li>The <code class="language-css">:first-child</code> selector</li>
  455. <li>The <code class="language-css">~ *</code> selector</li>
  456. </ol>
  457. <h3>Questioning selectors</h3>
  458. <p>To get the most out of Quantity Queries, you have to view the <abbr title="Cascading Style Sheets">CSS</abbr> selector as an <var>IF</var> statement that will ask a question of the markup and only run if all conditions are met. This more logical view of the selector helps with your decision-making when it comes to laying out specific elements.</p>
  459. <h3>The :nth-last-child selector</h3>
  460. <p>The <code class="language-css">:nth-last-child</code> selector was added in <abbr title="Cascading Style Sheets">CSS3</abbr> but it hasn’t had a great deal of publicity in comparison to its cool-kid siblings <code class="language-css">nth-child</code> and <code class="language-css">:first-of-type</code>. Their benefits are immediately obvious, hence the amount of air-time they received. <code class="language-css">:nth-last-child</code> has a more subtle set of benefits that have taken longer to discover.</p>
  461. <p>This selector will select the element(s) that meet the criteria passed into the brackets of the selector, working from the bottom of the element stack and counting up.</p>
  462. <p>In its simplest form, a single number can be passed into the brackets to ask the question, <em>‘Is this element the nth-last element that I’m working on?’</em>. The <code class="language-css">:nth-last-child(2)</code> selector will select the penultimate element, the <code class="language-css">:nth-last-child(4)</code> selector will select the fourth-last element. Although this is handy, it’s not going to be useful on every project. That is, until it is teamed with a number of other selectors.</p>
  463. <h3>The :first-child selector</h3>
  464. <p>We all know and love the <code class="language-css">:first-child</code> selector. It’s great for making our opening paragraphs a little larger or hiding borders for the first element in a list. However, this quaint selector becomes a pretty powerful anchor when combined with <code class="language-css">:nth-last-child</code>. Remember, our selectors are <var>IF</var> statements and by using <code class="language-css">:first-child</code> as the first selector (imagine this as the first parameter in an <var>IF</var> statement), we’re able to filter out all elements that are not the first element.</p>
  465. <p>Now our humble <code class="language-css">:nth-last-child(4)</code> selector can be combined to create <code class="language-css">:first-child:nth-last-child(4)</code> to create a much more specific selector asking the question <em>‘Is this element the first-child and the fourth-last element that I’m working on?’</em>. This is getting pretty close to something that could be very useful but it needs one final ingredient to take it to the next level.</p>
  466. <h3>The ~ * selector</h3>
  467. <p>This rather bizarre selector uses two less common elements in <abbr title="Cascading Style Sheets">CSS</abbr>: the general sibling combinator and the universal selector. It asks the question <em>‘Does this element come after the current selected element’</em>, effectively selecting all elements after the current element without traversing up an element level, something not currently possible in <abbr title="Cascading Style Sheets">CSS</abbr> – very cool! Combined with the previous code, we can write the following:</p>
  468. <pre><code> &lt;div class="code-embed"&gt;
  469. &lt;pre class="language-css"&gt;&lt;code&gt;:first-child:nth-last-child(4),
  470. </code></pre>
  471. <p>:first-child:nth-last-child(4) ~ * {
  472. /<em> Styles here </em>/
  473. }</code></pre>
  474. </div>
  475. <p>This asks the question <em>'Is this element the first-child and the fourth-last element that I'm working on OR does this element come after the first-child and the fourth-last element that I'm working on?'.</em></p>
  476. <p>We have a <abbr title="Cascading Style Sheets">CSS</abbr> selector that can check if a container holds exactly 4 elements!</p>
  477. <blockquote><p>In essence, we have created a content-aware stylesheet rule. That's pretty neat for a simple declarative language like CSS.</p></blockquote>
  478. <h4>Added bonus</h4>
  479. <p>As the <code class="language-css">:nth-last-child</code> selector works in a similar way to the famous <code class="language-css">:nth-child</code> selector, you can pass more than just a single number into the selector. For example, if you pass in n+5, you are able to test whether the container holds five or more elements and style all of the elements accordingly!</p>
  480. <h2>Why use Quantity Queries?</h2>
  481. <p>The reason I got so excited about this concept was because I could immediately see how useful it could be on the websites we develop. Being able to count the number elements in a container used to be a privilege only extended to JavaScript and server-side languages. The former meant waiting till the page had finished loading before counting the elements and the latter only worked on page load and wouldn't react to client-side changes. Using <abbr title="Cascading Style Sheets">CSS</abbr> to count solves both of these issues; <strong>it is both dynamic and instantaneous</strong>.</p>
  482. <p>In a world of Content Management Systems, the challenge to web developers is to ensure that content looks great on every device, regardless of the type and quantity of content that's been provided. Quantity Queries help towards this reactive goal by helping you to tidy up the page if too much or too little content has been added to a container.</p>
  483. <h2>Putting Quantity Queries to work</h2>
  484. <h3>Tag list</h3>
  485. <p>I used Quantity Queries on a recent build to change the way that tags would display depending on the total number. This subtle enhancement only kicked in if there was five or more tags and it neatened up what would've been a long list. Using the following simple Quantity Query, I was able to swap from a list to a brickwork-like structure with ease:</p></p>
  486. <pre><code> &lt;div class="code-embed"&gt;
  487. &lt;pre class="language-css"&gt;&lt;code&gt;.tag {
  488. display: block;
  489. </code></pre>
  490. <p>}</p>
  491. <p>.tag:first-child:nth-last-child(n+5),
  492. .tag:first-child:nth-last-child(n+5) ~ * {
  493. display: inline-block;
  494. }</code></pre>
  495. </div>
  496. <div id="attachment_3370" class="wp-caption alignnone"><img class="size-full wp-image-3370" src="http://www.tomango.co.uk/wp-content/uploads/2015/08/query.gif" alt="The finished result" width="845" height="678"/><p class="wp-caption-text">The finished result</p></div>
  497. <h3>The Grid System</h3>
  498. <p>I put Quantity Queries to use on a template that required a flexible grid system to display a list of projects and news items. My aim to was to ensure that no orphaned elements would be left at the end of the list, regardless of how many items were in the system. Using a more complex set of selectors, I was able to create an effective grid system.</p></p>
  499. <pre><code> &lt;div class="code-embed"&gt;
  500. &lt;pre class="language-css"&gt;&lt;code&gt;.panel:nth-child(3n),
  501. </code></pre>
  502. <p>.panel:nth-child(3n+1):last-child,
  503. .panel:nth-child(6n+1):nth-last-child(4),
  504. .panel:nth-child(6n+1):nth-last-child(4) ~ .panel,
  505. .panel:nth-child(6n+4):nth-last-child(4),
  506. .panel:nth-child(6n+4):nth-last-child(4) ~ .panel {
  507. width: 25%;
  508. }</p>
  509. <p>.panel:nth-child(6n+1),
  510. .panel:nth-child(6n+6),
  511. .panel:nth-child(6n+2):last-child,
  512. .panel:nth-child(6n+4):nth-last-child(2),
  513. .panel:nth-child(6n+4):nth-last-child(2) ~ .panel {
  514. width: 50%;
  515. }</code></pre>
  516. </div>
  517. <p><img class="alignnone size-full wp-image-3368" src="http://www.tomango.co.uk/wp-content/uploads/2015/08/grid.gif" alt="grid" width="1271" height="875"/></p>
  518. <h2>In closing</h2>
  519. <p>Working with Quantity Queries is a lot of fun. They give new possibilities for modular element design and they do a brilliant job of tidying up content extremes making your projects more flexible and future-proof.</p></p>
  520. </article>
  521. </section>
  522. <nav id="jumpto">
  523. <p>
  524. <a href="/david/blog/">Accueil du blog</a> |
  525. <a href="http://www.tomango.co.uk/thinks/using-quantity-queries-to-write-content-aware-css/">Source originale</a> |
  526. <a href="/david/stream/2019/">Accueil du flux</a>
  527. </p>
  528. </nav>
  529. <footer>
  530. <div>
  531. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  532. <p>
  533. Bonjour/Hi!
  534. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  535. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  536. </p>
  537. <p>
  538. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  539. </p>
  540. <p>
  541. Voici quelques articles choisis :
  542. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  543. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  544. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  545. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  546. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  547. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  548. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  549. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  550. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  551. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  552. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  553. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  554. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  555. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  556. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  557. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  558. </p>
  559. <p>
  560. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  561. </p>
  562. <p>
  563. Je ne traque pas ta navigation mais mon
  564. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  565. conserve des logs d’accès.
  566. </p>
  567. </div>
  568. </footer>
  569. <script type="text/javascript">
  570. ;(_ => {
  571. const jumper = document.getElementById('jumper')
  572. jumper.addEventListener('click', e => {
  573. e.preventDefault()
  574. const anchor = e.target.getAttribute('href')
  575. const targetEl = document.getElementById(anchor.substring(1))
  576. targetEl.scrollIntoView({behavior: 'smooth'})
  577. })
  578. })()
  579. </script>