Atribut lang hanya dapat memiliki satu bahasa yang terkait dengannya. Artinya,
atribut <html>
hanya dapat memiliki satu bahasa, meskipun ada beberapa
bahasa di halaman. Tetapkan lang
ke bahasa utama halaman.
<html lang="ar,en,fr,pt">...</html>
<html lang="ar">...</html>
Link
Serupa dengan tombol, link terutama mendapatkan nama yang dapat diakses dari konten teksnya. Trik yang bagus saat membuat link adalah menempatkan bagian teks yang paling bermakna 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 sesuatu selain transform
, cenderung lambat.
Dalam contoh berikut, saya telah mencapai hasil visual yang sama dengan 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 menjelajahi 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 merombak properti padding
untuk melakukan sesuatu di luar cakupan biasanya.
Ya, benar, saya menggunakan reduce
untuk merangkai urutan promise. Saya sangat
pintar. Namun, ini adalah pengkodean sangat cerdas yang sebaiknya tidak Anda gunakan.
Namun, saat mengonversi kode di atas menjadi fungsi asinkron, Anda mungkin tergoda untuk melakukannya terlalu berurutan:
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
"cerdas" diganti dengan for-loop standar, membosankan, dan dapat dibaca.
Menulis properti kustom Houdini
Berikut adalah contoh penetapan properti kustom (misalnya: variabel CSS), tetapi sekarang
dengan sintaksis (jenis), nilai awal (fallback), dan boolean pewarisan (apakah
properti 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 kustom CSS lainnya, melalui
var(--colorPrimary)
. Namun, perbedaannya di sini adalah --colorPrimary
tidak
hanya dibaca sebagai string. Datanya ada!
backdrop-filter
CSS menerapkan satu atau beberapa efek ke elemen yang buram atau transparan. Untuk memahaminya, perhatikan gambar di bawah.

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

.frosty-glass-pane { opacity: .9; backdrop-filter: blur(2px); }
Gambar di sebelah kiri menunjukkan cara elemen yang tumpang-tindih akan dirender jika backdrop-filter
tidak digunakan atau didukung. Gambar di sebelah kanan menerapkan efek pemburaman menggunakan backdrop-filter
. Perhatikan bahwa kode ini menggunakan opacity
selain backdrop-filter
. Tanpa opacity
, tidak akan ada yang akan menerapkan pemburaman. 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 mereka memiliki
perubahan yang belum disimpan dan akan hilang jika mereka keluar dari halaman. Dalam hal ini, sebaiknya
Anda hanya menambahkan pemroses beforeunload
saat pengguna memiliki perubahan
yang belum disimpan, lalu segera menghapusnya setelah perubahan yang belum disimpan disimpan.
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });
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); });
beforeunload
jika diperlukan (dan
menghapusnya jika tidak diperlukan).
Meminimalkan penggunaan Cache-Control: no-store
Cache-Control: no-store
adalah header HTTP yang dapat ditetapkan server web pada respons yang menginstruksikan browser untuk tidak menyimpan respons dalam cache HTTP apa pun. Ini harus digunakan untuk resource yang berisi informasi pengguna sensitif, misalnya halaman di balik login.
Elemen fieldset
, yang berisi setiap grup input (.fieldset-item
), menggunakan gap: 1px
untuk
membuat batas garis rambut di antara elemen. Tidak ada solusi batas 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, 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 batas 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 flex 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 bergerak secara horizontal dengan grup link, dan
tata letak header ini membantu menyiapkan tahap tersebut. Tidak ada elemen yang diposisikan secara mutlak di sini.
Gentle Flex adalah strategi khusus pemusatan yang lebih akurat. Hal ini lembut dan halus, karena
tidak seperti place-content: center
, tidak ada ukuran kotak turunan yang diubah selama
pemusatan. Semua item ditumpuk, dipusatkan, dan diberi spasi sehalus mungkin.
.gentle-flex {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1ch;
}
- Hanya menangani perataan, arah, dan distribusi
- Pengeditan dan pemeliharaan semuanya ada di satu tempat
- Gap menjamin spasi yang sama di antara turunan n
- Sebagian besar baris kode
Cocok untuk tata letak makro dan mikro.
Penggunaan
gap
menerima panjang
atau persentase CSS sebagai nilai.
.gap-example {
display: grid;
gap: 10px;
gap: 2ch;
gap: 5%;
gap: 1em;
gap: 3vmax;
}
Gap dapat diteruskan 1 panjang, yang akan digunakan untuk baris dan kolom.
.grid { display: grid; gap: 10px; }
.grid { display: grid; row-gap: 10px; column-gap: 10px; }
Gap dapat meneruskan 2 panjang, yang akan digunakan untuk baris dan kolom.
.grid { display: grid; gap: 10px 5%; }
.grid { display: grid; row-gap: 10px; column-gap: 5%; }