Lym­nee Css

Il vous est impossible d’accéder au contenu : soit JavaScript est désactivé dans votre navigateur, soit votre navigateur est obsolescent.

You cannot access the content: either JavaScript is disabled in your browser or your browser is outdated.

Lym­nee Css

Attributs de données avec style.

Classies data-attributes.

view_compact_alt

lire le résumé lire l’original

read the summary text read the full text

view content in English

voir le contenu en Français

translate

En ré­su­mé…

In sum­mary…

<de­tails>
<sum­mary>

Author’s note. As I am a French speaker, the translation can be improved!

Les attributs de données constituent une alternative aux classes Css pour mettre en forme une page Web.

Data attributes are an alternative to Css classes for formatting a web page.

Les attributs de données sont flexibles : leur valeur peut contenir n’importe quel caractère ! Aussi est-il loisible de suivre la grammaire Css pour déclarer un couple sélecteur - valeur. Par exemple…

Data attributes are flexible: their value can contain any character! So it is possible to follow the Css grammar to declare a couple selector - value. For example…

<html data-ym-font-size="medium"></html>

… ou…

… or…

<html 
data-ym-font-size="medium"
></html>

… où data-ym-font-size représente un espace de nom suivi du sélecteur.

… where data-ym-font-size represents a namespace followed by the selector.

Les relations Html - Css deviennent plus faciles à concevoir et à maintenir.

Html - Css relationships become easier to design and maintain.

Certes, l’outil de validation Css Lint émet des avertissements libellés avec le titre Disallow unqualified attribute selectors et la description Unqualified attribute selectors are known to be slow quand lui sont soumis des attributs de données.

Certainly, validation tool Css Lint issues warnings when data attributes are submitted to it : Disallow unqualified attribute selectors and Unqualified attribute selectors are known to be slow.

Cependant, en dépit d’une légende tenace, les attributs de données ne sont pas plus lents à interpréter que les classes Css… L’article How performant are data attributes as selectors propose un test, disponible dans le fichier lymnee.benchmark.html, afin de comparer les performances des deux sélecteurs grâce à 10 000 itérations.

However, despite a persistent legend, data attributes are not slower to interpret than Css… The article How performant are data attributes as selectors proposes a test, which is available in lymnee.benchmark.html: it compares the performances of the two selectors thanks to 10 000 iterations.

Cette proposition de syntaxe, baptisée Lymnee, est simple, mais pas simpliste : pseudo-classes, pseudo-elements, Media queries, règles @supports et sélecteurs contextuels sont pris en charge.

This syntax proposal, called Lymnee, is simple, but not simplistic: pseudo-classes, pseudo-elements, Media queries, @supports rules and contextual selectors are supported.

Lymnee s’accompagne de deux outils pour générer le code Css : un paquet Node.js, un script Php. Deux autres outils sont disponibles en JavaScript : un fichier de visualisation, d’une part, et, d’autre part, un fichier de production, servie également par un Cdn ; est écrite à la volée la feuille de style.

Lymnee dispose d’une librairie écrite en JavaScript qui génère la feuille de style à la volée : le fichier peut être servi par un Cdn.

Lymnee includes two tools to generate the code Css : a Node.js package, a Php script. Two other tools are available in JavaScript: a visualization file, on the one hand, and, on the other hand, a production file, also served by a Cdn; the stylesheet is written on the fly.

Lymnee has a library written in JavaScript which generates the style sheet on the fly : the file can be served by a Cdn.

</sum­mary>

Pro­lé­go­mè­nes

Back­ground

Écrivons trois lignes de Html et trois classes Css

Let’s write three lines of Html et three classes Css

<h1 class="foo">Title</h1>
<h2 class="else">Title</h2>
<p class="bar">Paragraph</p>
.foo {
    color: red;
    font-size: large
}
.else {
    color: blue;
    font-size: large
}
.bar {
    color: blue;
    font-size: medium
}

Émergent trois difficultés…

Three difficulties emerge…

  1. Comment nommer les classes ? En utilisant la sémantique grâce à un incommensurable effort d’imagination (songer aux esprits curieux qui, en ligne, ausculteront notre savoir-faire !) ? En recourant à un nom générique et réutilisable ?
  2. Comment ordonner les classes ? En les triant par ordre alphabétique au prix d’un travail fastidieux ? À défaut de tri, comment retrouver l’information dans plusieurs centaines, voire milliers de classes ? [Selon CSS Stats, Facebook utilise 1025 règles, le 19 septembre 2023.]
  3. Comment appliquer le principe Dry, c’est-à-dire factoriser le code afin d’obvier à la redondance ?
  1. How to name the classes? By using semantics thanks to an immeasurable effort of imagination (think of the inquisitive minds that, online, will examine our know-how!)? By using a generic and reusable name?
  2. How to order the classes? By sorting them in alphabetical order at the cost of a tedious job? Without sorting, how can you find information in several hundred or even thousands of classes? [According to CSS Stats, Facebook uses 1025 rules on September 19, 2023.]
  3. How to apply the Dry, i.e. factoring the code to avoid redundancy?

Avec un tri et un code factorisé (manuellement !), nos trois classes s’établissent ainsi…

With a sorting and a factorized code (manually!), our three classes are established as follows…

.bar { 
    font-size: medium
}
.bar,
.else {
    color: blue
}
.else,
.foo {
    font-size: large
}
.foo {
    color: red
}

ou…

or…

.bar,
.else {
    color: blue
}
.foo {
    color: red
}
.bar { 
    font-size: medium
}
.else,
.foo {
    font-size: large
}

Avec Lymnee, nous écrivons…

With Lymnee, we write…

<h1 data-ym-color="red" data-ym-font-size="large">Title</h1>
<h2 data-ym-color="blue" data-ym-font-size="large">Title</h2>
<p data-ym-color="blue" data-ym-font-size="medium">Paragraph</p>

Nous obtenons…

We get…

