Z atrybutem lang może być powiązany tylko jeden język. Oznacza to, że atrybut <html>
może mieć tylko 1 język, nawet jeśli na stronie jest kilka języków. Ustaw lang
jako główny język strony.
<html lang="ar,en,fr,pt">...</html>Wiele języków nie jest obsługiwanych.
<html lang="ar">...</html>Ustaw tylko podstawowy język strony. W tym przypadku językiem jest arabski.
Linki
Podobnie jak przyciski, nazwa linku pochodzi głównie z tekstu. Przy tworzeniu linku warto umieścić w nim najistotniejszy fragment tekstu, zamiast używać takich słów jak „tutaj” czy „Czytaj więcej”.
Check out our guide to web performance <a href="/guide">here</a>.
Check out <a href="/guide">our guide to web performance</a>.
Sprawdzanie, czy animacja uruchamia układ
Animacja, która porusza element za pomocą funkcji innego niż transform
, prawdopodobnie będzie wolna.
W poniższym przykładzie taki sam efekt daje animowanie elementów top
i left
oraz 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)); } }
Możesz przetestować ten mechanizm w 2 przykładach Usterek i sprawdzić wydajność za pomocą Narzędzi deweloperskich.
Tymi samymi znacznikami możemy zastąpić: padding-top: 56.25%
elementem aspect-ratio: 16 / 9
, ustawiając aspect-ratio
z określonym współczynnikiem width
/ height
.
.container { width: 100%; padding-top: 56.25%; }
.container { width: 100%; aspect-ratio: 16 / 9; }
Użycie właściwości aspect-ratio
zamiast padding-top
jest znacznie bardziej przejrzyste i nie powoduje modernizacji właściwości dopełnienia na potrzeby wykraczające poza zwykły zakres.
Zgadza się. Używam funkcji reduce
do łączenia sekwencji obietnic. Jestem takim mądrym. Jednak bez takiego kodowania radzisz sobie z bardzo inteligentnym kodowaniem.
Jednak podczas konwertowania powyższych funkcji na funkcję asynchroniczną można chcieć wykonać zbyt sekwencyjną czynność:
async function logInOrder(urls) { for (const url of urls) { const response = await fetch(url); console.log(await response.text()); } }Wygląda znacznie lepiej, ale drugie pobieranie nie rozpocznie się, dopóki pierwsze nie zostanie w pełni odczytane itd. Trwa to znacznie wolniej niż w przykładzie obiecującym, który wykonuje pobieranie równoległe. Na szczęście istnieje idealny środek pośredni.
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); } }W tym przykładzie adresy URL są pobierane i odczytywane równolegle, ale „inteligentny” bit
reduce
został zastąpiony standardowym, nudnym i czytelnym elementem pętli.
Zapisywanie właściwości niestandardowych Houdini
Oto przykład ustawienia właściwości niestandardowej (np. zmiennej CSS), ale ze składnią (typ), wartością początkową (zastępczą) i wartością logiczną dziedziczenia (dziedziczenie wartości z elementu nadrzędnego czy nie). Obecnie można to zrobić za pomocą metody CSS.registerProperty()
w JavaScript, ale w Chromium w wersji 85 i nowszych pliki CSS będą obsługiwać składnię @property
:
CSS.registerProperty({ name: '--colorPrimary', syntax: '', initialValue: 'magenta', inherits: false });
@property --colorPrimary { syntax: ''; initial-value: magenta; inherits: false; }
Teraz możesz uzyskać dostęp do właściwości --colorPrimary
w usłudze var(--colorPrimary)
, tak jak do każdej innej właściwości niestandardowej CSS. Różnica polega jednak na tym, że element --colorPrimary
nie jest tylko odczytywany jako ciąg znaków. Mamy dane!
CSS backdrop-filter
stosuje co najmniej 1 efekt do elementu, który jest półprzezroczysty. Aby to zrozumieć, spójrz na poniższe obrazy.
![Trójkąt nałożony na okrąg. Okrąg nie jest widoczne w trójkącie.](https://web.developers.google.cn/static/examples/image/admin/LOqxvB3qqVkbZBmxMmKS.png?hl=pl)
.frosty-glass-pane { backdrop-filter: blur(2px); }
![Trójkąt nałożony na okrąg. Trójkąt jest półprzezroczysty, przez co można przez niego dostrzec okrąg.](https://web.developers.google.cn/static/examples/image/admin/VbyjpS6Td39E4FudeiVg.png?hl=pl)
.frosty-glass-pane { opacity: .9; backdrop-filter: blur(2px); }
Obraz po lewej stronie pokazuje, jak zostałyby wyrenderowane nakładające się elementy, gdyby elementy backdrop-filter
nie były używane ani obsługiwane. Na obrazie po prawej stronie zastosowano efekt rozmycia za pomocą funkcji backdrop-filter
. Zwróć uwagę, że oprócz backdrop-filter
używa ona opacity
. Bez opacity
nie można byłoby zamazywać. Jeśli zasada opacity
ma ustawienie 1
(pełne nieprzezroczystość), nie będzie to miało żadnego wpływu na tło.
Istnieją jednak dozwolone przypadki użycia właściwości beforeunload
(w przeciwieństwie do zdarzenia unload
). Jeśli na przykład chcesz ostrzec użytkownika, że ma niezapisane zmiany, utraci on dostęp, jeśli opuści stronę. W takim przypadku zalecamy dodanie detektorów beforeunload
tylko wtedy, gdy użytkownik ma niezapisane zmiany, a potem usunięcie ich natychmiast po zapisaniu niezapisanych zmian.
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });Powyższy kod bezwarunkowo dodaje odbiornik
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); });Kod powyżej dodaje odbiornik
beforeunload
tylko wtedy, gdy jest potrzebny (i usuwa go, gdy jest niepotrzebny).
Ogranicz korzystanie z Cache-Control: no-store
Cache-Control: no-store
to nagłówek HTTP, który serwery WWW mogą ustawiać w odpowiedziach, informuje przeglądarkę, że ma nie zapisywać odpowiedzi w żadnej pamięci podręcznej HTTP. Tego formatu należy używać w przypadku zasobów zawierających poufne dane użytkownika, np. stron wymagających logowania.
Element fieldset
, który zawiera każdą grupę danych wejściowych (.fieldset-item
), używa właściwości gap: 1px
do tworzenia linii obramowania między elementami. Brak trudnego rozwiązania granicznego!
.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); } } }
Naturalne zawijanie siatki
Najbardziej złożonym układem był układ makro, czyli układ logiczny między <main>
a <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>
Element fieldset
, który zawiera każdą grupę danych wejściowych (.fieldset-item
), używa właściwości gap: 1px
do tworzenia linii obramowania między elementami. Brak trudnego rozwiązania granicznego!
.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); } } }
Układ kart <header>
Następny układ jest prawie taki sam: do tworzenia kolejności pionowej używam elastycznego.
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
Element .snap-indicator
powinien przemieszczać się wraz z grupą linków w poziomie. Ten układ nagłówka pomaga w ustawieniu tej sceny. Brak elementów w pozycji bezwzględnej.
Gentle Flex to bardziej prawdziwa strategia ukierunkowana tylko na wyśrodkowanie. Jest miękki i delikatny, ponieważ w przeciwieństwie do place-content: center
rozmiar pudełka dla dzieci nie zmienia się podczas wyśrodkowania. Wszystkie elementy są ułożone w stos, wyśrodkowane i rozmieszczone tak delikatnie, jak to możliwe.
.gentle-flex {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1ch;
}
- Obsługa tylko wyrównywania, kierunku i rozkładu
- Zmiany i konserwacja w jednym miejscu
- Luka gwarantuje równe odstępy między n dzieci
- Większość wierszy kodu
Świetnie sprawdza się w przypadku układów makro i mikro.
Wykorzystanie
gap
akceptuje dowolną długość lub percentage CSS jako wartość.
.gap-example {
display: grid;
gap: 10px;
gap: 2ch;
gap: 5%;
gap: 1em;
gap: 3vmax;
}
Luka może mieć 1 długość, która będzie używana zarówno w wierszu, jak i w kolumnie.
.grid { display: grid; gap: 10px; }Ustawianie razy jednocześnie wierszy i kolumn
.grid { display: grid; row-gap: 10px; column-gap: 10px; }
Luki można przekazywać na 2 różne długości, które będą używane w przypadku wiersza i kolumny.
.grid { display: grid; gap: 10px 5%; }Ustawiaj wiersze i kolumny oddzielnie naraz
.grid { display: grid; row-gap: 10px; column-gap: 5%; }