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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  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>Le petit flexbox illustré (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.vincent-valentin.name/articles/le-petit-flexbox-illustre">
  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. Le petit flexbox illustré (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.vincent-valentin.name/articles/le-petit-flexbox-illustre">Source originale du contenu</a></h3>
  445. <p><i lang="en">Flexbox</i> est un nouveau module d’affichage CSS qui apporte quelques possibilités graphiques jusqu’alors impossibles et qui permet aussi de grandement simplifier les constructions habituelles.</p>
  446. <p>Son principal frein reste le support limité à <abbr title="Internet Explorer">IE</abbr> 10+ (pas de souci pour la majorité des autres navigateurs), mais au regard des nouveautés offertes, il est d’ores et déjà intéressant d’en comprendre le fonctionnement et de résoudre certaines problématiques grâce à celui-ci.</p>
  447. <p><hr/>
  448. <p>Déclencher un affichage <i lang="en">flexbox</i> passe par la propriété <code>display</code>.</p>
  449. <p><i lang="en">Flexbox</i> diffère un peu des types d’affichages habituels car le changement va ici non seulement impacter l’élément sélectionné, mais également ses enfants <strong>directs</strong>.<br/>
  450. Ainsi on parlera de <i lang="en">flex-container</i> et de <i lang="en">flex-items</i> ; et il sera possible de passer des propriétés spécifiques à ces deux composants.</p>
  451. <p>Il sera tout à fait possible aussi qu’un élément soit à la fois un <i lang="en">flex-items</i> et un <i lang="en">flex-container</i> : autrement dit, les imbrications <i lang="en">flexbox</i> sont possibles.</p>
  452. <p>La courbe d’apprentissage du module peut paraître abrupte au premier abord. C’est sans compter les simplifications que permettent des outils comme <a href="https://github.com/postcss/autoprefixer"><i lang="en">autoprefixer</i></a>, qui viennent gommer les historiques de nommages et d’implémentations qui ont été faites.</p>
  453. <p>En effet <i lang="en">flexbox</i> en est toujours au stade du brouillon et a déjà subi trois refontes. On peut néanmoins penser qu’après un travail mené depuis plus de six ans, il soit maintenant suffisamment mature ; tout comme le statut actuel (<i lang="en">last call</i>) de la spécification et le nombre très faible de tickets encore ouverts le laisse entendre.</p>
  454. <p>Quoi qu’il en soit, au lieu de devoir écrire :</p>
  455. <pre><code>.foo
  456. {
  457. display: -webkit-box;
  458. display: -webkit-flex;
  459. display: -ms-flexbox;
  460. display: flex;
  461. }</code></pre>
  462. <p>il suffira simplement de passer par ce code pour que le post-processeur génère la même chose :</p>
  463. <pre><code>.foo
  464. {
  465. display: flex;
  466. }</code></pre>
  467. <p>On retrouve alors une courbe d’apprentissage relativement douce, où la principale difficulté reste le nombre de nouveautés. Nous allons donc passer en revue chacune d’elles méthodiquement, en commençant par les propriétés qui peuvent s’appliquer au <i lang="en">flex-container</i>.</p>
  468. <hr/>
  469. <p>Retenez cependant avant tout qu’un <i lang="en">flex-container</i> ou un <i lang="en">flex-item</i> appliquent un contexte de formatage de type <i lang="en">flex</i> équivalent au <a href="http://www.alsacreations.com/astuce/lire/1543-le-contexte-de-formatage-block-en-css.html">type <code>block</code></a>. (N’hésitez pas à lire maintenant ou plus tard l’article lié si ce concept ne vous semble pas clair.)</p>
  470. <h2>Propriétés sur le <i lang="en">flex-container</i></h2>
  471. <h3>La direction</h3>
  472. <p><strong><code>flex-direction</code></strong> permet de gérer la direction, par défaut en ligne (<code>row</code>) ; on pourra aussi la passer en colonne (<code>column</code>) très facilement.</p>
  473. <hr/>
  474. <p>La démonstration qui suit fait alterner différents affichages à chaque clic de votre part.<br/>
  475. (Il en sera de même sur la plupart des démonstrations de cette page.)</p>
  476. <hr/></p>
  477. <p>On pourra également inverser les flux et utiliser <code>row-reverse</code> et <code>column-reverse</code>.</p>
  478. <h3>Les débordements</h3>
  479. <p><strong><code>flex-wrap</code></strong> permet de gérer les débordements des <i lang="en">flex-items</i> dans les lignes ou dans les colonnes.<br/>
  480. Bien que par défaut ils ne soient pas autorisés (<code>nowrap</code>), il est tout à fait possible de changer ce comportement avec <code>wrap</code>.</p>
  481. <p>On pourra même inverser le flux et les débordements avec <code>wrap-reverse</code>.</p>
  482. <p>Notez que <code>flex-direction</code> et <code>flex-wrap</code> peuvent s’utiliser conjointement avec la propriété raccourcie <strong><code>flex-flow</code></strong>.</p>
  483. <p>Par exemple : </p>
  484. <pre><code>.bar
  485. {
  486. flex-direction: column;
  487. flex-wrap: wrap;
  488. }</code></pre>
  489. <p>sera équivalent à :</p>
  490. <pre><code>.bar
  491. {
  492. flex-flow: column wrap;
  493. }</code></pre>
  494. <h3>La justification sur l’axe principal</h3>
  495. <p><strong><code>justify-content</code></strong> aligne les <i lang="en">flex-items</i> le long de l’axe principal.</p>
  496. <p><hr/>
  497. <p>On parle d’axe principal et d’axe secondaire plutôt que d’axe vertical et horizontal car cela varie en fonction de la direction.</p>
  498. <hr/></p>
  499. <p>Par défaut les éléments sont empilés en début de flux (<code>flex-start</code>). Ils pourront l’être en fin de flux (<code>flex-end</code>), au milieu (<code>center</code>), espacés entre eux au maximum (<code>space-between</code>) ou espacés chacun d’eux par une marge identique (<code>space-around</code>).</p>
  500. <p><hr/>
  501. <p>Vous remarquerez quelques petites animations CSS qui permettent de mieux comprendre comment sont effectuées certaines répartitions d’espaces.</p>
  502. <hr/>
  503. <h3>La justification sur l’axe secondaire</h3>
  504. <p>Les enfants du <i lang="en">flex container</i> sont alignés :</p>
  505. <ul>
  506. <li>avec <code>align-items</code> au niveau de chaque ligne ;</li>
  507. <li>avec <code>align-content</code> au niveau de l’ensemble des lignes (il en faut donc plusieurs pour en constater l’effet).</li>
  508. </ul>
  509. <p><strong><code>align-items</code></strong> prend par défaut la valeur <code>stretch</code>, et accepte également <code>flex-start</code>, <code>flex-end</code>, <code>center</code> et <code>baseline</code>.</p></p>
  510. <p><strong><code>align-content</code></strong> prend par défaut la valeur <code>stretch</code>, et accepte également <code>flex-start</code>, <code>flex-end</code>, <code>center</code>, <code>space-between</code> et <code>space-around</code>.</p>
  511. <h2>Propriétés sur les <code>flex-items</code></h2>
  512. <p>Passons maintenant aux propriétés qui s’appliquent sur les enfants directs du <i>flex-container</i> et commençons par la plus riche : <code>flex</code>.</p>
  513. <p><hr/>
  514. <p>Ne confondez pas : nous avons vu plus haut ce mot-clef comme une nouvelle <em>valeur</em> de <code>display</code> ; il s’agit maintenant d’une nouvelle <em>propriété</em>.</p>
  515. <h3>Les dimensions</h3>
  516. <p><strong><code>flex</code></strong> est une propriété raccourcie qui combine <code>flex-grow</code>, <code>flex-shrink</code> et <code>flex-basis</code>.</p>
  517. <pre><code>.baz
  518. {
  519. flex: 0 1 auto;
  520. }</code></pre>
  521. <p>a donc pour équivalent :</p>
  522. <pre><code>.baz
  523. {
  524. flex-grow: 0;
  525. flex-shrink: 1;
  526. flex-basis: auto;
  527. }</code></pre>
  528. <ul>
  529. <li><code>flex-grow</code> définit les possibilités d’étirements d’un élément,</li>
  530. <li><code>flex-shrink</code> ses possibilités de contractions,</li>
  531. <li>et <code>flex-basis</code> sa dimension initiale.</li>
  532. </ul>
  533. <p>Par étirement et contraction, comprenez par là qu’un élément pourra voir sa taille surchargée afin de répondre au mieux à vos conditions et au contexte d’affichage courant.</p>
  534. <p><strong><code>flex-grow</code></strong> ne permet pas d’étirement quand il est à <code>0</code>, il faut passer un nombre positif plus ou moins important pour changer ce comportement par défaut.</p></p>
  535. <p><hr/>
  536. <p>Nous expliciterons un peu plus loin (avec <code>flex-basis</code>) la méthode de calcul qui définit les agrandissements. </p>
  537. <hr/>
  538. <p><strong><code>flex-shrink</code></strong> a pour valeur initiale 1 : la contraction est donc possible par défaut. On pourra lui passer un nombre nul ou un nombre positif pour annuler ou amplifier ce comportement.</p>
  539. <p>Plus un <code>flex-shrink</code> sera important, plus l’élément sera à même d’être compressé.</p></p>
  540. <p><strong>Comment sont calculées les compressions ?</strong></p>
  541. <p>Lorsque les facteurs de compression sont identiques, les proportions entre les éléments sont conservées.</p>
  542. <p>Dans le prochain exemple la taille du conteneur est revue (et animée) de manière à compresser les <i lang="en"> flex-items</i> dont les largeurs sont définies en pixels. </p>
  543. <p>On constate une largeur identique entre le premier <i lang="en"> flex-item</i> et les trois suivants quelle que soit la taille du <i lang="en">flex-container</i>.<br/>
  544. Et il en va de même pour les largeurs des trois derniers <i lang="en"> flex-items</i> qui restent identiques.</p>
  545. <p>Vous aurez peut-être noté que la largeur initiale des éléments intervient dans les calculs. Ainsi un élément deux fois plus large qu’un autre (et pourtant le même facteur de compression) se verra proportionnellement deux fois plus compressé si nécessaire.</p>
  546. <p>Quand les facteurs de compression sont différents, l’espace retiré lors de la compression est aussi proportionnel au facteur de compression.</p>
  547. <p>On constate ici que l’espace retiré du dernier <i lang="en"> flex-item</i> est trois fois plus grand que sur le second ; ainsi que deux fois plus grand que sur le troisième.<br/>
  548. Aucun espace n’est par contre retiré du premier.</p>
  549. <p>Ce sont donc les facteurs de compressions et les tailles initiales des éléments qui influent sur le taux de compression possible de chacun.</p>
  550. <p><strong><code>flex-basis</code></strong> est une propriété qui hérite par défaut (avec la valeur <code>auto</code>) de la largeur (<code>width</code>) ou de la hauteur (<code>height</code>) d’un élément, et ce en fonction de la direction définie sur le <i lang="en">flex-container</i>. </p>
  551. <p>Elle peut aussi prendre une valeur qui viendra surcharger cette dimension.</p>
  552. <p><code>flex-basis</code> va également redéfinir la taille minimale d’un élément (<code>min-width</code> ou <code>min-height</code>) et faire passer sa valeur par défaut de <code>0</code> à <code>auto</code>.</p>
  553. <p>On peut ainsi définir un <code>flex-basis</code> à <code>0</code>, tout en conservant visuellement une taille minimale pour l’élément.</p>
  554. <p><strong>Comment sont calculés les agrandissements ?</strong></p>
  555. <p>Ce qui est très intéressant avec <code>flex-basis</code>, c’est qu’il entre en jeu pour les calculs de dimensionnement : sa valeur va donc considérablement influencer les comportements d’agrandissement.</p>
  556. <ul>
  557. <li>Quand <code>flex-basis</code> est à <code>0</code>, c’est la taille des <i lang="en">flex-items</i> qui sera revue ;</li>
  558. <li>quand <code>flex-basis</code> est à <code>auto</code>, c’est l’espace restant qui sera revu.</li>
  559. </ul>
  560. <h3>La justification sur l’axe secondaire</h3>
  561. <p><code>align-items</code> (que nous avons vu plus haut) permet de justifier tous les éléments au sein d’un conteneur.</p>
  562. <p><strong><code>align-self</code></strong> permet de cibler individuellement ses enfants.</p>
  563. <p>Par défaut il est à <code>auto</code> et hérite du comportement du <i lang="en">flex-container</i> mais on retrouve les même valeurs possibles que pour <code>align-items</code>. À savoir : <code>flex-start</code>, <code>flex-end</code>, <code>center</code>, <code>baseline</code> et <code>stretch</code>.</p>
  564. <h3>L’ordonnancement</h3>
  565. <p><strong><code>order</code></strong> accepte uniquement des nombres entiers (négatifs ou positifs) et permet d’ordonner les éléments dans le flux. Il est fixé à <code>0</code> par défaut.</p>
  566. <p>Les ordres qui sont appliqués aux éléments sont alors classés par ordre croissant et c’est tout le flux d’affichage qui peut s’en retrouver modifié.</p>
  567. <p><hr/>
  568. <p>Outre cette compréhension basique des propriétés, il faudra bien sûr à l’avenir mieux appréhender l’utilisation de ce nouveau module. Agencements de propriétés, dégradations possibles, bugs…</p>
  569. <p>Par bien des aspects, je trouve que <i lang="en">flexbox</i> mélange les avantages des flottants et les avantages des tableaux. Nul doute : si vous êtes amenés à travailler dans des contextes responsifs, les possibilités offertes par <i lang="en">flexbox</i> vous intéresseront.</p>
  570. <hr/>
  571. <p>Voici pour compléter une liste de liens sur le sujet :</p></p>
  572. <ul>
  573. <li><a href="http://www.alsacreations.com/tuto/lire/1493-css3-flexbox-layout-module.html">article général en français</a> ;</li>
  574. <li><a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">article général en anglais</a> ;</li>
  575. <li><a href="http://la-cascade.ghost.io/tag/flexbox/">mises en applications commentées</a> ;</li>
  576. <li><a href="http://www.alsacreations.com/tuto/lire/1659-une-grille-responsive-avec-flexbox-et-LESS.html">une grille de mise en page</a> ;</li>
  577. <li><a href="http://tzi.github.io/chewing-grid.css/">une seconde grille de mise en page</a> ;</li>
  578. <li><a href="http://jackintheflexbox.tumblr.com/">des exemples pratiques</a> ;</li>
  579. <li><a href="http://philipwalton.github.io/solved-by-flexbox/">d’autres exemples</a> ;</li>
  580. <li><a href="https://github.com/philipwalton/flexbugs">une liste de bugs</a> ;</li>
  581. <li><a href="http://chriswrightdesign.com/experiments/flexbox-adventures/">un article qui s’attarde un peu plus sur les calculs d’agrandissements et de compressions</a> ;</li>
  582. <li><a href="http://caniuse.com/#search=flexbox">le support actuel</a> ;</li>
  583. <li><a href="http://www.w3.org/TR/css3-flexbox/">la spécification</a>.</li>
  584. </ul>
  585. <p>Bonnes lectures et bonnes expérimentations à tous.</p>
  586. </article>
  587. </section>
  588. <nav id="jumpto">
  589. <p>
  590. <a href="/david/blog/">Accueil du blog</a> |
  591. <a href="http://www.vincent-valentin.name/articles/le-petit-flexbox-illustre">Source originale</a> |
  592. <a href="/david/stream/2019/">Accueil du flux</a>
  593. </p>
  594. </nav>
  595. <footer>
  596. <div>
  597. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  598. <p>
  599. Bonjour/Hi!
  600. 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>
  601. 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>).
  602. </p>
  603. <p>
  604. 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>.
  605. </p>
  606. <p>
  607. Voici quelques articles choisis :
  608. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  609. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  610. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  611. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  612. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  613. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  614. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  615. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  616. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  617. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  618. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  619. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  620. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  621. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  622. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  623. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  624. </p>
  625. <p>
  626. 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>.
  627. </p>
  628. <p>
  629. Je ne traque pas ta navigation mais mon
  630. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  631. conserve des logs d’accès.
  632. </p>
  633. </div>
  634. </footer>
  635. <script type="text/javascript">
  636. ;(_ => {
  637. const jumper = document.getElementById('jumper')
  638. jumper.addEventListener('click', e => {
  639. e.preventDefault()
  640. const anchor = e.target.getAttribute('href')
  641. const targetEl = document.getElementById(anchor.substring(1))
  642. targetEl.scrollIntoView({behavior: 'smooth'})
  643. })
  644. })()
  645. </script>