[data-ym-color="red"] {
    color: red
}
[data-ym-font-size="large"] {
    font-size: large
}
[data-ym-color="blue"] {
    color: blue
}
[data-ym-font-size="medium"] {
    font-size: medium
}

Un codage classique nécessite six sélecteurs et quatre règles. Lymnee utilise quatre sélecteurs et quatre règles.

A classic coding requires six selectors and four rules. Lymnee uses four selectors and four rules.

Le code Html, valide ! est verbeux (lu communément par un logiciel…), mais la solution Lymnee présente plusieurs avantages…

The Html code is valid and verbose (read by a software…), but Lymnee has several advantages…

État des lieux

State of the art

Depuis des temps immémoriaux (!), les auteurs.autrices sont en quête de la structure idéale pour organiser le code Css.

Since the beginning of time (!), authors have been looking for the ideal structure to organize the Css code.

Les méthodes comme Object-Oriented CSS, BEM — Block Element Modifier, Atomic Design ajoutent une couche d’abstraction. Comment reconnaître un premier et un deuxième objet, un bloc et un élement, un organisme et un modèle ?… Collective et individuelle sont les variabilités… Le travail collaboratif, dans l’espace ou dans le temps, devient chaotique. Un.e auteur.autrice (le substantif développeur.se constitue un abus de langage, car Css comme Html n’utilisent pas la programmation) interprète différemment les règles au fil du temps, voire oublie le raisonnement qui l’a conduit à préférer une molécule à un atome.

Methods like Object-Oriented CSS, BEM — Block Element Modifier, Atomic Design add a layer of abstraction. How to recognize a first and a second object, a block and an element, an organism and a template?… Collective and individual are the variabilities… Collaborative work, in space or in time, becomes chaotic. An author interprets the rules differently over time, and even forgets the reasoning that led him to prefer a molecule to an atom.

