비교 및 비교 자막

lang 속성에는 하나의 언어만 연결될 수 있습니다. 즉, 페이지에 여러 언어가 있더라도 <html> 속성은 언어를 하나만 가질 수 있습니다. 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 이외의 항목을 사용하여 요소를 이동하는 애니메이션은 속도가 느릴 수 있습니다. 다음 예에서는 topleft를 애니메이션 처리하고 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));
  }
}

다음 두 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를 사용하여 프로미스 시퀀스를 체이닝하고 있습니다. 저는 엄청 똑똑해요. 하지만 약간의 스마트 코딩은 없는 것이 낫습니다.

하지만 위의 함수를 비동기 함수로 변환할 때는 너무 순차적으로 처리하려는 경향이 있을 수 있습니다.

권장하지 않음 - 너무 순차적임
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);
  }
}
이 예시에서는 URL을 가져와 동시에 읽지만 '스마트' reduce 비트는 지루하고 읽기 쉬운 표준 for 루프로 대체됩니다.

Houdini 맞춤 속성 작성

다음은 맞춤 속성 (예: CSS 변수)을 설정하는 예입니다. 그러나 이제 구문 (유형), 초깃값 (대체), 상속 불리언 (상위 요소로부터 값을 상속받는가?)을 사용할 수 있습니다. 현재 JavaScript에서 CSS.registerProperty()를 사용하면 이를 확인할 수 있지만 Chromium 85 이상에서는 CSS 파일에서 @property 문법이 지원됩니다.

별도의 자바스크립트 파일 (Chromium 78)
CSS.registerProperty({
  name: '--colorPrimary',
  syntax: '',
  initialValue: 'magenta',
  inherits: false
});
CSS 파일에 포함됨 (Chromium 85)
@property --colorPrimary {
  syntax: '';
  initial-value: magenta;
  inherits: false;
}

이제 var(--colorPrimary)를 통해 다른 CSS 맞춤 속성과 마찬가지로 --colorPrimary에 액세스할 수 있습니다. 하지만 여기서 차이점은 --colorPrimary이 단순히 문자열로 읽히지 않는다는 점입니다. 데이터가 있습니다.

CSS backdrop-filter은 반투명하거나 투명한 요소에 하나 이상의 효과를 적용합니다. 아래 이미지를 참고하세요.

포그라운드 투명도 없음
원 위에 겹쳐진 삼각형입니다. 원이 삼각형을 통해 볼 수 없습니다.
.frosty-glass-pane {
  backdrop-filter: blur(2px);
}
포그라운드 투명도
원 위에 겹쳐진 삼각형입니다. 삼각형은 반투명해서 원을 통해 볼 수 있습니다.
.frosty-glass-pane {
  opacity: .9;
  backdrop-filter: blur(2px);
}

왼쪽 이미지는 backdrop-filter가 사용되거나 지원되지 않는 경우 겹치는 요소가 어떻게 렌더링되는지 보여줍니다. 오른쪽 이미지는 backdrop-filter를 사용하여 블러 효과를 적용합니다. backdrop-filter 외에 opacity를 사용하는 것을 볼 수 있습니다. opacity가 없으면 블러를 적용할 대상이 없습니다. opacity1 (완전히 불투명)로 설정되면 배경에 영향을 미치지 않습니다.

그러나 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를 사용하여 세로 정렬을 만듭니다.

HTML
<snap-tabs>
  <header>
    <nav></nav>
    <span class="snap-indicator"></span>
  </header>
  <section></section>
</snap-tabs>
CSS
header {
  display: flex;
  flex-direction: column;
}

.snap-indicator는 링크 그룹과 함께 가로로 이동해야 하며 이 헤더 레이아웃은 이러한 단계를 설정하는 데 도움이 됩니다. 여기에는 절대 위치로 배치된 요소가 없습니다.

Gentle Flex는 진정한 센터링전용 전략입니다. place-content: center와 달리 가운데 정렬 중에 하위 요소 상자 크기가 변경되지 않으므로 부드럽고 부드럽습니다. 모든 항목은 최대한 배치되고 중앙에 배치되고 간격이 지정됩니다.

.gentle-flex {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1ch;
}
장점
  • 정렬, 방향, 배포만 처리
  • 한곳에서 수정 및 유지보수
  • 간격이 있으면 하위 요소 n개 간에 동일한 간격이 보장됩니다.
단점
  • 대부분의 코드 줄

매크로 및 마이크로 레이아웃에 모두 훌륭합니다.

사용

gap는 모든 CSS 길이 또는 비율을 값으로 허용합니다.

.gap-example {
  display: grid;
  gap: 10px;
  gap: 2ch;
  gap: 5%;
  gap: 1em;
  gap: 3vmax;
}


간격은 행 및 열 모두에 사용되는 1 길이를 전달할 수 있습니다.

약식
.grid {
  display: grid;
  gap: 10px;
}
행과 열을 한 번에 함께 설정하기
펼침
.grid {
  display: grid;
  row-gap: 10px;
  column-gap: 10px;
}


간격은 행과 열에 사용되는 두 개의 길이를 전달할 수 있습니다.

약식
.grid {
  display: grid;
  gap: 10px 5%;
}
한 번에 행과 열을 개별적으로 설정하기
펼침
.grid {
  display: grid;
  row-gap: 10px;
  column-gap: 5%;
}