retour

⚗️ Exercices (de feuille) de styles

Ces temps-ci j’ai environ 4 projets persos démarrés (plus 3 à l’état d’ébauche), auxquels j’ajoute un ou deux projets open source auxquels je contribue. C’est pour ça que quand j’ai cinq minutes, je fais des petits trucs sur mon blog, qui n’est pas comptabilisé dans les projets cités plus haut.

L’avantage avec le blog, c’est que la base est là, la baraque est construite, et que je peux juste faire des expériences de style, comme si je repeignais un mur, mais en moins salissant.

Tel qu’il est actuellement, le blog est propulsé par Kirby, mon petit chouchou pour la gestion simple de sites qui n’ont pas de gros besoins de fonctionnalités. J’ai un modèle de page d’accueil qui liste les billets du blog, j’ai un modèle de page de billet, et un modèle de page par défaut.

Les styles ont été conçus à partir de zéro. Mes seules règles : que le site soit lisible et accessible, et que je ne m’empèche pas d’utiliser des propriétés CSS modernes.

Parmi les exemples de propriétés modernes, le mode sombre et les liens.

Les couleurs du site sont gérées par le biais de propriétés CSS personnalisées. Une teinte est définie, et déclinée en plusieurs variantes, nommées en fonction du contraste qu’elles ont avec la couleur de fond.

:root {
    --color-base: 120deg;

    --color-action-low-contrast: hsl(var(--color-base), 80%, 80%);
    --color-action-medium-contrast: hsl(var(--color-base), 70%, 40%);
    --color-action-high-contrast: hsl(var(--color-base), 60%, 25%)
}

Le mode sombre est géré par une media-query spécifique, qui modifie les propriétés des couleurs, sans toucher à la teinte de base.

@media screen and (prefers-color-scheme: dark) {
    :root {
        --color-action-low-contrast: hsl(var(--color-base), 20%, 25%);
        --color-action-medium-contrast: hsl(var(--color-base), 50%, 50%);
        --color-action-high-contrast: hsl(var(--color-base), 100%, 80%);
    }
}

Pour voir les deux versions, j’ai trouvé cette excellente (et minuscule) extension Firefox, qui permet d’alterner entre le mode clair et le mode sombre, quels que soient les réglages du système ou du navigateur : https://github.com/Cimbali/toggle-dark-mode.

Les liens utilisent des propriétés CSS peu connues, mais très pratiques : text-decoration-thickness qui régit l’épaisseur du trait de décoration (ici un soulignement) et text-underline-offset qui cible le trait de soulignement pour le décaler. Ces deux propriétés sont utilisables sur tous les navigateurs depuis 2021, et elles sont animables via la propriété transition. En animant aussi la couleur du trait de soulignement et celle du texte, on obtient ce résultat. Le seul reproche que je peux faire à cette technique, c’est que je ne peux pas ajouter de marge intérieure au trait (qui est plutôt un bloc coloré qui contient le texte) pour le rendre un peu plus large que le texte qu’il contient.

Un site en jachère…

Un blog, ça vit, ça meurt… Je le sais, j’en ai entretenu une demi-douzaine en vingt ans (je viens de vérifier la date d’enregistrement de mon premier nom de domaine : ça dit Creation Date: 2003-01-23T17:55:34Z, j’étais au lycée), et la quasi-totalité ne sont plus entretenus, voire même plus sur le web (hé oui, pour les dix ans de mon premier je l’ai détruit, ce qui lui a valu un petit épitaphe sur le carnet d’un ami).

J’avais envie de présenter le manque d’entretien de ce carnet par un biais amusant et facilement compréhensible. Quand on a un jardin, si on le laisse tranquille plusieurs mois, les herbes folles poussent et les feuilles des arbres couvrent le sol. C’est le temps qui passe, c’est la nature.

Sur ce carnet, c’est pareil. Plus le temps s’écoulera entre deux mises à jour, plus les pages verront des plantes et des feuiles mortes. Si elles deviennent trop nombreuses et gênent à la lecture, il est possible de les ratisser.

