lang 属性には、関連付けることができる言語が 1 つだけです。つまり、ページに複数の言語が含まれている場合でも、<html>
属性に指定できる言語は 1 つだけです。lang
をページのメインの言語に設定します。
<html lang="ar,en,fr,pt">...</html>
<html lang="ar">...</html>
リンク
ボタンと同様に、リンクのユーザー補助機能名は主にテキスト コンテンツから取得されます。リンクを作成する際の便利な方法として、「こちら」や「続きを読む」などのあいまいな言葉ではなく、最も意味のあるテキストをリンク自体に含める方法があります。
Check out our guide to web performance <a href="/guide">here</a>.
Check out <a href="/guide">our guide to web performance</a>.
アニメーションがレイアウトをトリガーするかどうかを確認する
transform
以外のものを使用して要素を移動するアニメーションは、遅くなる可能性があります。次の例では、top
と left
をアニメーション化し、transform
を使用して、同じ視覚的な結果を実現しています。
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { top: calc(90vh - 160px); left: calc(90vw - 200px); } }
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { transform: translate(calc(90vw - 200px), calc(90vh - 160px)); } }
次の 2 つの Glitch の例でテストし、DevTools を使用してパフォーマンスを確認できます。
同じマークアップで、padding-top: 56.25%
を aspect-ratio: 16 / 9
に置き換え、aspect-ratio
を指定された比率 width
/ height
に設定できます。
.container { width: 100%; padding-top: 56.25%; }
.container { width: 100%; aspect-ratio: 16 / 9; }
padding-top
ではなく aspect-ratio
を使用すると、より明確になり、通常のスコープ外で何かを行うためにパディング プロパティをオーバーホールする必要がなくなります。
reduce
を使用して一連の Promise を連結しています。とても賢い。しかしこれは、使用しない方がよい「非常にスマートな」コーディングなのです。
上記を非同期関数に変える場合は、つい順次的になってしまいます。
async function logInOrder(urls) { for (const url of urls) { const response = await fetch(url); console.log(await response.text()); } }
function markHandled(...promises) { Promise.allSettled(promises); } async function logInOrder(urls) { // fetch all the URLs in parallel const textPromises = urls.map(async (url) => { const response = await fetch(url); return response.text(); }); markHandled(...textPromises); // log them in sequence for (const textPromise of textPromises) { console.log(await textPromise); } }
reduce
部分は、つまらなくて読み取りやすい標準的な for-loop で置き換えられています。
Houdini カスタム プロパティの作成
カスタム プロパティ(CSS 変数など)を設定する例を次に示します。構文(型)、初期値(フォールバック)、継承ブール値(親から値を継承するかどうか)が追加されています。現在、この操作を行う方法は JavaScript の CSS.registerProperty()
を使用していますが、Chromium 85 以降では、CSS ファイルで @property
構文がサポートされます。
CSS.registerProperty({ name: '--colorPrimary', syntax: '' , initialValue: 'magenta', inherits: false });
@property --colorPrimary { syntax: '' ; initial-value: magenta; inherits: false; }
これで、他の CSS カスタム プロパティと同様に、var(--colorPrimary)
を介して --colorPrimary
にアクセスできるようになりました。ただし、ここでの違いは、--colorPrimary
が文字列として読み取られるだけではないことです。データがあります。
CSS backdrop-filter
は、半透明または透明の要素に 1 つ以上の効果を適用します。以下の画像を例に説明します。

.frosty-glass-pane { backdrop-filter: blur(2px); }

.frosty-glass-pane { opacity: .9; backdrop-filter: blur(2px); }
左側の画像は、backdrop-filter
が使用されていない場合やサポートされていない場合に、重なり合う要素がどのようにレンダリングされるかを示しています。右の画像は、backdrop-filter
を使用してぼかし効果を適用しています。backdrop-filter
に加えて opacity
を使用していることに注意してください。opacity
がないと、ぼかしを適用する対象がありません。opacity
が 1
(完全に不透明)に設定されている場合、背景には影響しません。
ただし、unload
イベントとは異なり、beforeunload
には正当な用途があります。たとえば、ページを離れると保存されていない変更が失われることをユーザーに警告する場合などです。この場合、ユーザーが保存されていない変更を行った場合にのみ beforeunload
リスナーを追加し、保存されていない変更が保存された直後に削除することをおすすめします。
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });
beforeunload
リスナーを追加します。
function beforeUnloadListener(event) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; }; // A function that invokes a callback when the page has unsaved changes. onPageHasUnsavedChanges(() => { window.addEventListener('beforeunload', beforeUnloadListener); }); // A function that invokes a callback when the page's unsaved changes are resolved. onAllChangesSaved(() => { window.removeEventListener('beforeunload', beforeUnloadListener); });
beforeunload
リスナーは必要に応じてのみ追加され(必要ない場合は削除されます)。
Cache-Control: no-store
の使用を最小限に抑える
Cache-Control: no-store
は、ウェブサーバーがレスポンスに設定できる HTTP ヘッダーで、ブラウザにレスポンスを HTTP キャッシュに保存しないように指示します。これは、ログインが必要なページなど、機密性の高いユーザー情報が含まれるリソースに使用する必要があります。
各入力グループ(.fieldset-item
)を含む fieldset
要素は、gap: 1px
を使用して要素間の細い線の境界を作成しています。複雑な境界ソリューションは不要です。
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
自然なグリッドの折り返し
最も複雑なレイアウトは、<main>
と <form>
間の論理レイアウト システムであるマクロ レイアウトになりました。
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
各入力グループ(.fieldset-item
)を含む fieldset
要素は、gap: 1px
を使用して要素間の細い線の境界を作成しています。複雑な境界ソリューションは不要です。
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
タブ <header>
レイアウト
次のレイアウトはほぼ同じです。flex を使用して縦方向の順序付けを作成しています。
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
.snap-indicator
はリンクのグループとともに水平方向に移動する必要があります。このヘッダー レイアウトは、そのステージを設定するために役立ちます。絶対位置の要素は使用しないでください。
ジェントル フレックスは、より正確な中央配置のみの戦略です。place-content: center
とは異なり、中央揃え中に子のボックスサイズが変更されないため、ソフトで優しい配置です。すべてのアイテムが可能な限り慎重に積み重ねられ、中央に配置され、間隔が空けられます。
.gentle-flex {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1ch;
}
- 位置揃え、向き、分散のみを処理
- 編集とメンテナンスが 1 か所で完結
- Gap は、n 個の子要素の間隔を均等に保証します。
- コード行数の最小値
マクロ レイアウトとマイクロ レイアウトの両方に適しています。
用途
gap
は、値として任意の CSS 長さまたは割合を受け入れます。
.gap-example {
display: grid;
gap: 10px;
gap: 2ch;
gap: 5%;
gap: 1em;
gap: 3vmax;
}
Gap には 1 つの長さを渡すことができます。この長さは行と列の両方に使用されます。
.grid { display: grid; gap: 10px; }
.grid { display: grid; row-gap: 10px; column-gap: 10px; }
Gap には 2 つの長さを渡すことができます。これは行と列に使用されます。
.grid { display: grid; gap: 10px 5%; }
.grid { display: grid; row-gap: 10px; column-gap: 5%; }