Atribut lang hanya dapat memiliki satu bahasa yang terkait dengannya. Artinya,
atribut <html>
hanya dapat memiliki satu bahasa, meskipun ada beberapa
bahasa di halaman. Setel lang
ke bahasa utama halaman.
<html lang="ar,en,fr,pt">...</html>Beberapa bahasa tidak didukung.
<html lang="ar">...</html>Hanya setel bahasa utama halaman. Dalam hal ini, bahasa yang digunakan adalah bahasa Arab.
Link
Serupa dengan tombol, link terutama mendapatkan nama yang dapat diakses dari konten teksnya. Trik yang bagus saat membuat link adalah dengan memasukkan potongan teks yang paling penting ke dalam link itu sendiri, bukan kata pengisi seperti "Di sini" atau "Baca Selengkapnya."
Check out our guide to web performance <a href="/guide">here</a>.
Check out <a href="/guide">our guide to web performance</a>.
Memeriksa apakah animasi memicu tata letak
Animasi yang memindahkan elemen menggunakan selain transform
, kemungkinan akan berjalan lambat.
Pada contoh berikut, saya telah mencapai hasil visual yang sama yang menganimasikan top
dan left
, serta menggunakan 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)); } }
Anda dapat mengujinya dalam dua contoh Glitch berikut, dan mempelajari performa menggunakan DevTools.
Dengan markup yang sama, kita dapat mengganti: padding-top: 56.25%
dengan aspect-ratio: 16 / 9
, menetapkan
aspect-ratio
ke rasio width
/ height
yang ditentukan.
.container { width: 100%; padding-top: 56.25%; }
.container { width: 100%; aspect-ratio: 16 / 9; }
Menggunakan aspect-ratio
, bukan padding-top
, jauh lebih jelas, dan tidak memperbaiki properti padding untuk melakukan sesuatu di luar cakupan biasanya.
Ya, benar, saya menggunakan reduce
untuk merangkai urutan promise. Saya begitu
pintar. Tapi ini adalah coding yang sangat cerdas yang sebaiknya Anda tidak melakukannya.
Namun, saat mengonversi fungsi di atas menjadi fungsi asinkron, Anda mungkin ingin terlalu berurutan:
async function logInOrder(urls) { for (const url of urls) { const response = await fetch(url); console.log(await response.text()); } }Terlihat jauh lebih rapi, tetapi pengambilan kedua saya tidak dimulai hingga pengambilan pertama dibaca sepenuhnya, dan seterusnya. Ini jauh lebih lambat dibandingkan contoh promise yang melakukan pengambilan secara paralel. Untungnya ada jalan tengah yang ideal.
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); } }Dalam contoh ini, URL diambil dan dibaca secara paralel, tetapi bit
reduce
"pintar" diganti dengan for-loop yang standar, membosankan, dan dapat dibaca.
Menulis properti kustom Houdini
Berikut ini contoh penetapan properti kustom (misalnya: variabel CSS), tetapi sekarang
dengan sintaksis (jenis), nilai awal (fallback), dan boolean pewarisan (apakah
mewarisi nilai dari induknya atau tidak?). Cara saat ini untuk melakukannya adalah
melalui CSS.registerProperty()
di JavaScript, tetapi di Chromium 85 dan yang lebih baru, sintaksis
@property
akan didukung di file CSS Anda:
CSS.registerProperty({ name: '--colorPrimary', syntax: '', initialValue: 'magenta', inherits: false });
@property --colorPrimary { syntax: ''; initial-value: magenta; inherits: false; }
Sekarang Anda dapat mengakses --colorPrimary
seperti properti khusus CSS lainnya, melalui
var(--colorPrimary)
. Namun, perbedaannya di sini adalah --colorPrimary
tidak
hanya dibaca sebagai string. Data itu ada!
CSS backdrop-filter
menerapkan satu atau beberapa efek ke elemen yang transparan atau transparan. Untuk memahaminya, perhatikan gambar di bawah ini.
![Segitiga yang tumpang-tindih pada lingkaran. Lingkaran tidak dapat dilihat melalui segitiga.](https://web.dev/static/examples/image/admin/LOqxvB3qqVkbZBmxMmKS.png?hl=id)
.frosty-glass-pane { backdrop-filter: blur(2px); }
![Segitiga yang tumpang-tindih pada lingkaran. Segitiga ini tembus cahaya, sehingga lingkaran dapat dilihat melaluinya.](https://web.dev/static/examples/image/admin/VbyjpS6Td39E4FudeiVg.png?hl=id)
.frosty-glass-pane { opacity: .9; backdrop-filter: blur(2px); }
Gambar di sebelah kiri menunjukkan cara elemen yang tumpang-tindih dirender jika backdrop-filter
tidak digunakan atau didukung. Gambar di sebelah kanan menerapkan efek buram menggunakan backdrop-filter
. Perhatikan bahwa kode ini menggunakan opacity
selain backdrop-filter
. Tanpa opacity
, pemburaman tidak akan ada. Hampir tidak perlu dikatakan bahwa jika opacity
disetel ke 1
(sepenuhnya buram) tidak akan ada efek pada latar belakang.
Namun, tidak seperti peristiwa unload
, ada penggunaan yang sah untuk beforeunload
. Misalnya, saat Anda ingin memperingatkan pengguna bahwa perubahan
belum disimpan akan hilang jika mereka meninggalkan halaman. Dalam hal ini, sebaiknya Anda hanya menambahkan pemroses beforeunload
saat pengguna memiliki perubahan yang belum disimpan, lalu menghapusnya segera setelah perubahan yang belum disimpan disimpan.
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });Kode di atas menambahkan pemroses
beforeunload
tanpa syarat.
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); });Kode di atas hanya menambahkan pemroses
beforeunload
saat diperlukan (dan
menghapusnya jika tidak diperlukan).
Minimalkan penggunaan Cache-Control: no-store
Cache-Control: no-store
adalah server web header HTTP yang dapat ditetapkan pada respons yang menginstruksikan browser untuk tidak menyimpan respons dalam cache HTTP apa pun. Kebijakan ini harus digunakan untuk resource yang berisi informasi pengguna sensitif, misalnya halaman yang memerlukan login.
Elemen fieldset
, yang berisi setiap grup input (.fieldset-item
), menggunakan gap: 1px
untuk
membuat batas garis rambut di antara elemen. Tidak ada solusi perbatasan yang rumit.
.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); } } }
Penggabungan petak alami
Tata letak yang paling kompleks akhirnya menjadi tata letak makro, yaitu sistem tata letak
logis antara <main>
dan <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>
Elemen fieldset
, yang berisi setiap grup input (.fieldset-item
), menggunakan gap: 1px
untuk
membuat batas garis rambut di antara elemen. Tidak ada solusi perbatasan yang rumit.
.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); } } }
Tata letak <header>
tab
Tata letak berikutnya hampir sama: saya menggunakan fleksibilitas untuk membuat pengurutan vertikal.
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
.snap-indicator
harus berpindah secara horizontal bersama grup link, dan
tata letak header ini membantu menetapkan tahap tersebut. Tidak ada elemen yang diposisikan secara mutlak di sini!
Gentle Flex adalah strategi khusus pemusatan yang lebih nyata. Teks ini lembut dan lembut karena
tidak seperti place-content: center
, tidak ada ukuran kotak anak yang berubah selama
pemusatan. Sempurna mungkin, semua item ditumpuk, di tengah, dan diberi jarak.
.gentle-flex {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1ch;
}
- Hanya menangani perataan, arah, dan distribusi
- Semua pengeditan dan pemeliharaan ada di satu tempat
- Kesenjangan menjamin jarak yang sama di antara n turunan
- Sebagian besar baris kode
Sangat cocok untuk tata letak makro dan mikro.
Penggunaan
gap
menerima semua panjang
atau persentase CSS sebagai nilai.
.gap-example {
display: grid;
gap: 10px;
gap: 2ch;
gap: 5%;
gap: 1em;
gap: 3vmax;
}
Celah dapat diteruskan 1 panjang, yang akan digunakan untuk baris dan kolom.
.grid { display: grid; gap: 10px; }Menetapkan baris dan kolom bersama-sama sekaligus
.grid { display: grid; row-gap: 10px; column-gap: 10px; }
Celah dapat dilewati 2 panjang, yang akan digunakan untuk baris dan kolom.
.grid { display: grid; gap: 10px 5%; }Menetapkan baris dan kolom secara terpisah sekaligus
.grid { display: grid; row-gap: 10px; column-gap: 5%; }