…qui évolue un petit peu selon les saisons

En restant sur un thème de rythme de la nature, et du fait que ce rythme ne s’applique pas au web, j’ai eu envie d’insérer un autre témoin du temps qui passe. Là, il ne sera pas lié à mon entretien de cet espace web mais plutôt au jour de l’année.

Comme je l’ai abordé plus haut, la couleur est définie au format HSL, ou Hue/Saturation/Lightness, soit Teinte/Saturation/Luminosité en français. Grâce à la manière dont j’ai séparé la définition de la teinte dans la définition des couleurs, si je change la valeur de la teinte, les valeurs de saturation et de luminosité ne seront pas touchées.

Les valeurs de teinte sont définies en degré, selon leur angle sur le cercle chromatique. Il y a donc 360 couleurs. Et 365 jours dans l’année. Vous voyez où je veux en venir ?

En arrondissant un peu, chaque jour peut avoir une couleur différente selon son numéro dans l’année. Comment l’avoir ? En PHP c’est facile : <?= date('z') ?> nous fournit la valeur, qu’on colle donc dans une définition de style sur l’élément html :

<html lang="fr" style="--color-base: <?= date('z') ?>deg;">

Mais attendez ! Le cercle chromatique partirait du rouge en janvier, colorerait le printemps en jaune, l’été en vert puis bleu, et l’automne en violet. J’ai ajusté ça en inversant la valeur du jour, et en choissant un point de départ différent. Comme ça on a bleu (hiver), vert (printemps), orange (été) rouge et violet (automne). Ça se tient mieux, à mon avis.

Et comme je pouvais le faire, j’ai ajouté un filtre à l’icône de raccourci, qui dépend lui aussi de la date actuelle, pour décaler la teinte de l’icône et donc adapter sa couleur en fonction de la couleur principale du blog. L’emoji qui précède le titre du site a lui aussi reçu ce traitement lorsqu’on ne passe pas la souris sur le titre.

Avec des emoji qui dépassent un peu

En parlant de l’emoji qui précède le titre, là aussi il y a quelques trucs CSS pour que ça fonctionne.

L’emoji est placé par rapport au positionnement du titre, en retrait par rapport à la colonne de contenu. Jusque là tout va bien. Mais initialement, elle dépassait aussi sur format mobile—et était coupée par le bord de l’écran. Il a fallu trouver une solution.

La colonne de contenu est définie sans avoir besoin de media-query. En effet, ma définition se fonde sur la valeur minimale entre 86% de la largeur de la fenêtre, et la largeur maximum de ligne, qui est de 44 hauteurs de caractère à la taille par défaut. Soit, en CSS :

:root {
    --max-body-width: 86vw;
    --max-line-length: 44rem;
}

body {
    width: min(var(--max-body-width), var(--max-line-length));
}

Pour rentrer le titre (et son icône) dans la colonne, il faut ajouter une marge :

  • qui ne soit jamais supérieure à la largeur de l’icône (pour ne pas trop décaler le titre vers la droite)
  • qui ne soit jamais négative (à l’inverse, pour ne pas décaler le titre vers la droite)
  • qui dépende de la différence entre la largeur maximale de la ligne et la largeur courante de l’écran (cette valeur est négative en écran large et positive en écran mobile)

Ce qui donne, en CSS :

h1 {
    --icon-width: 1.25em;
    margin-left:
        min(
            var(--icon-width),
            max(
                0px, calc(var(--max-line-length) - var(--max-body-width))
            )
        );
}

Et voilà, suite à ça j’ai pas trop de conclusion à apporter à l’article. Si ça se trouve je recommencerai tout le travail de style dans trois semaines, ou dans trois ans. Ça va dépendre de mon avancée sur mes autres projets, je pense. D’ici là, on va essayer de ne pas laisser pousser trop d’herbes folles.


On en discute ?…


Billets liés