CSSでロジックを書く

PHPz
PHPzオリジナル
2024-08-05 19:44:521116ブラウズ

Escrevendo Lógica em CSS

注: 以下のテキストを翻訳してここに投稿しました。参考文献はこの記事の最後にあります。

CSS は、スタイル システムに焦点を当てた高度に特殊化されたプログラミング言語です。この使用例は 1 つだけであり、宣言的な性質があるため、理解するのが難しい場合があります。プログラミング言語であることを否定する人もいます。インテリジェントで柔軟なスタイル システムをプログラミングして、それらが間違っていることを証明しましょう。

制御構造

より伝統的な汎用言語 (JavaScript など) では、「条件」 (if/then)、「ループ」 (for、while)、「論理ゲート」 (===、&& など) などのツールが提供されます。 .) と「変数」。これらの構造は CSS では異なる名前が付けられ、その構文はドキュメントのスタイルを設定する特定の使用例にうまく対応するために大きく異なります。また、それらの一部は単純に数年前まで CSS で使用できませんでした。

変数

変数は最も簡単です。これらは、CSS では カスタム プロパティ と呼ばれます (ただし、独自の構文であっても、誰もがこれらを変数と呼びます)。

:root {
    --color: red;
}
span {
    color: var(--color, blue);
}

二重ダッシュは変数を宣言し、値を割り当てます。これをセレクターの外で行うと CSS 構文が壊れてしまうため、これはスコープ内で行う必要があります。 :root セレクターはグローバル スコープとして機能することに注意してください。

条件

条件は、使用する場所に応じて、いくつかの方法で記述することができます。セレクターには要素のスコープがあり、メディア クエリにはグローバル スコープがあり、独自のセレクターが必要です。

属性セレクター:

[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 */
    }
}

ループ

カウンターは CSS のループの最も直接的な形式ですが、使用例が最も制限されているものでもあります。カウンターはコンテンツ プロパティでのみ使用でき、テキストとして表示されます。 「増分」、「開始点」、「値」はいつでも調整できますが、出力は常にテキストに限定されます。

main {
    counter-reset: section;
}

section {
    counter-increment: section;
    counter-reset: section;
}

section > h2::before {
    content: 'Headline ' counter(section) ': ';
}

しかし、ループを使用して繰り返しのレイアウト パターンを定義したい場合はどうすればよいでしょうか?このタイプのループはもう少しわかりにくく、グリッドの自動入力プロパティです。

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

これにより、グリッドに収まる限り多くの要素が埋め込まれ、使用可能なスペースを満たすように要素が拡大縮小されますが、必要に応じて複数の行に分割されます。グリッド項目が見つかる限り繰り返し、最小幅は 300 ピクセル、最大幅はグリッド コンテナーのサイズの一部に制限されます。おそらく説明するより見たほうが簡単でしょう:

そして最後に、「ループセレクター」があります。これらは引数を受け取ります。これは、非常に正確に選択するための式にすることができます。

section:nth-child(2n) {
    /* seleciona todos os elementos pares */
}

section:nth-child(4n + 2) {
    /* seleciona a cada quarto items, iniciando a partir do segundo */
}

本当に特殊な場合には、次のように :nth-child() と :not() を組み合わせることができます。

section:nth-child(3n):not(:nth-child(6)) {
    /* seleciona a cada 3 elementos, mas não o sexto elemento */
}

:nth-child() を :nth-of-type() および :nth-last-of-type() に置き換えて、これらの最後の例のスコープを変更できます。

論理ゲート

Ana Tudor が CSS Logic Gates に関する記事を書きました。 Login Gates は、変数と計算を組み合わせるというアイデアに基づいて動作します。その後、これを使用して 3D オブジェクトのモデリングとアニメーションを続けます。これは難解な魔法のように聞こえますが、記事が進むにつれてさらに常軌を逸したものになっていきます。一般的に、これは CSS が実際にプログラミング言語である理由を説明する最良の説明の 1 つです。

テクニック

フクロウセレクター

* + * {
    margin-top: 1rem;
}

フクロウセレクターは、項目に続く各項目を選択します。これにマージントップを適用すると、グリッド ギャップと同様に項目間にギャップが効果的に追加されますが、グリッド システムは使用されません。これは、よりカスタマイズ可能であることも意味します。 margin-top をオーバーライドして、あらゆるタイプのコンテンツに適応させることができます。各項目間のスペースは 1 レム、タイトルの前は 3 レムにしたいですか?これは、グリッドよりもフクロウ セレクターを使用した方が簡単です。

Kevin Pennekamp はこれに関する詳細な記事を掲載しており、彼のアルゴリズムを疑似コードで説明しています。

Conditional Styling

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.

Automatic contrast colors

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.

Limpando as stylesheets

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:

  • Quais aspectos globais da stylesheet temos? Estou pensando em coisas como font size, colors, medidas repetidas, etc.
  • Quais aspectos que mudam frequentemente nós temos? Container widths, Grid layouts e similares vêm à mente.
  • Como os valores devem mudar entre as viewports? Quais global styles se aplicam a qual viewport?

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.

Leando o hash parameter

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.

Definindo Variables ​​em JavaScript

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.

Resumo

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.

Fonte

Artigo escrito por Daniel Schulz

以上がCSSでロジックを書くの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。