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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  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>Living Style Guide Tools In-depth Overview (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="https://medium.com/@operatino/living-style-guide-tools-in-depth-overview-28cfffb92d05">
  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. Living Style Guide Tools In-depth Overview (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="https://medium.com/@operatino/living-style-guide-tools-in-depth-overview-28cfffb92d05">Source originale du contenu</a></h3>
  445. <h3 name="dfd5" id="dfd5" class="graf--h3">Intro</h3>
  446. <p name="f09c" id="f09c" class="graf--p">This overview is the outcome of a research on the current open source solutions followed by my personal feedback.</p>
  447. <p name="a528" id="a528" class="graf--p">Arranging the tools by functional aspects, I will highlight only the most powerful ones worth knowing. You can find more tools as well as videos, articles and other materials about Style Guides at <a href="http://styleguides.io/tools.html" data-href="http://styleguides.io/tools.html" class="markup--anchor markup--p-anchor" rel="nofollow">styleguide.io</a>.</p>
  448. <p name="a05d" id="a05d" class="graf--p">Before we start, if you are not yet familiar with Living Style Guides topic, I would suggest looking into these materials:</p>
  449. <blockquote name="ac4f" id="ac4f" class="graf--blockquote">In a nutshell, Living Style Guides are designed to aid building well-organized documentation of Front-end codebase. The “Living” part of it, means that documentation remains in constant sync with the actual code.</blockquote>
  450. <h3 name="bfc1" id="bfc1" class="graf--h3">CSS Documentation</h3>
  451. <p name="5fbc" id="5fbc" class="graf--p">The first players in the field are <em class="markup--em markup--p-em">CSS Documentation</em> parsing tools. The idea of combining description of components with styles source code first came from Web Designers. Combining creative approach and Design Style Guides success with web implementation practices has led to <a href="http://warpspire.com/kss/" data-href="http://warpspire.com/kss/" class="markup--anchor markup--p-anchor" rel="nofollow">KSS</a> development.</p>
  452. <p name="b804" id="b804" class="graf--p">As you most probably have heard about it, I will quickly recap on the main idea behind it. Similar with <a href="https://github.com/jsdoc3/jsdoc" data-href="https://github.com/jsdoc3/jsdoc" class="markup--anchor markup--p-anchor" rel="nofollow">JSDoc</a>, CSS component description is set right in the source code comments.</p>
  453. <pre name="eda8" id="eda8" class="graf--pre">// A button suitable for giving a star to someone.<br/>//<br/>// :hover - Subtle hover highlight.<br/>// .star-given - A highlight indicating.<br/>// .star-given:hover - Subtle hover highlight.<br/>// .disabled - Dims the button.<br/>//<br/>// Styleguide 2.1.3.</pre>
  454. <pre name="8edf" id="8edf" class="graf--pre">a.button.star{<br/> ...<br/> &amp;.star-given{<br/> ...<br/> }<br/> &amp;.disabled{<br/> ...<br/> }<br/>}</pre>
  455. <p name="6235" id="6235" class="graf--p">KSS allows to define component section number and different states description. Which is then parsed by special tools, generating a single-page documentation or a set of static HTML files with rendered examples and code snippets.</p>
  456. <figure name="b8e9" id="b8e9" class="graf--figure postField--insetLeftImage"><div class="aspectRatioPlaceholder is-locked"><p class="aspect-ratio-fill"/><img class="graf-image" data-image-id="1*VbgLdzU-OehiW7CEviDc0g.png" data-width="1183" data-height="1505" data-action="zoom" data-action-value="1*VbgLdzU-OehiW7CEviDc0g.png" src="https://d262ilb51hltx0.cloudfront.net/max/600/1*VbgLdzU-OehiW7CEviDc0g.png"/></div><figcaption class="imageCaption">KSS generated single page documentation.</figcaption></figure>
  457. <p name="8cf1" id="8cf1" class="graf--p">In similar CSS Doc parsing tools, it is also possible to define the HTML markup in comments, when KSS only parses the actual CSS selectors and generates simple markup automatically.</p>
  458. <p name="d37b" id="d37b" class="graf--p">Currently KSS is positioned as a documentation solution only, and the parsing tool is not getting new updates.</p>
  459. <p name="9780" id="9780" class="graf--p graf--empty"><br/></p>
  460. <p name="8293" id="8293" class="graf--p graf--empty"><br/></p>
  461. <h4 name="29c6" id="29c6" class="graf--h4">KSS alternatives</h4>
  462. <p name="c3d8" id="c3d8" class="graf--p">Since the original KSS, many similar tools have been presented to do exactly the same thing. One of the most successful implementations is <a href="http://styleguide.sc5.io/" data-href="http://styleguide.sc5.io/" class="markup--anchor markup--p-anchor" rel="nofollow">SC5 Style Guide</a>. In addition to encapsulated (using Shadow DOM) rendered component previews the tool also allows to edit SASS or LESS styles right in the browser. It is also possible to define Angular directives or Web components as a markup example in CSS comments, which will then be transformed into a fully operational component.</p>
  463. <p name="246b" id="246b" class="graf--p">Unfortunately, most of the CSS Documentation tools are somewhat copying each other, without introducing any new possibilities. That is the reason why it is not worth to describe each tool separately, so I will just list the ones you can find out there — StyleDocco, Kalei Styleguide (client-side only), Hologram and Styledown.</p>
  464. <p name="7527" id="7527" class="graf--p">Yet there is a tool with distinction. <a href="https://github.com/darcyclarke/DSS" data-href="https://github.com/darcyclarke/DSS" class="markup--anchor markup--p-anchor" rel="nofollow">DSS</a> is the only <em class="markup--em markup--p-em">standalone</em> CSS documentation parser, that produces JSON for later templating. Based on Node.js with support of all modern pre-processors. Comparing to KSS, it is possible to integrate DSS into any other tools and environments, as the original author also did with <a href="https://github.com/darcyclarke/grunt-dss" data-href="https://github.com/darcyclarke/grunt-dss" class="markup--anchor markup--p-anchor" rel="nofollow">Grunt plugin</a>.</p>
  465. <h3 name="0975" id="0975" class="graf--h3">Style Guide Platforms</h3>
  466. <p name="415e" id="415e" class="graf--p">The problem with CSS Documentation parsers is that they are very limited, nevertheless they are the easiest to implement. Trying to describe more complex components in CSS, you will end up with bloated and hard to manage styles, containing tons of copy-pasted HTML snippets all over the codebase.</p>
  467. <p name="2338" id="2338" class="graf--p">The more of duplicated templates and HTML markup you have, the less <em class="markup--em markup--p-em">Living</em> are your Style Guides. Without constant sync between codebase and the pattern library, you may face more problems than with having no documentation at all.</p>
  468. <p name="2b02" id="2b02" class="graf--p">Having big plans for maintaining own UI components library, it’s better to chose an alternative group of tools called <em class="markup--em markup--p-em">Style Guide Platforms</em>. Using both static-site generators and running dynamic environments, they provide more alternative and scalable solutions for collecting your documentation.</p>
  469. <h3 name="c916" id="c916" class="graf--h3">Static Style Guide Generators</h3>
  470. <p name="9e44" id="9e44" class="graf--p">Most basic example of static Front-end Style Guide generator is <a href="https://github.com/adactio/Pattern-Primer" data-href="https://github.com/adactio/Pattern-Primer" class="markup--anchor markup--p-anchor" rel="nofollow">Pattern Primer</a>. All it does is concatenating a list of HTML files into the one-page documentation, which you can enhance with a small text description and code examples.</p>
  471. <p name="eaff" id="eaff" class="graf--p">The reason I started with it is that all the other tools I will mention in this section are doing almost the same thing, but with separate additional perks on top.</p>
  472. <h4 name="6a07" id="6a07" class="graf--h4">Pattern Lab</h4>
  473. <p name="73a8" id="73a8" class="graf--p"><a href="http://patternlab.io/" data-href="http://patternlab.io/" class="markup--anchor markup--p-anchor" rel="nofollow">Pattern Lab</a> is another tool for concatenating a set of templates into a static website. But on top of that it is also providing a set of useful features like navigation, annotation support and smart templating.</p>
  474. <p name="58d0" id="58d0" class="graf--p">Every tool must have a workflow and Pattern Lab does it best, combining opinionated structure with <a href="http://bradfrost.com/blog/post/atomic-web-design/" data-href="http://bradfrost.com/blog/post/atomic-web-design/" class="markup--anchor markup--p-anchor" rel="nofollow">Atomic design</a> approach. This is an ideal combination for easy prototyping and passing HTML markup to client or back-end developers. Yet the opinion on technologies and file naming may interfere with existing codebase and special needs.</p>
  475. <figure name="1f3d" id="1f3d" class="graf--figure"><div class="aspectRatioPlaceholder is-locked"><p class="aspect-ratio-fill"/><img class="graf-image" data-image-id="1*Uqk5QrR5BmAByuiTf1rjiA.png" data-width="915" data-height="703" data-action="zoom" data-action-value="1*Uqk5QrR5BmAByuiTf1rjiA.png" src="https://d262ilb51hltx0.cloudfront.net/max/800/1*Uqk5QrR5BmAByuiTf1rjiA.png"/></div><figcaption class="imageCaption">Folder structure and Pattern Lab generated navigation.</figcaption></figure>
  476. <p name="f538" id="f538" class="graf--p">As an input to Pattern Lab static-site generator, user should prepare a <em class="markup--em markup--p-em">_patterns</em> catalog with folders for each component, following the naming convention. Each folder therefore contains a set of Mustache templates with HTML markup.</p>
  477. <figure name="3933" id="3933" class="graf--figure"><div class="aspectRatioPlaceholder is-locked"><p class="aspect-ratio-fill"/><img class="graf-image" data-image-id="1*Fg1jJNbzGJ2ULnspXTI_hg.png" data-width="606" data-height="161" src="https://d262ilb51hltx0.cloudfront.net/max/800/1*Fg1jJNbzGJ2ULnspXTI_hg.png"/></div></figure>
  478. <p name="1f76" id="1f76" class="graf--p">Data for templates is defined on a global level, or may be set locally next to the markup itself:</p>
  479. <pre name="070c" id="070c" class="graf--pre">pages/article.mustache<br/>pages/article.json</pre>
  480. <p name="40a1" id="40a1" class="graf--p">Then all is left is to link project styles into a generic page template and run the Pattern Lab builder. View the resulting <a href="http://demo.patternlab.io/" data-href="http://demo.patternlab.io/" class="markup--anchor markup--p-anchor" rel="nofollow">demo page</a> of generated pattern library.</p>
  481. <h4 name="e7a4" id="e7a4" class="graf--h4">Other generators</h4>
  482. <p name="ee0e" id="ee0e" class="graf--p">There are a few more tools, following same site-generator principles. <a href="http://fbrctr.github.io/fabricator" data-href="http://fbrctr.github.io/fabricator" class="markup--anchor markup--p-anchor" rel="nofollow">Fabricator</a> is gathering HTML and Markdown files, providing you better flexibility on structuring components documentation.</p>
  483. <figure name="8716" id="8716" class="graf--figure"><div class="aspectRatioPlaceholder is-locked"><p class="aspect-ratio-fill"/><img class="graf-image" data-image-id="1*orRqPigNylwy1bSJMJKPow.png" data-width="1143" data-height="788" data-action="zoom" data-action-value="1*orRqPigNylwy1bSJMJKPow.png" src="https://d262ilb51hltx0.cloudfront.net/max/800/1*orRqPigNylwy1bSJMJKPow.png"/></div><figcaption class="imageCaption">Fabricator compatible folder structure and produced page screenshot.</figcaption></figure>
  484. <p name="c382" id="c382" class="graf--p">As the Pattern Lab allows to define template data next to Mustache sources, with Fabricator it is possible to define Markdown file with text description next to the HTML source.</p>
  485. <p name="844f" id="844f" class="graf--p">Documentation processing is done by using Gulp build task, which also includes Live reload for ease of development. Here is an <a href="http://fbrctr.github.io/fabricator/toolkit/" data-href="http://fbrctr.github.io/fabricator/toolkit/" class="markup--anchor markup--p-anchor" rel="nofollow">example output</a> generated by Fabricator.</p>
  486. <h4 name="a699" id="a699" class="graf--h4">Living Style Guide Gem</h4>
  487. <p name="0d89" id="0d89" class="graf--p">Another tool worth mentioning is <a href="http://livingstyleguide.org/" data-href="http://livingstyleguide.org/" class="markup--anchor markup--p-anchor" rel="nofollow">Living Style Guide Gem</a>, based on SASS and Markdown.</p>
  488. <p name="fd37" id="fd37" class="graf--p">To define markup, you can choose between HTML and HAML. UI elements are described by using Markdown with custom syntax for imports and data definition.</p>
  489. <pre name="0363" id="0363" class="graf--pre">@haml<br/>@full-width<br/>***.concept-page***<br/> ***.concept-page--container***<br/> %h1***.concept-page--title*** Concept<br/> ***.concept-page--section***</pre>
  490. <p name="a16b" id="a16b" class="graf--p">Here is a <a href="https://github.com/eurucamp/livingstyleguide-eurucamp/tree/2015/source/stylesheets/components" data-href="https://github.com/eurucamp/livingstyleguide-eurucamp/tree/2015/source/stylesheets/components" class="markup--anchor markup--p-anchor" rel="nofollow">list of demo components</a> used as an input to Living Style Guide generator and the resulting <a href="http://livingstyleguide.com/eurucamp/" data-href="http://livingstyleguide.com/eurucamp/" class="markup--anchor markup--p-anchor" rel="nofollow">single page doc</a>.</p>
  491. <p name="8ea0" id="8ea0" class="graf--p">Since it follows quite opinionated technology stack, most benefits will be revealed only by utilizing Ruby ecosystem.</p>
  492. <h3 name="4caf" id="4caf" class="graf--h3">Dynamic Style Guide Platforms</h3>
  493. <p name="4767" id="4767" class="graf--p">To get even more flexibility and richer set of features you can choose <em class="markup--em markup--p-em">Dynamic Style Guide Platform</em>. The difference from all other tools mentioned above is the fact that it does not produce static website sources, but instead provides a full-featured web application.</p>
  494. <p name="bbba" id="bbba" class="graf--p">For the time being, there are only two good examples of dynamic Style Guide Platforms — <a href="https://github.com/lonelyplanet/rizzo" data-href="https://github.com/lonelyplanet/rizzo" class="markup--anchor markup--p-anchor" rel="nofollow">Rizzo</a> and <a href="http://sourcejs.com/" data-href="http://sourcejs.com/" class="markup--anchor markup--p-anchor" rel="nofollow">SourceJS</a>.</p>
  495. <blockquote name="0df8" id="0df8" class="graf--pullquote pullquote">Comparing to CSS focused tools, Style Guide Platforms are more engineer-driven, covering full development and integration process, not only the HTML markup and web design aspects.</blockquote>
  496. <h4 name="c28c" id="c28c" class="graf--h4">Rizzo</h4>
  497. <p name="b03e" id="b03e" class="graf--p">Rizzo is a small Ruby application, that pulls UI component assets via special API that master (main product) application provides. Instead of copying templates and markup into the Style Guide repository, component sources are pulled there automatically. It is currently the best way to develop truly <strong class="markup--strong markup--p-strong"><em class="markup--em markup--p-em">Living</em></strong> style guides, that are constantly in sync with the real codebase, thus providing more flexibility than CSS documentation parsers.</p>
  498. <p name="191f" id="191f" class="graf--p">Unfortunately Rizzo is highly opinionated and is not yet suited for easy re-use in other applications, but I definitely suggest you reading more about ideas behind it on Lonely Planet <a href="https://github.com/lonelyplanet/rizzo" data-href="https://github.com/lonelyplanet/rizzo" class="markup--anchor markup--p-anchor" rel="nofollow">engineering blog</a>.</p>
  499. <h4 name="dc9c" id="dc9c" class="graf--h4">SourceJS</h4>
  500. <p name="8929" id="8929" class="graf--p">Compared to Rizzo, <a href="http://sourcejs.com/" data-href="http://sourcejs.com/" class="markup--anchor markup--p-anchor" rel="nofollow">SourceJS</a> is a scalable open source solution. The dynamic app environment allows to configure any custom routing and on the fly API based documentation page generation. Giving more freedom for integration with your main application sources like it’s done in Rizzo.</p>
  501. <p name="0ccb" id="0ccb" class="graf--p">Out of the box, SourceJS allows to use Markdown files and special template pages for describing UI components. With official plugins, it is also possible to use <a href="https://github.com/sourcejs/sourcejs-contrib-dss" data-href="https://github.com/sourcejs/sourcejs-contrib-dss" class="markup--anchor markup--p-anchor" rel="nofollow">CSS Documentation</a> and <a href="https://github.com/sourcejs/sourcejs-jade" data-href="https://github.com/sourcejs/sourcejs-jade" class="markup--anchor markup--p-anchor" rel="nofollow">Jade</a> based templates. Chose preferred syntax or combine everything at once (see <a href="http://sourcejs.com/specs/" data-href="http://sourcejs.com/specs/" class="markup--anchor markup--p-anchor" rel="nofollow">examples</a>).</p>
  502. <figure name="cdb6" id="cdb6" class="graf--figure graf--iframe"><p class="iframeContainer"/><figcaption class="imageCaption">SourceJS introduction video.</figcaption></figure>
  503. <p name="f795" id="f795" class="graf--p">Core of the application is highly modular, containing only the most common features and API’s used for <a href="http://sourcejs.com/docs/api/plugins/" data-href="http://sourcejs.com/docs/api/plugins/" class="markup--anchor markup--p-anchor" rel="nofollow">developing custom plugins</a>. Platform is built with Node.js but does not provide any opinion on technologies you might want to integrate, like different templating languages and CSS pre-processors.</p>
  504. <h4 name="91d7" id="91d7" class="graf--h4">Components Oriented</h4>
  505. <p name="de3a" id="de3a" class="graf--p">SourceJS workflow is mostly focused on <em class="markup--em markup--p-em">component libraries</em> organization and is supporting Living Style Guide driven development rules. That helps to develop and test components right in the documentation pages.</p>
  506. <p name="b673" id="b673" class="graf--p">This approach allows to combine multiple sets of components in one environment, even for different web projects. Simply put the main application next to SourceJS app and link CSS styles, JS and templates into documentation pages.</p>
  507. <p name="9db1" id="9db1" class="graf--p">If project codebase is already focused on standalone UI components, link their folders to SourceJS spec catalog:</p>
  508. <pre name="28cf" id="28cf" class="graf--pre">sourcejs/specs/<br/> menu-component/<br/> menu.css<br/> menu.js<br/> menu.html<br/> readme.md<br/> [index.src]</pre>
  509. <p name="3b77" id="3b77" class="graf--p">Engine will parse the <em class="markup--em markup--p-em">readme.md</em> file or special <em class="markup--em markup--p-em">index.src</em> template with component representation examples and expose rich <a href="http://sourcejs.com/docs/spec/" data-href="http://sourcejs.com/docs/spec/" class="markup--anchor markup--p-anchor" rel="nofollow">documentation page</a>. Use this page to list all component states with different data, making it easier to test and share among team members.</p>
  510. <p name="ee80" id="ee80" class="graf--p">Request a <a href="mailto:r@rhr.me" data-href="mailto:r@rhr.me" class="markup--anchor markup--p-anchor">consultation session</a> with the authors of the SourceJS platform to see how it could be integrated with your codebase. Or use GitHub issues and <a href="http://gitter.im/sourcejs/Source" data-href="http://gitter.im/sourcejs/Source" class="markup--anchor markup--p-anchor" rel="nofollow">Gitter chat</a> for questions.</p>
  511. <h2 name="53b3" id="53b3" class="graf--h2">Starter Kits</h2>
  512. <p name="3528" id="3528" class="graf--p">Most common misunderstanding I see around Style Guide tool compilations is that Starter kits are mixed together with generators and parsers. Treat them only as HTML5 boilerplate for upcoming Style Guide:</p>
  513. <p name="ada4" id="ada4" class="graf--p">These starter templates could be used in any of mentioned tools, as a markup examples.</p>
  514. <h2 name="bfe5" id="bfe5" class="graf--h2">Summing up</h2>
  515. <p name="be9e" id="be9e" class="graf--p">If you find it hard to choose the right tool, let me help solving this question by summing up the main concerns.</p>
  516. <p name="bf50" id="bf50" class="graf--p">I won’t focus on technologies on which these tools are based, because in most cases it does not matter if a generator or dynamic server is running on Ruby or Node.js. The thing that <em class="markup--em markup--p-em">really matters</em> is the organizational structure, used templating engines and platform flexibility.</p>
  517. <h4 name="ef3f" id="ef3f" class="graf--h4">Starting from small</h4>
  518. <p name="c1b5" id="c1b5" class="graf--p">For simple CSS Frameworks and small web projects, that are not planned for long-time support, I would suggest using <a href="http://styleguide.sc5.io/" data-href="http://styleguide.sc5.io/" class="markup--anchor markup--p-anchor" rel="nofollow">SC5 Style Guide</a> or <a href="https://github.com/darcyclarke/DSS" data-href="https://github.com/darcyclarke/DSS" class="markup--anchor markup--p-anchor" rel="nofollow">DSS</a>. Both of them are really easy to set up and master.</p>
  519. <figure name="7914" id="7914" class="graf--figure"><div class="aspectRatioPlaceholder is-locked"><p class="aspect-ratio-fill"/><img class="graf-image" data-image-id="1*sY3tE8tmRlpcpd7ngV830A.png" data-width="923" data-height="460" data-action="zoom" data-action-value="1*sY3tE8tmRlpcpd7ngV830A.png" src="https://d262ilb51hltx0.cloudfront.net/max/800/1*sY3tE8tmRlpcpd7ngV830A.png"/></div><figcaption class="imageCaption">Simple CSS Components Library from Heroku.</figcaption></figure>
  520. <h4 name="8001" id="8001" class="graf--h4">For more complex component libraries</h4>
  521. <p name="009e" id="009e" class="graf--p">If you need to support components more complex than buttons and forms, containing many technologies like templates and JavaScript, the best choice will be the Style Guide Platforms. Comparing to CSS Documentation, Platforms allow following Style Guide Driven Development with all it’s benefits.</p>
  522. <p name="51fe" id="51fe" class="graf--p">This combination will help you maintain a really Living pattern libraries, keeping codebase well structured and easy to reuse.</p>
  523. <h4 name="bf34" id="bf34" class="graf--h4">Flexible solutions, for deep integration</h4>
  524. <p name="859c" id="859c" class="graf--p">The only efficient and long-lasting way of supporting Living Style Guides is having no code duplication at all. <a href="https://github.com/lonelyplanet/rizzo" data-href="https://github.com/lonelyplanet/rizzo" class="markup--anchor markup--p-anchor" rel="nofollow">Rizzo</a> and <a href="http://sourcejs.com/" data-href="http://sourcejs.com/" class="markup--anchor markup--p-anchor" rel="nofollow">SourceJS</a> approach allows to seamlessly integrate development workflow with the documentation process. Write code once and use it both in the product application and in the Style Guide with descriptions and different states representation.</p>
  525. <p name="3574" id="3574" class="graf--p">With SourceJS, it is possible to repeat almost all the workflows that other tools are offering, but with wider possibilities for custom integration and powerful plugins infrastructure.</p>
  526. <h4 name="1891" id="1891" class="graf--h4">The future of Style Guides</h4>
  527. <p name="75e1" id="75e1" class="graf--p">Since I am the main contributor to SourceJS, I will let myself mention few additional benefits of the engine, sharing our team’s vision about Style Guides future.</p>
  528. <blockquote name="a887" id="a887" class="graf--pullquote pullquote">We believe that Style Guides must serve as an entry point to any Front-end related workflows for the whole team. Therefore, Style Guides should be treated more seriously than just a regular documentation or a brand guideline.</blockquote>
  529. <p name="44cc" id="44cc" class="graf--p">Using plugins like <a href="http://github.com/sourcejs/sourcejs-comments" data-href="http://github.com/sourcejs/sourcejs-comments" class="markup--anchor markup--p-anchor" rel="nofollow">comments</a> or <a href="http://github.com/sourcejs/sourcejs-crowd-voice" data-href="http://github.com/sourcejs/sourcejs-crowd-voice" class="markup--anchor markup--p-anchor" rel="nofollow">crowd-voice</a>, teams are able to communicate between different departments within the Style Guide. Leaving their remarks and feedback in the place where components are developed, tested and maintained.</p>
  530. <figure name="4667" id="4667" class="graf--figure"><div class="aspectRatioPlaceholder is-locked"><p class="aspect-ratio-fill"/><img class="graf-image" data-image-id="1*cJKUjG6OrJCl-9Y_Aouxdg.png" data-width="628" data-height="344" src="https://d262ilb51hltx0.cloudfront.net/max/800/1*cJKUjG6OrJCl-9Y_Aouxdg.png"/></div><figcaption class="imageCaption">SourceJS plugin for commenting the rendered UI examples.</figcaption></figure>
  531. <p name="700b" id="700b" class="graf--p">Apart from in-place communication, we can combine different development tools in one place. Run live reload, linting and testing tools with a single command all together withing the Style Guide Platform. Integrate performance metrics results and provide optimization suggestions right on the documentation page. The possibilities are endless.</p>
  532. <p name="0be7" id="0be7" class="graf--p">We are working on getting more different interactive documentation and various front-end infrastructure dashboards in one place, making an ultimate tool for the web developers.</p>
  533. <p name="9776" id="9776" class="graf--p">If you also believe in the future of Style Guides and are willing to support this movement, we will be happy to see you in SourceJS community.</p>
  534. <h3 name="a075" id="a075" class="graf--h3">Further Research</h3>
  535. <p name="13b3" id="13b3" class="graf--p graf--empty"><br/></p>
  536. <ul class="postList"><li name="4a64" id="4a64" class="graf--li"><a href="http://www.elementcss.com" data-href="http://www.elementcss.com" class="markup--anchor markup--li-anchor" rel="nofollow">Element CSS</a> — interesting approach of hosted service with on the fly Style Guide creation</li><li name="4501" id="4501" class="graf--li"><a href="http://patternry.com/" data-href="http://patternry.com/" class="markup--anchor markup--li-anchor" rel="nofollow">Patternry</a> — a service for storing and organizing Front-end Style Guides online</li><li name="ade6" id="ade6" class="graf--li"><a href="http://styleguides.io" data-href="http://styleguides.io" class="markup--anchor markup--li-anchor" rel="nofollow">styleguides.io</a> — a collection of tools, articles and other materials on the Style Guides</li><li name="6786" id="6786" class="graf--li"><a href="https://github.com/davidhund/styleguide-generators" data-href="https://github.com/davidhund/styleguide-generators" class="markup--anchor markup--li-anchor" rel="nofollow">An overview of Pattern Library Generators</a></li></ul>
  537. <p name="54c5" id="54c5" class="graf--p">And here is the video of my latest talk on the corresponding topic:</p>
  538. <figure name="544d" id="544d" class="graf--figure graf--iframe graf--last"><p class="iframeContainer"/><figcaption class="imageCaption">Maintaining Own Components Library with Living Style Guides.</figcaption></figure>
  539. </article>
  540. </section>
  541. <nav id="jumpto">
  542. <p>
  543. <a href="/david/blog/">Accueil du blog</a> |
  544. <a href="https://medium.com/@operatino/living-style-guide-tools-in-depth-overview-28cfffb92d05">Source originale</a> |
  545. <a href="/david/stream/2019/">Accueil du flux</a>
  546. </p>
  547. </nav>
  548. <footer>
  549. <div>
  550. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  551. <p>
  552. Bonjour/Hi!
  553. 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>
  554. 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>).
  555. </p>
  556. <p>
  557. 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>.
  558. </p>
  559. <p>
  560. Voici quelques articles choisis :
  561. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  562. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  563. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  564. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  565. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  566. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  567. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  568. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  569. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  570. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  571. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  572. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  573. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  574. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  575. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  576. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  577. </p>
  578. <p>
  579. 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>.
  580. </p>
  581. <p>
  582. Je ne traque pas ta navigation mais mon
  583. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  584. conserve des logs d’accès.
  585. </p>
  586. </div>
  587. </footer>
  588. <script type="text/javascript">
  589. ;(_ => {
  590. const jumper = document.getElementById('jumper')
  591. jumper.addEventListener('click', e => {
  592. e.preventDefault()
  593. const anchor = e.target.getAttribute('href')
  594. const targetEl = document.getElementById(anchor.substring(1))
  595. targetEl.scrollIntoView({behavior: 'smooth'})
  596. })
  597. })()
  598. </script>