Remarque : Je viens de traduire le texte ci-dessous et de le publier ici. Les références sont à la fin de cet article.
CSS est un langage de programmation hautement spécialisé axé sur les systèmes de style. En raison de ce cas d’usage unique et de son caractère déclaratif, il est parfois difficile à comprendre. Certains nient même qu’il s’agisse d’un langage de programmation. Prouvons-leur le contraire en programmant un système de style intelligent et flexible.
Les langages plus traditionnels et généraux (comme JavaScript) nous donnent des outils comme "Conditions" (if/then), "Boucles" (pour, while), "Portes logiques" (===, &&, etc. .) et "Variables". Ces structures sont nommées différemment en CSS, leur syntaxe est très différente pour mieux s'adapter au cas d'utilisation spécifique du style d'un document, et certaines d'entre elles n'étaient tout simplement pas disponibles en CSS jusqu'à il y a quelques années.
Les variables sont les plus simples. On les appelle Propriétés personnalisées en CSS (même si tout le monde les appelle de toute façon des variables, même dans leur propre syntaxe).
:root { --color: red; } span { color: var(--color, blue); }
Le double tiret déclare une variable et attribue une valeur. Cela doit se produire dans une portée, car faire cela en dehors d'un sélecteur briserait la syntaxe CSS. Notez le sélecteur :root, qui fonctionne comme une portée globale.
Les conditions peuvent être écrites de plusieurs manières, selon l'endroit où vous souhaitez les utiliser. Les sélecteurs ont une portée pour leurs éléments, les requêtes multimédias ont une portée globale et nécessitent leurs propres sélecteurs.
[data-attr='true'] { /* if */ } [data-attr='false'] { /* elseif */ } :not([data-attr]) { /* else */ }
:checked { /* if */ } :not(:checked) { /* else */ }
:root { color: red; /* else */ } @media (min-width > 600px) { :root { color: blue; /* if */ } }
Les compteurs sont la forme de boucle la plus directe en CSS, mais aussi celle avec le cas d'utilisation le plus restreint. Vous pouvez uniquement utiliser des compteurs sur la propriété content, en l'affichant sous forme de texte. Vous pouvez ajuster votre « incrément », votre « point de départ » et votre « valeur » à tout moment donné, mais la sortie est toujours limitée au texte.
main { counter-reset: section; } section { counter-increment: section; counter-reset: section; } section > h2::before { content: 'Headline ' counter(section) ': '; }
Mais que se passe-t-il si vous souhaitez utiliser une boucle pour définir un modèle de mise en page récurrent ? Ce type de boucle est un peu plus obscur : c'est la propriété d'auto-remplissage des grilles.
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
Cela remplit la grille avec autant d'éléments que possible, tout en les mettant à l'échelle pour remplir l'espace disponible, mais en les divisant en plusieurs lignes si nécessaire. Il se répète tant qu'il trouve des éléments de grille et les limite à une largeur minimale de 300 px et une largeur maximale d'une fraction de la taille de leur conteneur de grille. C'est probablement plus facile à voir qu'à expliquer :
Et enfin, il y a les « sélecteurs en boucle ». Ils prennent un argument, qui peut être une formule à sélectionner très précisément.
section:nth-child(2n) { /* seleciona todos os elementos pares */ } section:nth-child(4n + 2) { /* seleciona a cada quarto items, iniciando a partir do segundo */ }
Pour des cas vraiment particuliers, vous pouvez combiner :nth-child() avec :not(), comme :
section:nth-child(3n):not(:nth-child(6)) { /* seleciona a cada 3 elementos, mas não o sexto elemento */ }
Vous pouvez remplacer :nth-child() par :nth-of-type() et :nth-last-of-type() pour modifier la portée de ces derniers exemples.
Ana Tudor a écrit un article sur les portes logiques CSS. Login Gates travaille sur l'idée de combiner des variables avec calc. Elle continue ensuite à modéliser et à animer des objets 3D avec cela. Cela ressemble à de la magie arcanique, cela devient de plus en plus fou à mesure que l'article avance, et c'est généralement l'une des meilleures explications de la raison pour laquelle CSS est en fait un langage de programmation.
* + * { margin-top: 1rem; }
Owl Selector sélectionne chaque élément qui suit un élément. L'application d'une marge supérieure à cela ajoute effectivement un espace entre les éléments, comme le fait l'écart de grille, mais sans le système de grille. Cela signifie également qu'il est plus personnalisable. Vous pouvez remplacer votre marge supérieure et l'adapter à tout type de contenu. Vous souhaitez avoir 1rem d'espace entre chaque élément, mais 3rem avant un titre ? C'est plus facile à faire avec un sélecteur de hibou que dans une grille.
Kevin Pennekamp a un article détaillé à ce sujet qui explique même son algorithme en pseudocode.
Podemos criar toggles em nosso código css que ligam e desligam certas regras com variables e calc. Isso nos dá condições muito versáteis.
.box { padding: 1rem 1rem 1rem calc(1rem + var(--s) * 4rem); color: hsl(0, calc(var(--s, 0) * 100%), 80%); background-color: hsl(0, calc(var(--s, 0) * 100%), 15%); border: calc(var(--s, 0) * 1px) solid hsl(0, calc(var(--s, 0) * 100%), 80%); } .icon { opacity: calc(var(--s) * 100%); transform: scale(calc(var(--s) * 100%)); }
Dependendo do valor de --s, .box habilitará ou desabilitará seus alert styles.
Vamos levar a mesma lógica um passo adiante e criar uma color variable que depende do seu contraste com a background color:
:root { --theme-hue: 210deg; --theme-sat: 30%; --theme-lit: 20%; --theme-font-threshold: 51%; --background-color: hsl(var(--theme-hue), var(--theme-sat), var(--theme-lit)); --font-color: hsl( var(--theme-hue), var(--theme-sat), clamp(10%, calc(100% - (var(--theme-lit) - var(theme-font-threshold)) * 1000), 95%) ); }
Este snippet calcula um background color a partir de valores HSL e uma font color black ou white, invertendo o valor de lightness (luminosidade) do background. Isso por si só pode resultar em baixo contraste de cor (uma fonte cinza de 40% em um background cinza de 60% é praticamente ilegível), então subtrairei um valor threshold (o ponto em que a cor muda de white para black), multiplicarei por um valor insanamente alto como 1000 e farei clamp nele entre 10% e 95%, para obter uma porcentagem de lightness válida no final. Tudo é controlável editando as quatro variáveis no início do snippet.
Este método também pode ser usado para escrever lógica de cores intrincada e themes automáticos, com base apenas em valores HSL.
Vamos combinar o que temos até agora para limpar a stylesheet. Ordenando tudo por viewports parece um pouco espaguete, mas ordenar isso por componente não parece nada melhor. Com variables, podemos ter o melhor dos dois mundos:
/* define variables */ :root { --paragraph-width: 90ch; --sidebar-width: 30ch; --layout-s: "header header" "sidebar sidebar" "main main" "footer footer"; --layout-l: "header header" "main sidebar" "footer footer"; --template-s: auto auto minmax(100%, 1fr) auto / minmax(70%, var(--paragraph-width)) minmax(30%, var(--sidebar-width)); --template-l: auto minmax(100%, 1fr) auto / minmax(70%, var(--paragraph-width)) minmax(30%, var(--sidebar-width)); --layout: var(--layout-s); --template: var(--template-s); --gap-width: 1rem; } /* manipula variables por viewport */ @media (min-width: 48rem) { :root { --layout: var(--layout-l); --template: var(--template-l); } } /* realiza o bind no DOM */ body { display: grid; grid-template: var(--template); grid-template-areas: var(--layout); grid-gap: var(--gap-width); justify-content: center; min-height: 100vh; max-width: calc( var(--paragraph-width) + var(--sidebar-width) + var(--gap-width) ); padding: 0 var(--gap-width); }
Todas as global variables são definidas no topo e ordenadas por viewport. Essa seção efetivamente se torna a Definition of Behavior, esclarecendo questões como:
Abaixo estão as definições de regras, ordenadas por componente. As Media Queries não são mais necessárias aqui, porque elas já estão definidas no topo e colocadas em variables. Podemos simplesmente codificar em nossas stylesheets sem interrupções neste ponto.
Um caso especial de pseudo classes é o :target selector, que pode ler o hash fragment da URL. Aqui está uma demonstração que usa essa mecânica para simular uma experiência semelhante a SPA:
Eu escrevi um post sobre isso. Só esteja ciente de que isso tem algumas implicações sérias de acessibilidade e precisa de alguma mecânica JavaScript para realmente ser livre de barreiras. Não faça isso em um live environment.
Manipular CSS variables se tornou uma ferramenta muito poderosa agora. Também podemos aproveitar isso em JavaScript:
// configura --s em :root document.documentElement.style.setProperty('--s', e.target.value); // configura --s scoped para #myID const el = document.querySelector('#myID'); el.style.setProperty('--s', e.target.value); // lê variables de um element const switch = getComputedStyle(el).getPropertyValue('--s');
Os exemplos de codepen acima funcionam exatamente assim.
CSS é muito capaz de definir layout systems inteligentes e reativos. Suas estruturas de controle e algoritmos podem ser um pouco estranhos em comparação com outras linguagens, mas eles estão lá e estão à altura da tarefa. Vamos parar de apenas descrever alguns styles e começar a fazer eles funcionar.
Artigo escrito por Daniel Schulz
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!