Les préprocesseurs, comme Less, visent notamment à rationaliser le code Css. Le contenu est souvent divisé en fragments gigognes qui suivent une logique aléatoire. La recherche d’une règle impose de parcourir plusieurs fichiers. Comme la plupart des navigateurs interprète maintenant les variables Css [Can I use # CSS Variables (Custom Properties)] et utilise la fonction (hélas limitée aux opérations arithmétiques traditionnelles !) Calc() [Can I use calc() as CSS unit value], l’intérêt des préprocesseurs est moindre.

Preprocessors, such as Sass or Less, aim in particular to streamline Css code. The content is often divided into fragments that follow a random logic. Searching for a rule requires browsing several files. As most browsers now interpret Can I use # CSS Variables (Custom Properties) [Can I use # CSS Variables (Custom Properties)] and use the function (alas limited to traditional arithmetic operations!) Calc() [Can I use calc() as CSS unit value], the interest of preprocessors is less.

D’At­tributes Mod­ules for CSS

From At­tributes Mod­ules for CSS…

En 2014, Glen Maddern et Ben Schwarz commettent l’article Attributes Modules for CSS. Ils y proposent une syntaxe comme…

In 2014, Glen Maddern and Ben Schwarz wrote the article Attributes Modules for CSS. In it, they propose a syntax as…

<a am-Button="primary large">Large primary button</a>
<a am-Button></a>
<a am-Button="info small"></a>
<a am-Button="danger extra-small"></a>

(L’exemple est repris de la documentation.)

(The example is taken from the documentation.)

Il s’agit d’un usage des attributs de données, qui est aussi préconisé par Object-Oriented CSS.

This is a use of data attributes, which is also advocated by Object-Oriented CSS.

… Via Atomic CSS

… Via Atomic CSS

Atomic CSS, conçu par Thierry Koblentz, style directement les composants. Cette méthodologie évite de concevoir des classes difficiles à maintenir. Ainsi, le code Html

Atomic CSS, designed by Thierry Koblentz, styles components directly. This methodology avoids designing classes that are difficult to maintain. Thus, the Html code…

<div class="D(b) Va(t) Fz(20px)">Hello World!</div>

… est traduit comme suit en Css

… is translated into Css as follows…

.D(b) {
    display: block
}
.Va(t) {
    vertical-align: top
}
.Fz(20px) {
    font-size: 20px
}

(L’exemple est repris de la documentation.)

(The example is taken from the documentation.)

Cette méthode est captivante ! Atomic CSS n’utilise pas les styles en ligne. Le code Css est mis en cache et factorisé. La syntaxe alourdit le poids d’un fichier Html, mais la compression est performante.

This method is captivating! Atomic CSS does not use inline styles. The Css code is cached and factored. The syntax increases the weight of an Html file, but the compression is efficient.

Cependant, Atomic CSS présente deux écueils…

However, Atomic CSS has two pitfalls…

  1. Les classes sont difficiles à mémoriser et à relire. Elles s’appuient sur la syntaxe Emmet, dont les abréviations ne sont pas intuitives. Emmet n’est pas maintenu à jour : ainsi, comment recourir à Css Grid Layout ?
  2. L’échappement des caractères spéciaux est pénible !

    Par exemple, en utilisant les Media queries, le code Html

    <div class="bdrs@large"></div>
    

    … est traduit comme suit en Css

    @media only screen and (min-width: 768px) {
        .bdrs\@large {
            border-radius: .5rem
        }
    }
    

    JavaScript échappe les caractères spéciaux avec la méthode CSS.escape().

  1. The classes are difficult to memorize and to read back. They are based on Emmet syntax, whose abbreviations are not intuitive. Emmet is not kept up to date: so how to use Css Grid Layout>?
  2. Escaping special characters is a pain!

    For example, using Media queries, Html code…

    <div class="bdrs@large"></div>
    

    … is translated as follows in Css

    @media only screen and (min-width: 768px) {
        .bdrs\@large {
            border-radius: .5rem
        }
    }
    

    JavaScript escapes special characters with the CSS.escape() method.

Autrement dit, les concepts d’Atomic CSS méritent quelque intérêt, mais sont difficiles à appréhender au quotidien.

In other words, the concepts of Atomic CSS are interesting, but difficult to use in everyday life.

… À Lym­nee

… To Lym­nee

Or, la philosophie d’Atomic CSS est applicable aux attributs de données : les codes Html et Css deviennent simples à écrire et à lire ! Par un humain. Par un logiciel.

Atomic CSS philosophy is applicable to data attributes: Html and Css codes become easy to write and read! By a human. By a software.

Les valeurs des attributs de données peuvent contenir n’importe quel caractère : (…) attributes on HTML elements may have any string value, including the empty string. (…).

Data attributes values can contain any character: (…) attributes on HTML elements may have any string value, including the empty string. (…).

At­tri­buts de données

Data at­tributes

Les attributs de données permettent d’ajouter des informations à un élément Html.

Data attributes are used to add information to an Html element.

Par exemple, pour stocker le nombre d’habitants d’une ville sans recourir à une base de données, peut être écrit… <p id="paris" data-population="2148271">Paris</p>. L’information est facile à extraire en JavaScript : console.log(document.querySelector(`#paris`).dataset.population);, voire console.log(document.querySelector(`#paris`).getAttribute(`data-population`));.

For example, to store the number of inhabitants of a city without using a database, we can write… <p id="paris" data-population="2148271">Paris</p>. The information is easy to extract in JavaScript: console.log(document.querySelector(`#paris`).dataset.population); or console.log(document.querySelector(`#paris`).getAttribute(`data-population`));.

Les attributs de données doivent être préfixés data- pour être valides. Une balise Html peut en recevoir plusieurs.

Data attributes must be prefixed with data- to be valid. An Html tag can receive several of them.

Les attributs de données peuvent aussi servir à styler un élément, comme le rappelle Chris Coyier dans son article A Complete Guide to Data Attributes.

>Data Attributes can also be used to style an element. Chris Coyier explains this in his article A Complete Guide to Data Attributes.

Classes

Classes

En Css, chaque sélecteur a une spécificité. La hiérarchie s’organise comme suit en schématisant : balise (priorité 1), classe (priorité 10), identifiant (priorité 100). En cas de conflit, la dernière règle s’applique grâce à la cascade. (La règle !important a une priorité de 10 000 ; elle signe un travail bâclé.)

In Css, each selector has a specificity. The hierarchy is organized as follows: tag (priority 1), class (priority 10), identifier (priority 100). In case of conflict, the last rule applies thanks to the cascade. (The !important rule has a priority of 10,000; it signals sloppy work).

Les attributs de données ont la même spécificité que les classes.

Data attributes have the same specificity as classes.

Afin d’éviter les conflits, une bonne pratique consiste à n’utiliser que des classes pour la mise en forme. Les identifiants sont réservés aux interactions avec JavaScript. En revanche, dans les deux cas, les attributs de données peuvent trouver un emploi !

To avoid conflicts, a good practice is to use only classes for formatting. Identifiers are reserved for interactions with JavaScript. On the other hand, in both cases, data attributes can find a use!

Ba­lises

Tags

Les balises servent exclusivement à structurer le contenu.

Tags are used exclusively to structure content.

Souvenir des balbutiements du Web, chaque navigateur attribue aux balises un style par défaut, qui compromet la sémantique, d’une part, et, d’autre part, parasite la mise en forme. Aussi convient-il de réinitialiser les styles et d’obtenir le rendu visuel souhaité exclusivement au moyen de classes (ou d’attributs de données).

Reminiscent of the early days of the Web, each browser assigns a default style to tags, which compromises semantics on the one hand and, on the other, interferes with formatting. It is therefore advisable to reset the styles and to obtain the desired visual rendering exclusively by means of classes (or data attributes).

Plutôt que recourir à une librairie comme Normalize.css pour citer la plus connue, la propriété raccourcie all: unset gagne à être utilisée.

Instead of using a library like Normalize.css to name the best known, the shortened property all: unset can be used.

Ainsi…

Thus…

a, abbr, address, area, article, aside, audio, b, base, bdi, bdo, blockquote, body, br, button, canvas, caption, cite, code, col, colgroup, data, datalist, dd, del, details, dfn, dialog, div, dl, dt, em, embed, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, head, header, hgroup, hr, html, i, iframe, img, input, ins, kbd, label, legend, li, link, main, map, mark, math, menu, menuitem, meta, meter, nav, noscript, object, ol, optgroup, option, output, p, param, picture, pre, progress, q, rb, rp, rt, rtc, ruby, s, samp, script, section, select, slot, small, source, span, strong, style, sub, summary, sup, svg, table, tbody, td, template, textarea, tfoot, th, thead, time, title, tr, track, u, ul, var, video, wbr {
    all: unset
}

… ou, en ne ciblant, que les éléments visuels…

… or, by targeting only the visual elements…

a, abbr, address, area, article, aside, audio, b, base, bdi, bdo, blockquote, body, br, button, canvas, caption, cite, code, col, colgroup, data, datalist, dd, del, details, dfn, dialog, div, dl, dt, em, embed, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, html, i, iframe, img, input, ins, kbd, label, legend, li, main, map, mark, math, menu, menuitem, meter, nav, object, ol, optgroup, option, output, p, param, picture, pre, progress, q, rb, rp, rt, rtc, ruby, s, samp, section, select, slot, small, source, span, strong, sub, summary, sup, svg, table, tbody, td, template, textarea, tfoot, th, thead, time, tr, track, u, ul, var, video, wbr {
    all: unset
}

… réinitialise chaque balise.

… resets each tag.

Un travail rigoureux commande de réinitialiser les seules balises pertinentes : la ressource est rare ! n’en déplaise aux amateurs de vastes librairies Css prêtes à l’emploi.

A rigorous work orders to reset only the relevant tags: the resource is rare! Notwithstanding the amateurs of vast Css libraries ready to use.

CSS Default Values Reference indique les valeurs Css par défaut de chaque sélecteur. La réinitialisation proposée peut paraître déconcertante quand les classes (ou les attributs de données !) n’existent pas encore.

CSS Default Values Reference shows the default Css values for each selector. The proposed reset may seem confusing when the classes (or data attributes!) do not exist yet.

Le support de la propriété all est universel, comme l’indique Can I use CSS unset value.

The support of the all property is universal, as indicated in Can I use CSS unset value.

Cependant, la réinitialisation n’est pas parfaite, par exemple avec les éléments <details> et <summary> : une recherche devient alors nécessaire afin de déterminer comment les navigateurs gèrent ces balises. Avec cette syntaxe, l’astuce *{box-sizing:border-box} semble inopérante (le paramètre boxSizingLymnee y remédie) et les césures automatiques ne sont pas correctement prises en charge (une césure manuelle s’impose, hy&#xad;phen).

However, the reset is not perfect, for example with <details> and <summary> elements: a search then becomes necessary to determine how browsers handle these tags. With this syntax, the trick *{box-sizing:border-box} seems inoperative (the parameter boxSizingLymnee remedies this) and automatic hyphenation is not properly supported (manual hyphenation is required, hy&#xad;phen).

Privé.e des éléments visuels imposés par le navigateur, l’auteur.autrice emploie la sémantique à bon escient… Pourquoi recourir à <strong> pour afficher du gras ? Ce contenu a-t-il une haute importance ? Pourquoi utiliser <em> pour obtenir de l’italique ? Ce texte mérite-t-il une emphase ? (Une portion de texte en italique parmi du romain créée une rupture visuelle incongrue comme le soulignement des liens et autres acronymes, d’ailleurs !) Ne vaut-il mieux utiliser un élement générique <span> aux fins de décoration ?

Deprived of the visual elements imposed by the browser, the author employs semantics to good effect… Why use <strong> to display bold? Is this content of high importance? Why use <em> to get italics? Does this text deserve emphasis? (A portion of italicized text among Roman creates an incongruous visual break like underlining links and other acronyms, by the way!) Isn’t it better to use a generic <span> element for decorative purposes?

Le respect de la sémantique favorise le référencement par les moteurs de recherche et la compréhension du contenu par les agents utilisateurs, notamment ceux qui n’offrent pas de restitution visuelle.

The respect of semantics favors the referencing by search engines and the comprehension of the content by user agents, especially those that do not offer visual restitution.

Un lien peut servir à la compréhension du contenu par les robots d’indexation, mais ne pas être heureux à signaler au.à la lecteur.lectrice. Cette pratique est néanmoins déconseillée.

A link can be used for the understanding of the content by the indexing robots, but not be happy to report to the reader. This practice is however not recommended.

Assigner un style à une balise oblige à modifier son apparence dans les cas spécifiques. Par exemple, afin de maintenir le rythme vertical nécessaire à une composition harmonieuse, est attribuée par défaut une marge supérieure aux paragraphes avec p {margin-block-start: 1.5 rem} ; si cette marge devient indésirable, par exemple pour un paragraphe inclus dans un item de liste, l’emploi d’une classe comme .unwelcome {margin-block-start: 0} s’impose. Approche guère rationnelle…

Assigning a style to a tag forces to modify its appearance in specific cases. For example, in order to maintain the vertical rhythm necessary for a harmonious composition, a top margin is assigned by default to paragraphs with p {margin-block-start: 1.5 rem}; if this margin becomes undesirable, for example for a paragraph included in a list item, the use of a class such as .unwelcome {margin-block-start: 0} is required. Hardly a rational approach…

À ce propos, incise, oublions les dimensions physiques au profit des propriétés et valeurs logiques bien plus flexibles !

By the way, let’s forget the physical dimensions in favor of the much more flexible logical properties and values!

Il peut paraître commode de styler directement (en dur) les balises qui reçoivent des pseudo-elements par exemple guillemets ou ornements textuels, si leur apparence dans la page ne varie pas.

It may seem convenient to style directly the tags that receive pseudo-elements, for example quotation marks or textual ornaments, if their appearance in the page does not vary.

Syn­taxe

Syn­tax

Un attribut s’écrit data-ym-selecteur="valeur". La valeur reçoit des guillemets doubles de part et d’autre… "valeur". Le sélecteur et la valeur doivent être conformes aux spécifications Css.

An attribute is written data-ym-selector="value". The value gets double quotes on both sides… "value". The selector and the value must conform to the CSS specifications.

Connaissant la syntaxe Css

Knowing the Css syntax…

.myclass {
    background-color: yellow;
    display: flex
}

… il est facile d’en déduire par rétroaction les attributs de données Html

… it is easy to deduce by feedback Html Data Attributes

<div data-ym-background-color="yellow" data-ym-display="flex">Div</div>

La syntaxe utilisée par Lymnee utilise deux opérateurs booléens, de gauche à droite :  &&  (and, c’est le sélecteur contextuel),  ||  (or). L’arobase, , spécifie une règle (@media ou @supports), les pseudo-sélecteurs un pseudo-élement (:) ou une pseudo-classe (::), comme en Css.

The syntax used by Lymnee uses two Boolean operators, from left to right:  &&  (and, this is the contextual selector),  ||  (or). The arobase, , specifies a rule (@media or @supports), the pseudo-selectors a pseudo-element (:) or a pseudo-class (::), as in Css.

La présente page est évidemment mise en forme grâce à Lymnee ! La console du navigateur présente des dizaines d’exemples.

This page is obviously formatted thanks to Lymnee! The console of the navigator presents dozens of examples.

Pour tester rapidement les exemples présentés, le fichier lymnee.sandbox.html peut être utilisé. Nota. Avec un autre fichier, le paramètre unsetLymnee doit être défini false ou non défini.

To quickly test the examples presented, the file lymnee.sandbox.html can be used. Note: With another file, the unsetLymnee parameter must be set to false or not set.

Attribut simple
Simple attribute
<p data-ym-color="#0000ff">Paragraph</p>
[data-ym-color="#0000ff"] {
    color: #0000ff
}

Une balise peut recevoir un nombre infini d’attributs de données

A tag can receive an infinite number of data attributes

<p data-ym-color="blue" data-ym-font-size="medium">Paragraph</p>

Le nom d’un attribut n’est pas duplicable : l’opérateur  ||  répond à cet usage.

The name of an attribute is not duplicable: the  ||  operator is used for this purpose.

Pseudo-éléments et pseudo-classes s’écrivent…

Pseudo-elements and pseudo-classes are written…

<p data-ym-color="red::first-letter">Paragraph</p>
[data-ym-color="red::first-letter"]::first-letter {
    color: red
}
<a data-ym-content="' ['attr(href)']'::after" href="http://info.cern.ch/hypertext/WWW/TheProject.html">The World Wide Web project</a>
[data-ym-content="' ['attr(href)']'::after"]::after {
    content: ' ['attr(href)']'
}
<p data-ym-color="red::before" data-ym-content="'♩Ox2001'::before">Paragraph</p>
[data-ym-color="red::before"]::before {
    color: red
}
[data-ym-content="'♩Ox2001'::before"]::before {
    content:'♩\2001'
}
<p data-ym-content="'Ox266B'::before">Paragraph</p>
[data-ym-content="'Ox266B'::before"]::before {
    content: '\266B'
}

Les caractères Unicode peuvent être écrits directement ou encodés au format UTF-16. Deux entités encodées au format UTF-16 ne peuvent se suivre. Ces caractères doivent être encadrés par un guillemet droit, '.

Unicode characters can be written directly or encoded in UTF-16 format. Two entities in UTF-16 format cannot follow each other. These characters must be surrounded by a right quotation mark, , '.

La pseudo-classe de négation :not est supportée…

The negation pseudo-class :not is supported…

Avec une classe et un paragraphe, le code s’utilise comme suit…

With a class and a paragraph, this functional notation is used as follows…

<div data-ym-color="red :not(.😂, p)">
    <h1>Title</h1>
    <h2 class="😂">Title</h2>
    <p>Paragraph</p>
</div>
[data-ym-color="red :not(.😂, p)"] :not(.😂, p) {
    color: red
}

Noter l’espace avant :not, car sont ciblés les descendants.

Note the before :not, because descendants are targeted.

Un attribut de données fonctionne également…

A data attribute also works…

<div data-ym-color="red :not([data-foo])">
    <h1>Title</h1>
    <p data-foo>Paragraph</p>
</div>
[data-ym-color="red :not([data-foo])"] :not([data-foo]) {
    color: red
}

Nota. Le nom de cet attribut ne peut commencer par data-ym- ou l’espace de nom équivalent (data-hello-…) qui sert à déclarer les styles.

Note: The name of this attribute cannot start with data-ym- or the equivalent namespace (data-hello-…) used to declare styles.

Les Media queries (requêtes media) sont prises en charge.

Media queries are supported.

<div data-ym-max-width="1024px@media screen and (min-width: 1024px)">Div</div>
@media screen and (min-width: 1024px) {
    [data-ym-max-width="1024px@media screen and (min-width: 1024px)"] {
        max-width: 1024px
    }
}

Les règles @supports fonctionnent…

The @supports rules work…

<div data-ym-display="flex@supports (display: grid)">
    <p>A</p>
    <p>B</p>
</div>
@supports (display: grid) {
    [data-ym-display="flex@supports (display: grid)"] {
        display: flex
    }
}

Les variables Css sont utilisables…

CSS variables can be used…

<p data-ym-font-weight="var(--font-weight-bold)">Paragraph</p>
:root {
    --font-weight-bold: 700
}

[data-ym-font-weight="var(--font-weight-bold)"] {
    font-weight: var(--font-weight-bold)
}

Une valeur peut comprendre n’importe quel caractère, hormis le guillemet "

A value can include any character, except the quote "

<img data-ym-filter="invert(13%) sepia(92%) saturate(7286%) hue-rotate(0deg) brightness(94%) contrast(117%)">
[data-ym-filter="invert(13%) sepia(92%) saturate(7286%) hue-rotate(0deg) brightness(94%) contrast(117%)"] {
    filter: invert(13%) sepia(92%) saturate(7286%) hue-rotate(0deg) brightness(94%) contrast(117%)
}

Dernière illustration…

Latest example…

<div data-ym-animation="sweep 1.5s ease-in-out"></div>
[data-ym-animation="sweep 1.5s ease-in-out"] {
    animation: sweep 1.5s ease-in-out
}
Attribut avec l’opérateur  || 
Attribute with the  ||  operator

Avec le booléen or sont appliquées plusieurs valeurs au même attribut. C’est utile notamment pour les Media queries (requêtes media).

With the boolean or several values are applied to the same attribute. This is useful especially for Media queries.

Premier exemple…

First exemple…

<p data-ym-font-family="sans-serif@media screen || monospace@media print">Paragraph</p>
@media screen {
    [data-ym-font-family="sans-serif@media screen || monospace@media print"] {
        font-family: sans-serif
    }
}
@media print {
    [data-ym-font-family="sans-serif@media screen || monospace@media print"] {
        font-family: monospace
    }
}

Deuxième illustration…

Second illustration…

<a data-ym-color="blue:link || grey:visited || yellow:focus || orange:hover || teal:active" data-ym-cursor="pointer" href="https://www.w3.org/" title="go to W3C" target="_blank" lang="en">W3c</a>
[data-ym-color="blue:link || grey:visited || yellow:focus || orange:hover || teal:active"]:link {
    color: blue
}
[data-ym-color="blue:link || grey:visited || yellow:focus || orange:hover || teal:active"]:visited {
    color: grey
}
[data-ym-color="blue:link || grey:visited || yellow:focus || orange:hover || teal:active"]:focus {
    color: yellow
}
[data-ym-color="blue:link || grey:visited || yellow:focus || orange:hover || teal:active"]:hover {
    color: orange
}
[data-ym-color="blue:link || grey:visited || yellow:focus || orange:hover || teal:active"]:active {
    color: teal
}
[data-ym-cursor="pointer"] {
    cursor: pointer
}

L’ordre des sélecteurs (l’acronyme LoVe Fears HAte constitue un moyen mnémotechnique) est respecté dans la feuille de style produite.

The order of the selectors (the acronym LoVe Fears HAte is a mnemonic) is respected in the produced style sheet.

Troisième exemple…

Third example…

<div data-ym-display="flex@media screen and (min-width: 30em) and (max-width: 49em) || inline@media screen and (min-width: 50em)">Div</div>
@media screen and (min-width: 30em) and (max-width: 49em) {
    [data-ym-display="flex@media screen and (min-width: 30em) and (max-width: 49em) || inline@media screen and (min-width: 50em)"] {
        display: flex
    }
}
@media screen and (min-width: 50em) {
    [data-ym-display="flex@media screen and (min-width: 30em) and (max-width: 49em) || inline@media screen and (min-width: 50em)"] {
        display: inline
    }
}

La quatrième illustration est plus complexe à appréhender…

The fourth illustration is more complex to understand…

<div data-ym-display="inline-block::before || block">Div</div>
[data-ym-display="inline-block::before || block"]::before {
    display: inline-block
}
[data-ym-display="inline-block::before || block"] {
    display: block
}
Attribut avec l’opérateur  && 
Attribute with the  &&  operator

Le booléen and permet l’usage d’un sélecteur contextuel.

The boolean and allows the use of a contextual selector.

Premier exemple…

First exemple…

<div class="ispage">
    <div data-ym-background-color="red && .ispage">Div</div>
</div>
.ispage [data-ym-background-color="red && .ispage"] {
    background-color: red
}

Deuxième illustration, avec deux sélecteurs contextuels différents…

Second illustration, with two different contextual selectors…

<div class="ishome">
    <div data-ym-font-weight="600@media screen and (min-width: 30em) and (max-width: 49em) && .ishome || 700@media screen and (min-width: 50em) && .ishome">Div</div>
</div>

<div class="ispage">
    <div data-ym-font-weight="600@media screen and (min-width: 30em) and (max-width: 49em) && .ispage || 700@media screen and (min-width: 50em) && .ispage">Div</div>
</div>
@media screen and (min-width: 30em) and (max-width: 49em) {
    .ishome [data-ym-font-weight="600@media screen and (min-width: 30em) and (max-width: 49em) && .ishome || 700@media screen and (min-width: 50em) && .ishome"] {
        font-weight: 600
    }
}

@media screen and (min-width: 50em) {
    .ishome [data-ym-font-weight="600@media screen and (min-width: 30em) and (max-width: 49em) && .ishome || 700@media screen and (min-width: 50em) && .ishome"] {
        font-weight: 700
    }
}

@media screen and (min-width: 30em) and (max-width: 49em) {
    .ispage [data-ym-font-weight="600@media screen and (min-width: 30em) and (max-width: 49em) && .ispage || 700@media screen and (min-width: 50em) && .ispage"] {
        font-weight: 600
    }
}

@media screen and (min-width: 50em) {
    .ispage [data-ym-font-weight="600@media screen and (min-width: 30em) and (max-width: 49em) && .ispage || 700@media screen and (min-width: 50em) && .ispage"] {
        font-weight: 700
    }
}

Ultimes exemples…

Finals examples…

<div data-js-summary="open">
    <p data-ym-color="blue && [data-js-summary=close] || red && [data-js-summary=open]">Summary</p>
</div>
[data-js-summary=close] [data-ym-color="blue && [data-js-summary=close] || red && [data-js-summary=open]"] {
    color: blue
}

[data-js-summary=open] [data-ym-color="blue && [data-js-summary=close] || red && [data-js-summary=open]"] {
    color: red
}
<details open>
    <summary>Summary</summary>
    <p data-ym-color="blue && details[open]">Details</p>
</details>
details[open] [data-ym-color="blue && details[open]"] {
    color: blue
}

Le sélecteur contextuel peut être un identifiant #monidentifiant, une classe .maclasse ou un attribut [monattribut].

The contextual selector can be an identifier #myidentifier, a class .myclass or an attribute [myattribute].

Le sélecteur contextuel est commode pour préparer un contenu invisible au chargement de la page, qui s’affichera ultérieurement grâce à JavaScript…

The contextual selector is convenient for preparing content that is invisible when the page loads, and that will be displayed later thanks to JavaScript…

<div id="foo">
    <div data-ym-background-color="red && [data-js-bar]">Div</div>
</div>
<script>
document.querySelector('#foo').setAttribute('data-js-bar', '');
</script>

Pour viser en plus un élément <span>, la syntaxe devient…

To additionally target a <span> element, the syntax becomes…

<script>
document.querySelector('#foo').setAttribute('data-js-bar', '');
document.querySelector('#foo span').setAttribute('data-js-bar', '');
</script>

Afin d’ajouter l’attribut à tous les enfants, nous utilisons…

In order to add the attribute to all children, we use…

<script>
document.querySelector('#foo').setAttribute('data-js-bar', '');
document.querySelector('#foo > *').setAttribute('data-js-bar', '');
</script>

Le codage manuel du style de ces attributs de données est facile, mais il peut être automatisé.

Hand coding the style of these data attributes is easy, but it can be automated.

Li­brai­rie

Li­brarie

La simplicité de lecture de Lymnee par un humain facilite son traitement logique…

The simplicity of reading Lymnee by a human facilitates its logical treatment…

Avec XPath ?

With XPath?

… Surtout que le langage de requête XML Path Language localise les nœuds.

… Especially since the XML Path Language query locates the nodes.

En Php, la syntaxe pour identifier ces nœuds s’écrit…

In Php, the syntax for identifying these nodes is…

$prefixDataAttributes = 'data-ym-';
$nodesYm = $xpath->query('//@*[starts-with(name(), "'.substr($prefixDataAttributes, 0, -1).'")]');

Avec le paquet xpath dans Node.js, la syntaxe pour identifier ces nœuds s’écrit…

With the xpath package in Node.js, the syntax for identifying these nodes is written…

var prefixDataAttributes = 'data-ym-';
var nodesYm = xpath.select('//@*[starts-with(name(), "' +  prefixDataAttributes.slice(0, -1) + '")]', doc);

En JavaScript, la syntaxe pour identifier ces nœuds s’écrit…

In JavaScript, the syntax for identifying these nodes is written…

var prefixDataAttributes = 'data-ym-';
var nodesYm = document.evaluate('//@*[starts-with(name(), "' +  prefixDataAttributes.slice(0, -1) + '")]', document, null, XPathResult.ANY_TYPE, null);

La méthode iterateNext() effectue une itération sur chaque nœud.

The iterateNext() method performs an iteration on each node.

Les trois prédicats sont identiques, bien évidemment !

The three predicates are identical, of course!

Pour identifier toutes les balises en JavaScript, la syntaxe est…

To identify all tags in JavaScript, the syntax is…

var tags = document.evaluate('//*', document, null, XPathResult.ANY_TYPE, null);

Pour identifier uniquement les balises comportant l'attribut data-ym-, la requête devient…

To identify only tags with the attribute data-ym-, the query becomes…

var prefixDataAttributes = `data-ym-`;
var tags = document.evaluate('//*[starts-with(name(@*), "' +  prefixDataAttributes.slice(0, -1) + '")]', document, null, XPathResult.ANY_TYPE, null);

… ou…

… or…

var prefixDataAttributes = `data-ym-`;
var tags = document.evaluate(`//@*[starts-with(name(), "` +  prefixDataAttributes.slice(0, -1) + `")]/..`, document, null, XPathResult.ANY_TYPE, null);

… avec la mé­thode Document.querySelectorAll()

… with the method Document.querySelectorAll()

En dernier ressort, la méthode Document.querySelectorAll() plus simple et concise est préférée…

As a last resort, the simpler and more concise Document.querySelectorAll() method is preferred…

var prefixDataAttributes = `data-ym-`;
var nodesYm = document.querySelectorAll(`*`);
nodesYm.forEach((nodeYm) => {
    for (let attribute of nodeYm.getAttributeNames()) {
        if (attribute.startsWith(prefixDataAttributes.slice(0, -1))) {
        }
    }
});

Le fichier en JavaScript, lymnee.reload.js, injecte une feuille de style dans le Dom à partir des attributs de données qui respectent la syntaxe Lymnee.

The file in JavaScript, lymnee.reload.js, injects a style sheet into the Dom from the data attributes that respect the Lymnee syntax.

Le code Css s’inscrit juste avant la fermeture de la balise <head>.

The Css code is written just before the <head> tag is close.

L’analyse puis la génération ne ralentissent pas significativement l’affichage du document.

The analysis and then the generation do not significantly slow down the display of the document.

Cette option permet de tester une règle de style, instantanément, c’est-à-dire à la volée.

This option also allows you to test a style rule, instantly, i.e. on the fly.

Le fichier doit être inclus à la fin de chaque page…

The file must be included at the end of each page…

<script src="lymnee.reload.js"></script>

Afin de ne pas gêner les utilisateurs, l’ancienne version lymnee.live.min.js est toujours en ligne. Comme l’actuelle version, lymnee.reload.js, utilise la version Ecma 6, le code ne se compresse pas.

In order not to bother users, the old version lymnee.live.min.js is still online. As the current version, lymnee.reload.js, uses the Ecma 6, version, the code does not compress.

Pa­ra­mètres

Pa­ram­e­ters

Tous les paramètres, facultatifs, sont définis false. Ils doivent être déclarés avant l’appel de lymnee.reload.js.

All parameters, optional, are set to false. They must be declared before calling lymnee.reload.js.

Lymnee analyse les chaînes en Javascript qui s’affichent au chargement de la page. Seule condition : le script lymnee.reload.js doit être appelé juste avant la balise </body>.

Lymnee parses the strings in Javascript that are displayed when the page are displayed at page load. The only condition: the script lymnee.reload.js must be called just before the </body> tag.

Paramètre boxSizingLymnee
ParameterboxSizingLymnee

Si ce paramètre est défini true avec le paramètre unsetLymnee, les éléments réinitialisés recevront la règle box-sizing:border-box.

If this parameter is set to true with the unsetLymnee parameter, the reset elements will receive the rule box-sizing:border-box.

Paramètre cssAfterLymnee
ParametercssAfterLymnee

Ce paramètre permet d’ajouter un code Css qui s’inscrira après les styles générés par Lymnee à l’issue de l’analyse des attributs de données.

This parameter allows to add a Css code which will be written after the styles generated by Lymnee after the analysis of the data attributes.

Paramètre cssBeforeLymnee
ParametercssBeforeLymnee

Ce paramètre permet d’ajouter un code Css qui s’inscrira avant les styles générés par Lymnee à l’issue de l’analyse des attributs de données.

This parameter makes it possible to add a Css code which will be registered before the styles generated by Lymnee at the end of the analysis of the data attributes.

Il est aussi possible d’ajouter ce code directement dans la balise <head> </head>.

It is also possible to add this code directly in the <head> </head>tag.

Paramètre entriesLymnee
ParameterentriesLymnee

Ce paramètre, défini par un objet Set, spécifie des attributs de données non présents lors du chargement de la page : ils sont analysés par Lymnee et ajoutés aux styles. Ils doivent avoir le même préfixe que les autres attributs de données (data-ym-, data-hello- et autres espaces de nom équivalents…). Cette option est pratique afin de styler un contenu qui s’affichera plus tard. Par exemple…

This parameter, defined by a Set object, specifies data attributes not present when the page is loaded: they are parsed by Lymnee and added to the styles. They must have the same prefix as the other data attributes (data-ym-, data-hello- and other equivalent namespaces…). This option is useful to style content that will be displayed later. For example…

var entriesLymnee = new Set([`data-ym-background-color="black"`, `data-ym-color="red"`, `data-ym-font-size="large@media screen || medium@media screen and (max-width: 768px) || 12pt@media print"`]);

Si les attributs de données existent déjà, il sont fusionnés.

If the data attributes already exist, they are merged.

Paramètre prefixDataAttributes
ParameterprefixDataAttributes

Si ce paramètre n’est pas défini, Lymnee analysera les attributs de données préfixés par data-ym-. Le choix de l’espace de nom équivalent est sans importance : il doit débuter par data- et être suivi du nom choisi puis d’un tiret, par exemple data-prefix-.

If this parameter is not set, Lymnee will parse data attributes prefixed with data-ym-. The choice of the equivalent namespace is irrelevant: it must start with data- and be followed by the chosen name and a dash, for example data-prefix-.

Paramètre printLymnee
ParameterprintLymnee

Si ce paramètre est défini true, la console du navigateur affichera la feuille de style.

If this parameter is set to true, the browser console will display the stylesheet.

Paramètre unsetLymnee
ParameterunsetLymnee

Si ce paramètre est défini true, sont réinitialisés les styles par défaut des éléments qui reçoivent l’attribut data-ym- ou un espace de nom équivalent.

If this parameter is set to true, the default styles of elements that receive the attribute data-ym- or an equivalent namespace are reset.

Browser Default Styles indique comment les navigateurs stylent par défaut les éléments Html.

Browser Default Styles indicates how browsers style Html elements by default.

Ce paramètre peut aussi défini être défini par un objet Set : il vaut alors true et réinitialise en plus les élements Html énumérés. Par exemple…

This parameter can also be defined by a Set object: it is then true and resets the listed Html elements. For example.…

var unsetLymnee = new Set([`h1`, `h2`, `h3`, `h4`, `h5`, `h6`]);

Si les élements Html énumérés existent déjà car ils ont reçu l’attribut data-ym-, ils sont fusionnés.

If the listed Html elements already exist because they have been given the attribute data-ym-, they are merged.

Le recours à l’objet unsetLymnee s’impose notamment si des attributs de données sont servis par JavaScript avant le chargement de la page.

The use of the unsetLymnee object is particularly necessary if data attributes are served by JavaScript before the page is loaded.

Tous les paramètres (à titre d’exemple)
All parameters (for example)
<script>
var cssAfterLymnee = `
:lang(fr) {  
    quotes: '«\u202F' '\u202F»'
}
:lang(en) {  
    quotes: '“' '”'
}`,
cssBeforeLymnee = `
:root {
    --font-size: medium;
    --font-weight-bold: 700;
    --font-weight-regular: 400;
    --font-weight-strong: 600;
}`,
boxSizingLymnee = true,
entriesLymnee = new Set([`data-ym-background-color="black"`, `data-ym-color="red"`, `data-ym-font-size="large@media screen || medium@media screen and (max-width: 768px) || 12pt@media print"`]),
prefixDataAttributes = `data-ym-`,
printLymnee = true,
unsetLymnee = new Set([`h1`, `h2`, `h3`, `h4`, `h5`, `h6`]);
</script>

Cdn

Une version distante, accessible à l’Url https://cdn.jsdelivr.net/gh/lymnee/lymnee/lymnee.reload.js, est aussi utilisable en production…

A remote version, accessible at the Url https://cdn.jsdelivr.net/gh/lymnee/lymnee/lymnee.reload.js, can also be used in production…

<script src="https://cdn.jsdelivr.net/gh/lymnee/lymnee/lymnee.reload.js"></script>

Ce fichier distant fonctionne comme le fichier local.

This remote file works like the local file.

Trai­te­ment

Pro­cess­ing

À l’issue de l’analyse des attributs de données, les styles générés par Lymnee sont ajoutés à l’élement <head>.

Upon completion of the data attribute analysis, the styles generated by Lymnee are added to the <html> element.

Lymnee ajoute à la balise <html> l’attribut de donnée data-lymnee et supprime l’attribut de donnée data-eenmyl s’il existe : ce traitement permet une solution de repli en Css quand le navigateur du client ne permet pas de styler le contenu faute de support Ecma 6. Dans le présent document, nous utilisons les règles de style suivantes …

Lymnee adds to the <html> tag the data-lymnee data attribute and removes the data-eenmyl data attribute if it exists: this treatment allows a fallback solution in Css when the client’s browser does not allow to style the content due to lack of Ecma 6 support. In this document, we use the following style rules…

<html data-eenmyl>
<head>
    <style>
        [data-eenmyl] [data-lʎɯuǝǝ] {
            font-family: monospace
        }
        [data-eenmyl] [data-ǝǝuɯʎl] {
            display: none
        }
    </style>
</head>
<body>
    <div data-ym-display="none" data-lʎɯuǝǝ>
    </div>
    <div data-ǝǝuɯʎl>
    </div>
</body>

À pro­pos de ce do­cu­ment…

About the do­c­ument…

Le présent document recourt extensivement aux attributs de données : ils servent à styler le contenu, à afficher les abbréviations et les liens, à générer le sommaire et à servir quatre versions différentes…

This document makes extensive use of data attributes: they are used to style the content, to display abbreviations and links, to generate the summary and to serve four different versions…

  1. le texte en français ;
  2. le texte en anglais ;
  3. un résumé en français ;
  4. un résumé en anglais.
  1. the French text;
  2. the English text;
  3. a summary in French;
  4. a summary in English.

(Les technologies courantes pour produire un contenu multilingue sont pénibles à utiliser et nécessitent un traitement côté serveur.)

(Current technologies for producing multilingual content are cumbersome to use and require server-side processing).

L’application des attributs de données peut être illimitée et rendre ainsi le Htmlextensible.

The application of data attributes can be unlimited and thus make Htmlextensible.

Les attributs de données sont aussi faciles à utiliser en Html qu’en JavaScript.

Data attributes are as easy to use in Html as in JavaScript.

</de­tails>

Contact, lymnnee@outlok.fr.

Contenu à parfaire mis à jour le Perfectible content updated on .

arrow_circle_up