2022년 CSS 현황

Google IO 2022에서 소개된 현재와 미래의 웹 스타일 지정 기능에 더해 몇 가지 추가 기능이 있습니다.

2022년은 14가지 기능을 구현하기 위한 공동 목표를 세우고 기능과 협력 브라우저 기능 출시 모두에서 CSS의 가장 중요한 해가 될 예정입니다.

개요

이 게시물은 Google IO 2022에서 진행된 강연의 기사 형식입니다. 각 기능에 관한 심층 가이드가 아니라 관심을 끌기 위한 소개 및 간략한 개요로, 심층적인 내용보다는 폭넓은 내용을 제공합니다. 관심이 생겼다면 섹션 끝에 있는 리소스 링크에서 자세한 내용을 확인하세요.

목차

아래 목록을 사용하여 관심 있는 주제로 이동하세요.

브라우저 호환성

이렇게 많은 CSS 기능이 공동 출시되도록 설정된 주된 이유는 상호 운용성 2022의 노력 때문입니다. 상호 운용성 작업을 연구하기 전에 Compat 2021의 작업을 살펴보는 것이 중요합니다.

Compat 2021

설문조사를 통한 개발자 의견을 바탕으로 2021년의 목표는 현재 기능을 안정화하고 테스트 모음을 개선하며 다음 5가지 기능에 대한 브라우저의 통과 점수를 높이는 것이었습니다.

  1. sticky 배치
  2. aspect-ratio 크기 조정
  3. flex 레이아웃
  4. grid 레이아웃
  5. transform 위치 지정 및 애니메이션

전반적인 테스트 점수가 올라가 안정성과 신뢰성이 향상되었습니다. 수상팀에 축하의 인사를 전합니다.

상호 운용성 2022

올해 브라우저는 함께 모여 작업할 기능과 우선순위를 논의하고 협력했습니다. 개발자를 위해 다음과 같은 웹 기능을 제공할 계획이었습니다.

  1. @layer
  2. 색상 공간 및 함수
  3. 억제
  4. <dialog>
  5. 양식 호환성
  6. 스크롤
  7. 서브 그리드
  8. 서체
  9. 표시 영역 단위
  10. 웹 호환성

흥미롭고 야심 찬 계획이니 펼쳐질 모습을 기대하고 있습니다.

2022년의 신규 업데이트

당연히 Interop 2022 작업은 CSS 2022의 상태에 큰 영향을 미칩니다.

계단식 레이어

브라우저 지원

  • Chrome: 99.
  • Edge: 99.
  • Firefox: 97.
  • Safari 15.4.

소스

@layer 이전에는 로드된 스타일시트의 발견 순서가 매우 중요했습니다. 마지막으로 로드된 스타일이 이전에 로드된 스타일을 덮어쓸 수 있기 때문입니다. 그 결과 개발자가 덜 중요한 스타일을 먼저 로드하고 나중에 더 중요한 스타일을 로드해야 하는 엔트리 스타일시트를 세심하게 관리할 수 있었습니다. 개발자가 이러한 중요성을 관리할 수 있도록 지원하는 전체적인 방법론(예: ITCSS)이 있습니다.

@layer를 사용하면 항목 파일이 레이어와 순서를 미리 정의할 수 있습니다. 그런 다음 스타일이 로드되거나 정의될 때 스타일을 레이어 내에 배치하여 스타일 재정의 중요도를 보존할 수 있지만 정교하게 관리되는 로드 조정은 필요하지 않습니다.

이 동영상은 정의된 캐스케이드 레이어를 통해 필요에 따라 캐스케이드를 유지하면서 보다 자유롭고 자유로운 스타일 작성 및 로드 프로세스를 허용하는 방법을 보여줍니다.

Chrome DevTools는 어떤 레이어에서 어떤 스타일이 오는지 시각화하는 데 도움이 됩니다.

Chrome Devtools의 스타일 사이드바 스크린샷으로, 새 레이어 그룹 내에 스타일이 표시되는 방식을 강조 표시합니다.

리소스

서브 그리드

브라우저 지원

  • Chrome: 117
  • Edge: 117.
  • Firefox: 71
  • Safari: 16

소스

subgrid 이전에는 다른 그리드 내의 그리드가 상위 셀이나 그리드 선에 정렬될 수 없었습니다. 각 그리드 레이아웃은 고유했습니다. 많은 디자이너가 전체 디자인 위에 단일 그리드를 배치하고 그 안에서 항목을 지속적으로 정렬합니다. 이는 CSS로는 불가능합니다.

subgrid 후에 그리드의 하위 요소는 상위 요소의 열이나 행을 자신의 것으로 채택하고 자신 또는 하위 요소를 이에 맞게 정렬할 수 있습니다.

다음 데모에서 body 요소는 3개의 열로 구성된 기본 그리드를 만듭니다. 가운데 열을 main라고 하고, 왼쪽과 오른쪽 열의 선 이름을 지정 fullbleed합니다. 그런 다음 본문의 각 요소인 <nav><main>grid-template-columns: subgrid를 설정하여 본문에서 이름이 지정된 선을 채택합니다.

​​body {
  display: grid;
  grid-template-columns:
    [fullbleed-start]
    auto [main-start] min(90%, 60ch) [main-end] auto
    [fullbleed-end]
  ;
}

body > * {
  display: grid;
  grid-template-columns: subgrid;
}

마지막으로 <nav> 또는 <main>의 하위 요소는 fullbleedmain 열과 선을 사용하여 정렬하거나 크기를 조절할 수 있습니다.

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

Devtools를 사용하면 선과 하위 그리드를 볼 수 있습니다(현재 Firefox만 해당). 다음 이미지에서는 상위 그리드와 하위 그리드가 겹쳐져 있습니다. 이제 디자이너가 레이아웃을 생각한 방식과 비슷해졌습니다.

Chrome DevTools 그리드 오버레이 도구를 사용하여 CSS로 정의된 선을 보여주는 하위 그리드 데모의 스크린샷

devtools의 요소 패널에서 어떤 요소가 그리드 및 서브그리드인지 확인할 수 있으며, 이는 레이아웃을 디버깅하거나 확인하는 데 매우 유용합니다.

그리드 또는 서브 그리드 레이아웃이 있는 요소에 라벨이 지정된 Chrome Devtools Elements 패널의 스크린샷
Firefox Devtools의 스크린샷

리소스

컨테이너 쿼리

브라우저 지원

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16

소스

@container 이전에는 웹페이지의 요소가 전체 표시 영역의 크기에만 반응할 수 있었습니다. 이는 매크로 레이아웃에는 좋지만 외부 컨테이너가 전체 뷰포트가 아닌 마이크로 레이아웃의 경우 레이아웃이 적절하게 조정될 수 없습니다.

@container 후에 요소는 상위 컨테이너 크기나 스타일에 응답할 수 있습니다. 유일한 단점은 컨테이너가 가능한 쿼리 타겟으로 자신을 선언해야 한다는 점입니다. 이는 큰 이점을 얻기 위한 작은 요구사항입니다.

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

이러한 스타일을 사용하면 다음 동영상의 월, 화, 수, 목, 금 열을 이벤트 요소로 쿼리할 수 있습니다.

데모 Una Kravets

다음은 calendar-day 컨테이너의 크기를 쿼리한 다음 레이아웃과 글꼴 크기를 조정하는 CSS입니다.

@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}

다음은 또 다른 예입니다. 한 권의 도서 구성요소가 드래그된 열의 사용 가능한 공간에 맞게 조정됩니다.

데모 Max Böck

유나는 상황을 새로운 응답형으로 평가한 것이 맞습니다. @container를 사용할 때는 흥미롭고 의미 있는 디자인 결정을 많이 내려야 합니다.

리소스

accent-color

브라우저 지원

  • Chrome: 93.
  • Edge: 93.
  • Firefox: 92.
  • Safari 15.4.

소스

accent-color 이전에는 브랜드와 일치하는 색상의 양식을 만들려면 시간이 지남에 따라 관리하기 어려운 복잡한 라이브러리 또는 CSS 솔루션을 사용해야 했습니다. 모든 옵션을 제공하고 접근성을 포함했으면 좋겠지만, 내장 구성요소를 사용할지 아니면 자체 구성요소를 채택할지 계속 선택하는 것은 지루해집니다.

accent-color 뒤에 CSS 한 줄을 추가하면 내장 구성요소에 브랜드 색상이 적용됩니다. 브라우저는 색조 외에도 구성요소의 보조 부분에 적절한 대비 색상을 지능적으로 선택하고 시스템 색 구성표(밝은 색 또는 어두운 색)에 맞게 조정합니다.

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

밝은 강조 표시 HTML 요소와 어두운 강조 표시 HTML 요소를 나란히 비교합니다.

accent-color에 관해 자세히 알아보려면 이 유용한 CSS 속성의 더 많은 측면을 살펴보는 web.dev의 게시물을 확인하세요.

리소스

색상 수준 4 및 5

지난 수십 년간 웹은 sRGB의 지배를 받았지만 OLED 또는 QLED 화면이 사전 장착된 고화질 디스플레이와 휴대기기의 확장되는 디지털 세계에서는 sRGB로는 충분하지 않습니다. 또한 사용자 환경설정에 맞게 조정되는 동적 페이지가 요구되며, 색 관리는 디자이너, 디자인 시스템, 코드 유지관리자에게 점점 더 큰 관심을 두고 있습니다.

2022년에는 그렇지 않습니다. CSS에는 여러 가지 새로운 색상 함수와 공간이 있습니다. - 디스플레이의 HD 색상 기능에 도달하는 색상 - 인텐트와 일치하는 색상 공간(예: 지각적 균일성) - 보간 결과를 크게 변경하는 그라데이션의 색상 공간 - 색상 혼합 및 대비, 작업 공간 선택에 도움이 되는 색상 함수

이러한 모든 색상 기능이 도입되기 전에는 디자인 시스템이 적절한 대비 색상을 사전 계산하고 적절히 선명한 팔레트를 보장해야 했으며, 이때 프리프로세서 또는 JavaScript가 많은 작업을 처리했습니다.

이러한 모든 색상 기능을 사용하면 브라우저와 CSS가 모든 작업을 동적으로 적시에 처리할 수 있습니다. 테마 설정과 데이터 시각화 색상을 사용 설정하기 위해 사용자에게 많은 KB의 CSS 및 JavaScript를 전송하는 대신 CSS는 조정 및 계산을 수행할 수 있습니다. 또한 CSS는 사용 전에 지원을 확인하거나 대체를 적절하게 처리할 수 있습니다.

@media (dynamic-range: high) {
  .neon-pink {
    --neon-glow: color(display-p3 1 0 1);
  }
}

@supports (color: lab(0% 0 0)) {
  .neon-pink {
    --neon-glow: lab(150% 160 0);
  }
}

hwb()

브라우저 지원

  • Chrome: 101.
  • Edge: 101.
  • Firefox: 96.
  • Safari: 15

소스

HWB는 색조, 흰색, 검은색을 나타냅니다. 색조와 밝게 하거나 어둡게 하는 흰색 또는 검은색의 양일 뿐이므로 인간 친화적인 색상 표현 방법으로 표시됩니다. 색상을 흰색 또는 검은색과 혼합하는 아티스트는 이 색상 문법 추가 기능을 유용하게 활용할 수 있습니다.

이 색상 함수를 사용하면 HSL 및 RGB와 마찬가지로 sRGB 색상 공간의 색상이 생성됩니다. 2022년의 새로운 점은 새로운 색상이 제공되는 것이 아니라 문법과 멘탈 모델을 좋아하는 사용자가 일부 작업을 더 쉽게 할 수 있다는 점입니다.

리소스

색상 공간

색상이 표현되는 방식은 색상 공간으로 이루어집니다. 각 색상 공간은 색상 작업을 위한 다양한 기능과 장단점을 제공합니다. 어떤 사람은 밝은 색상을 모두 모으기도 하고, 어떤 사람은 밝기를 기준으로 먼저 색상을 정렬하기도 합니다.

2022년 CSS는 디자이너와 개발자가 색상을 표시, 선택, 혼합하는 데 도움이 되는 고유한 기능을 갖춘 10개의 새로운 색상 공간을 제공할 예정입니다. 이전에는 sRGB가 색상을 처리하는 유일한 옵션이었지만 이제 CSS를 사용하면 새로운 잠재력과 새로운 기본 색상 공간인 LCH를 활용할 수 있습니다.

color-mix()

브라우저 지원

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

소스

color-mix() 이전에는 개발자와 디자이너가 브라우저에서 색상을 보기 전에 색상을 혼합하기 위해 Sass와 같은 전처리기가 필요했습니다. 또한 대부분의 색상 믹싱 함수는 믹싱을 실행할 색 공간을 지정하는 옵션을 제공하지 않았기 때문에 때로는 혼란스러운 결과가 발생했습니다.

color-mix() 이후 개발자와 디자이너는 빌드 프로세스를 실행하거나 JavaScript를 포함하지 않고도 브라우저에서 다른 모든 스타일과 함께 색상을 혼합할 수 있습니다. 또한 믹싱을 실행할 색 공간을 지정하거나 LCH의 기본 믹싱 색 공간을 사용할 수도 있습니다.

브랜드 색상이 기본으로 사용되며 이를 기반으로 대안이 생성됩니다(예: 마우스 오버 스타일의 더 밝은 색상 또는 더 어두운 색상). color-mix()를 사용하면 다음과 같이 표시됩니다.

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}

이러한 색상을 srgb와 같은 다른 색상 공간에서 혼합하려면 다음과 같이 변경합니다.

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

다음은 color-mix()를 사용한 테마 설정 데모입니다. 브랜드 색상을 변경해 보고 테마 업데이트를 확인해 보세요.

2022년에는 스타일시트에서 다양한 색상 공간의 색상을 혼합해 보세요.

리소스

color-contrast()

브라우저 지원

  • Chrome: 지원되지 않음
  • Edge: 지원되지 않음
  • Firefox: 지원되지 않음
  • Safari: 플래그 뒤에 있습니다.

소스

color-contrast() 이전에는 스타일시트 작성자가 접근 가능한 색상을 미리 알아야 했습니다. 팔레트는 색상 견본에 검은색 또는 흰색 텍스트를 표시하여 색상 시스템 사용자에게 해당 견본과 적절하게 대비되는 텍스트 색상을 나타내는 경우가 많습니다.

14가지 색상과 텍스트에 적합한 흰색 또는 검은색 대비 색상을 보여주는 Material 팔레트 3개의 스크린샷
2014 Material Design 색상 팔레트의 예

color-contrast() 후에는 스타일시트 작성자가 작업을 완전히 브라우저에 오프로드할 수 있습니다. 브라우저를 사용하여 검은색 또는 흰색 색상을 자동으로 선택할 수 있을 뿐만 아니라 디자인 시스템에 적합한 색상 목록을 제공하고 원하는 대비율을 통과하는 첫 번째 색상을 선택하도록 할 수도 있습니다.

다음은 견본 색상을 기반으로 브라우저에서 텍스트 색상을 자동으로 선택하는 HWB 색상 팔레트 세트 데모의 스크린샷입니다.

브라우저에 따라 각 팔레트에 밝은 텍스트와 어두운 텍스트가 다르게 페어링된 HWB 데모의 스크린샷입니다.
데모 사용해 보기

구문의 기본은 다음과 같습니다. 여기서 회색이 함수에 전달되고 브라우저는 검은색과 흰색 중 어느 쪽이 가장 대비가 높은지 결정합니다.

color: color-contrast(gray);

이 함수는 색상 목록으로 맞춤설정할 수도 있으며, 이 목록에서 선택한 항목 중 가장 높은 대비 색상을 선택합니다.

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

마지막으로, 목록에서 가장 대비되는 색상을 선택하지 않는 것이 바람직한 경우 타겟 대비율을 제공할 수 있으며 이를 전달할 첫 번째 색상이 선택됩니다.

color: color-contrast(
  var(--bg-blue-1)
  vs
  var(--text-lightest), var(--text-light), var(--text-subdued)
  to AA /* 4.5 could also be passed */
);

이 함수는 텍스트 색상 외에도 더 많은 용도로 사용할 수 있지만, 텍스트 색상이 주된 사용 사례일 것으로 예상됩니다. 적절한 대비 색상 선택이 CSS 언어 자체에 내장되면 접근성이 높고 읽기 쉬운 인터페이스를 제공하는 것이 얼마나 쉬워질지 생각해 보세요.

리소스

상대 색상 구문

브라우저 지원

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113
  • Safari: 15

소스

상대 색상 문법 이전에는 색상을 계산하고 조정하려면 색상 채널을 맞춤 속성에 개별적으로 배치해야 했습니다. 이 제한으로 인해 HSL은 색상을 조작하는 기본 색상 함수가 되었습니다. 색조, 채도, 밝기를 모두 calc()로 간단하게 조정할 수 있기 때문입니다.

상대 색상 구문 이후에는 어떤 공간에든 모든 색상을 한 줄의 CSS로 해체, 수정, 색상으로 반환할 수 있습니다. HSL에 더 이상 제한이 없습니다. 원하는 색상 공간에서 조작할 수 있으며 이를 용이하게 하기 위해 더 적은 수의 맞춤 속성을 만들어야 합니다.

다음 문법 예에서는 기본 16진수가 제공되고 이를 기준으로 두 가지 새 색상이 생성됩니다. 첫 번째 색상 --absolute-change는 기본 색상에서 LCH로 새 색상을 만든 다음 기본 색상의 밝기를 75%로 대체하여 채도(c)와 색조(h)를 유지합니다. 두 번째 색상 --relative-change는 기본 색상에서 LCH로 새 색상을 만들지만 이번에는 채도(c)를 20% 줄입니다.

.relative-color-syntax {
  --color: #0af;
  --absolute-change: lch(from var(--color) 75% c h);
  --relative-change: lch(from var(--color) l calc(c-20%) h);
}

색상을 혼합하는 것과 비슷하지만 혼합하는 것보다 변경과 더 유사합니다. 다른 색상에서 색상을 전송하여 사용된 색상 함수의 이름으로 지정된 세 가지 채널 값에 액세스하고 이러한 채널을 조정할 수 있습니다. 전체적으로 이는 매우 멋지고 강력한 색상 구문입니다.

다음 데모에서는 상대 색상 문법을 사용하여 기본 색상의 밝은 변형과 어두운 변형을 만들고 color-contrast()를 사용하여 라벨의 대비가 적절하도록 했습니다.

열이 3개인 스크린샷으로, 각 열이 가운데 열보다 어둡거나 밝습니다.
데모 사용해 보기

이 함수는 색상 팔레트 생성에도 사용할 수 있습니다. 다음은 제공된 기본 색상에서 전체 팔레트가 생성되는 데모입니다. 이 CSS 세트 하나로 모든 다양한 팔레트를 지원하며 각 팔레트는 서로 다른 기반을 제공합니다. 보너스로, LCH를 사용했으므로 팔레트가 지각적으로 얼마나 균일한지 확인해 보세요. 이 색상 공간 덕분에 핫 스팟이나 다크 스팟이 보이지 않습니다.

:root {
  --_color-base: #339af0;

  --color-0:  lch(from var(--_color-base) 98% 10 h);
  --color-1:  lch(from var(--_color-base) 93% 20 h);
  --color-2:  lch(from var(--_color-base) 85% 40 h);
  --color-3:  lch(from var(--_color-base) 75% 46 h);
  --color-4:  lch(from var(--_color-base) 66% 51 h);
  --color-5:  lch(from var(--_color-base) 61% 52 h);
  --color-6:  lch(from var(--_color-base) 55% 57 h);
  --color-7:  lch(from var(--_color-base) 49% 58 h);
  --color-8:  lch(from var(--_color-base) 43% 55 h);
  --color-9:  lch(from var(--_color-base) 39% 52 h);
  --color-10: lch(from var(--_color-base) 32% 48 h);
  --color-11: lch(from var(--_color-base) 25% 45 h);
  --color-12: lch(from var(--_color-base) 17% 40 h);
  --color-13: lch(from var(--_color-base) 10% 30 h);
  --color-14: lch(from var(--_color-base) 5% 20 h);
  --color-15: lch(from var(--_color-base) 1% 5 h);
}
모두 CSS로 동적으로 생성된 15개의 팔레트 스크린샷
데모 사용해 보기

이제 색상 공간과 다양한 색상 함수가 각각의 장단점을 고려하여 다양한 목적으로 사용될 수 있는 방법을 이해하셨기를 바랍니다.

리소스

그라디언트 색상 공간

그라데이션 색상 공간 이전에는 sRGB가 사용되는 기본 색상 공간이었습니다. sRGB는 일반적으로 안정적이지만 회색 비활성 영역과 같은 약점이 있습니다.

녹청색에서 딥핑크색까지 그리드에 있는 4개의 그라데이션 LCH와 LAB는 좀 더 일관된 생동감을 보이므로 sRGB는 중간에서 약간 채도가 낮아집니다.

그라디언트 색공간 뒤에 브라우저에 색상 보간에 사용할 색공간을 지정합니다. 이를 통해 개발자와 디자이너는 원하는 그라데이션을 선택할 수 있습니다. 기본 색상 공간도 sRGB 대신 LCH로 변경됩니다.

구문 추가는 그라데이션 방향 뒤에 적용되며 새 in 구문을 사용하며 선택사항입니다.

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

다음은 흑백의 기본적이고 필수적인 그라데이션입니다. 각 색상 공간에서 결과 범위를 확인합니다. 어떤 것은 다른 것보다 더 빨리 진한 검은색이 되며, 어떤 것은 너무 늦게 흰색으로 변합니다.

검은색과 흰색을 비교하는 11색 공간

다음 예에서는 검은색이 파란색으로 전환됩니다. 그라데이션의 알려진 문제 공간이기 때문입니다. 대부분의 색 공간은 색상 보간 중에 또는 색상이 색 공간 내에서 A 지점에서 B 지점으로 이동할 때 보라색으로 변합니다. 그라데이션은 A 지점에서 B 지점으로 직선을 그리므로 색상 공간의 모양에 따라 경로가 지나가는 중간에 있는 중지점이 크게 달라집니다.

파란색과 검은색을 비교하는 11가지 색상 공간

자세한 내용, 예시, 의견은 이 트위터 대화목록을 참고하세요.

리소스

inert

브라우저 지원

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 112
  • Safari: 15.5

소스

inert 이전에는 즉각적인 주의가 필요한 페이지 또는 앱 영역으로 사용자의 포커스를 유도하는 것이 좋았습니다. 이러한 유도 포커스 전략은 개발자가 대화형 공간에 포커스를 배치하고 포커스 변경 이벤트를 수신 대기하며 포커스가 대화형 공간을 벗어나면 강제로 다시 들어가기 때문에 포커스 트래핑이라고 하는 것입니다. 키보드나 스크린 리더를 사용하는 사용자는 작업이 완료된 후에만 다음 단계로 이동할 수 있도록 대화형 스페이스로 다시 안내됩니다.

inert 이후에는 페이지나 앱의 전체 섹션을 고정하거나 보호할 수 있으므로 트래핑이 필요하지 않습니다. 문서의 이러한 부분이 비활성 상태인 동안에는 클릭 및 포커스 변경 시도를 사용할 수 없습니다. 이를 함정이라기보다는 가드로 생각할 수도 있습니다. 즉, inert은 사용자가 다른 장소를 사용할 수 없게 만드는 것이 아니라 어딘가에 머무르게 하는 데 관심이 없습니다.

JavaScript alert() 함수가 좋은 예입니다.

웹사이트가 대화형으로 표시된 후 alert()가 호출되고 페이지가 더 이상 활성 상태가 아닙니다.

이전 동영상에서 alert()가 호출될 때까지 마우스와 키보드로 페이지에 액세스할 수 있었던 방법을 살펴보세요. 알림 대화상자 팝업이 표시되면 나머지 페이지가 정지되었습니다(inert). 사용자의 포커스는 알림 대화상자 내에 배치되며 다른 곳으로 이동할 수 없습니다. 사용자가 알림 함수 요청과 상호작용하여 완료하면 페이지가 다시 대화형이 됩니다. inert를 사용하면 개발자가 이와 동일한 안내식 포커스 환경을 쉽게 구현할 수 있습니다.

다음은 작동 방식을 보여주는 작은 코드 샘플입니다.

<body>
  <div class="modal">
    <h2>Modal Title</h2>
    <p>...<p>
    <button>Save</button>
    <button>Discard</button>
  </div>
  <main inert>
    <!-- cannot be keyboard focused or clicked -->
  </main>
</body>

대화상자가 좋은 예이지만 inert는 슬라이드 아웃 측면 메뉴 사용자 환경과 같은 작업에도 유용합니다. 사용자가 측면 메뉴를 슬라이드 아웃하면 마우스나 키보드가 그 뒤에 있는 페이지와 상호작용할 수 있도록 허용해서는 안 됩니다. 이는 사용자에게 약간 까다롭습니다. 대신 측면 메뉴가 표시될 때 페이지를 비활성화합니다. 이제 사용자는 측면 메뉴를 닫거나 측면 메뉴 내에서 탐색해야 하며 메뉴가 열려 있는 페이지의 다른 곳으로 이동하지 않습니다.

리소스

COLRv1 글꼴

COLRv1 글꼴 이전에는 그라데이션과 내장 색상 및 효과가 있는 글꼴의 오픈 형식인 OT-SVG 글꼴이 웹에 있었습니다. 이러한 문자는 매우 커질 수 있고 텍스트를 수정할 수 있었지만 맞춤설정할 수 있는 범위는 그리 많지 않았습니다.

COLRv1 글꼴 이후 웹은 사용 사례별로 글꼴을 맞춤설정하거나 브랜드에 맞추기 위한 매개변수를 허용하는 풋프린트가 더 작고, 벡터 확장과 재배치 가능하고, 그라데이션이 적용되고, 혼합 모드 기반 글꼴이 됩니다.

COLRv1 글꼴이 더 선명하고 작다는 것을 보여주는 비교 시각화 및 막대 그래프
https://developer.chrome.com/blog/colrv1-fonts/에서 가져온 이미지

다음은 그림 이모티콘에 관한 Chrome 개발자 블로그 게시물의 예입니다. 그림 이모티콘의 글꼴 크기를 조정하면 선명도가 유지되지 않는 것을 눈치채셨을 수도 있습니다. 벡터 아트가 아닌 이미지입니다. 애플리케이션에서 그림 이모티콘이 사용될 때는 종종 더 높은 품질의 애셋으로 교체됩니다. COLRv1 글꼴을 사용하면 그림 이모티콘이 벡터로 표시되어 아름답습니다.

아이콘 글꼴은 이 형식을 사용하여 맞춤 듀오톤 색상 팔레트 등을 제공하는 등 놀라운 작업을 할 수 있습니다. COLRv1 글꼴을 로드하는 방법은 다른 글꼴 파일과 동일합니다.

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

COLRv1 글꼴 맞춤설정은 나중에 참조할 수 있도록 맞춤설정 옵션 집합을 번들로 그룹화하고 이름을 지정하는 특수 CSS 규칙인 @font-palette-values를 사용하여 실행됩니다. 커스텀 속성과 마찬가지로 --로 시작하는 커스텀 이름을 지정하는 방법을 확인하세요.

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

--colorized를 맞춤설정의 별칭으로 사용했으므로 마지막 단계는 색상 글꼴 모음을 사용하는 요소에 팔레트를 적용하는 것입니다.

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
DUNE이라는 단어가 포함된 Bungee Spice 글꼴의 스크린샷
맞춤 색상으로 표시된 Bungee Spice 글꼴, 출처: https://developer.chrome.com/blog/colrv1-fonts/

점점 더 많은 다양한 글꼴과 색상 글꼴이 제공되면서 웹 서체는 풍부한 맞춤설정과 창의적인 표현을 향해 나아가고 있습니다.

리소스

표시 영역 단위

기기 화면, 브라우저 창, iframe이 모두 서로 다른 뷰포트를 갖는 방식을 보여주는 그래픽

새 표시 영역 변형이 도입되기 전에는 웹에서 표시 영역을 맞추는 데 도움이 되는 실제 단위를 제공했습니다. 각각 높이, 너비, 최소 크기 (vmin), 가장 큰 변 (vmax)에 관한 것이었습니다. 이는 많은 작업에 효과적이었지만 모바일 브라우저로 인해 복잡성이 도입되었습니다.

모바일에서 페이지를 로드하면 URL이 포함된 상태 표시줄이 표시되며 이 표시줄은 일부 뷰포트 공간을 사용합니다. 몇 초 후 상호작용이 이루어지면 상태 표시줄이 밀려나 사용자에게 더 큰 뷰포트 환경을 제공할 수 있습니다. 하지만 이 막대가 슬라이드 아웃되면 표시 영역 높이가 변경되고 모든 vh 단위는 타겟 크기가 변경될 때마다 이동하고 크기가 조절됩니다. 나중에 vh 단위는 휴대기기에서 불편한 시각적 레이아웃 문제를 일으키고 있었기 때문에 사용할 두 가지 표시 영역 크기 중 어떤 크기를 사용할지 결정해야 했습니다. vh가 항상 가장 큰 표시 영역을 나타내는 것으로 확인되었습니다.

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

새 표시 영역 변형이 도입되면서 작은, 큰, 동적 표시 영역 단위를 사용할 수 있게 되었으며, 실제 단위에 논리적 등가 항목이 추가되었습니다. 개발자와 디자이너가 특정 시나리오에 사용할 단위를 선택할 수 있도록 하는 것이 목표입니다. 상태 표시줄이 사라질 때 약간의 불편한 레이아웃 전환이 발생해도 괜찮을 수 있으므로 dvh(동적 표시 영역 높이)를 걱정 없이 사용할 수 있습니다.

DVH, LVH, SVH를 설명하는 데 도움이 되는 휴대전화 3대의 그래픽 DVH 예시 휴대전화에는 세로선이 두 개 있습니다. 하나는 검색창 하단과 표시 영역 하단 사이에 있고 다른 하나는 검색창 위 (시스템 상태 표시줄 아래) 표시 영역 아래쪽에 있으며 DVH가 두 길이 중 하나가 될 수 있음을 보여줍니다. LVH는 기기 상태 표시줄 하단과 휴대전화 표시 영역의 버튼 사이에 줄로 가운데에 표시됩니다. 마지막은 브라우저 검색창 하단에서 뷰포트 하단까지의 선을 보여주는 SVH 단위 예시입니다.

다음은 새 뷰포트 변형으로 사용할 수 있는 모든 새 뷰포트 단위 옵션의 전체 목록입니다.

높이 표시 영역 단위
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
너비 뷰포트 단위
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
가장 작은 표시 영역 측면 단위
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
가장 큰 뷰포트 측면 단위
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

이를 통해 개발자와 디자이너가 뷰포트 반응형 디자인을 구현하는 데 필요한 유연성을 얻을 수 있기를 바랍니다.

리소스

:has()

브라우저 지원

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4

소스

:has() 이전에는 선택자주제가 항상 끝에 있었습니다. 예를 들어 이 선택기의 주제는 목록 항목 ul > li입니다. 가상 선택기는 선택기를 변경할 수 있지만 ul > li:hover 또는 ul > li:not(.selected)과 같은 주제는 변경하지 않습니다.

:has() 이후에는 요소 트리에서 더 높은 수준의 주제가 하위 요소에 관한 쿼리(ul:has(> li))를 제공하면서 주제로 유지될 수 있습니다. 이 경우 선택자의 주제가 상위 요소가 되므로 :has()가 '상위 요소 선택자'라는 일반적인 이름을 얻게 된 이유를 쉽게 이해할 수 있습니다.

다음은 클래스 .parent가 주제이지만 하위 요소에 .child 클래스가 있는 경우에만 선택되는 기본 문법 예입니다.

.parent:has(.child) {...}

다음은 <section> 요소가 제목이지만 선택기는 하위 요소 중 하나에 :focus-visible가 있는 경우에만 일치하는 예입니다.

section:has(*:focus-visible) {...}

더 실용적인 사용 사례가 명확해지면 :has() 선택기가 훌륭한 유틸리티가 됩니다. 예를 들어 현재 이미지를 래핑할 때 <a> 태그를 선택할 수 없으므로 해당 사용 사례에서 앵커 태그에 스타일을 변경하는 방법을 가르치기 어렵습니다. :has()를 사용하면 가능합니다.

a:has(> img) {...}

모두 :has()가 상위 선택기처럼 보이는 예입니다. <figure> 요소 내 이미지의 사용 사례를 고려하고 그림에 <figcaption>가 있는 경우 이미지의 스타일을 조정합니다. 다음 예에서는 그림 설명이 있는 그림이 선택된 후 해당 컨텍스트 내 이미지가 선택됩니다. 타겟팅하는 주제가 그림이 아닌 이미지이므로 :has()가 사용되며 주제를 변경하지 않습니다.

figure:has(figcaption) img {...}

조합은 무궁무진합니다. :has()수량 쿼리와 결합하고 하위 요소 수를 기반으로 CSS 그리드 레이아웃을 조정합니다. :has()대화형 가상 클래스 상태와 결합하여 새롭고 창의적인 방식으로 응답하는 애플리케이션을 만듭니다.

지원 여부를 확인하는 것은 브라우저가 구문을 사용하기 전에 이를 이해하는지 테스트하는 @supportsselector() 함수를 사용하면 간단합니다.

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

리소스

2022년과 그 이후

2022년에 이러한 멋진 기능이 모두 출시된 후에도 아직 할 일이 많이 있습니다. 다음 섹션에서는 남아 있는 몇 가지 문제와 이를 해결하기 위해 적극적으로 개발 중인 솔루션을 살펴봅니다. 이러한 솔루션은 브라우저에서 플래그 뒤에 지정되거나 제공될 수 있지만 실험용입니다.

다음 섹션의 결과는 2023년에 이러한 솔루션이 출시될 예정이라는 것이 아니라 나열된 문제에 대해 많은 회사에서 해결 방법을 찾고 있는 많은 사람이 있다는 편리함이 될 것입니다.

느슨한 유형의 맞춤 속성

브라우저 지원

  • Chrome: 85
  • Edge: 85.
  • Firefox: 128.
  • Safari 16.4.

소스

CSS 맞춤 속성은 놀랍습니다. 이를 통해 다양한 항목을 이름이 지정된 변수 내에 저장할 수 있으며, 그런 다음 이를 확장, 계산, 공유할 수 있습니다. 사실 너무 유연해서 유연성이 떨어지는 함수가 있으면 좋을 것 같습니다.

box-shadow가 값에 맞춤 속성을 사용하는 시나리오를 생각해 보세요.

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

속성 중 하나가 CSS에서 허용하지 않는 값(예: --x: red)으로 변경될 때까지는 모두 잘 작동합니다. 중첩된 변수 중 하나가 누락되거나 잘못된 값 유형으로 설정되면 전체 그림자가 중단됩니다.

여기에서 @property가 사용됩니다. --x는 더 이상 느슨하고 유연하지 않고 정의된 경계가 있는 안전한 유형의 맞춤 속성이 될 수 있습니다.

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

이제 box-shadowvar(--x)를 사용하고 나중에 --x: red를 시도하면 red<length>가 아니므로 무시됩니다. 즉, 맞춤 속성 중 하나에 잘못된 값이 주어졌더라도 그림자가 계속 작동합니다. 실패하는 대신 0pxinitial-value로 되돌아갑니다.

애니메이션

유형 안전 외에도 애니메이션에 다양한 가능성을 열어줍니다. CSS 문법의 유연성으로 인해 그라데이션과 같은 일부 항목은 애니메이션할 수 없습니다. 유형이 지정된 CSS 속성은 지나치게 복잡한 보간 내에서 개발자의 의도를 브라우저에 알릴 수 있으므로 여기에서 @property가 유용합니다. 브라우저가 이전에는 할 수 없었던 스타일의 측면을 애니메이션으로 만들 수 있을 만큼 가능성의 범위를 제한합니다.

원형 그라데이션을 사용하여 오버레이의 일부를 만들어 스포트라이트 포커스 효과를 만드는 데모 예시를 살펴보세요. JavaScript는 alt/opt 키를 누르면 마우스 x 및 y를 설정한 다음 focal-size를 25%와 같은 더 작은 값으로 변경하여 마우스 위치에 스포트라이트 포커스 원을 만듭니다.

데모 사용해 보기
.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );
}

그러나 그라데이션은 애니메이션 처리할 수 없습니다. 애니메이션은 너무 유연하고 너무 복잡하여 브라우저에서 원하는 애니메이션 방식을 '파생'하기에는 너무 복잡합니다. 하지만 @property를 사용하면 하나의 속성을 별도로 입력하고 애니메이션으로 표시할 수 있으므로 브라우저에서 인텐트를 쉽게 이해할 수 있습니다.

이 포커스 효과를 사용하는 비디오 게임은 항상 큰 원부터 작은 원까지 원을 애니메이션 처리합니다. 브라우저에서 그라데이션 마스크의 애니메이션을 실행하도록 데모에서 @property를 사용하는 방법은 다음과 같습니다.

@property --focal-size {
  syntax: '<length-percentage>';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );

  transition: --focal-size .3s ease;
}
데모 사용해 보기

이제 브라우저가 경사 크기를 애니메이션할 수 있습니다. 수정의 표면적을 단 하나의 속성으로 줄이고 브라우저가 길이를 지능적으로 보간할 수 있도록 값을 입력했기 때문입니다.

@property는 훨씬 많은 작업을 할 수 있지만 이 작은 구현으로도 큰 효과를 거둘 수 있습니다.

리소스

min-width 또는 max-width에 있었음

미디어 쿼리 범위 전에 CSS 미디어 쿼리는 min-widthmax-width를 사용하여 over 및 under 조건을 설명합니다. 다음과 같이 표시될 수 있습니다.

@media (min-width: 320px) {
  
}

미디어 쿼리 범위 이후에 동일한 미디어 쿼리는 다음과 같을 수 있습니다.

@media (width >= 320px) {
  
}

min-widthmax-width를 모두 사용하는 CSS 미디어 쿼리는 다음과 같습니다.

@media (min-width: 320px) and (max-width: 1280px) {
  
}

미디어 쿼리 범위 이후에 동일한 미디어 쿼리는 다음과 같을 수 있습니다.

@media (320px <= width <= 1280px) {
  
}

코딩 배경에 따라 둘 중 하나가 다른 하나보다 훨씬 더 읽기 쉽습니다. 사양 추가 덕분에 개발자는 원하는 것을 선택하거나 서로 바꿔서 사용할 수 있습니다.

리소스

미디어 쿼리 변수 없음

@custom-media 이전에는 미디어 쿼리를 반복해서 실행하거나 빌드 시간 동안 정적 변수를 기반으로 적절한 출력을 생성하기 위해 전처리기에 의존해야 했습니다.

@custom-media 이후 CSS에서는 맞춤 속성과 마찬가지로 미디어 쿼리의 별칭 지정과 참조를 허용합니다.

이름 지정은 매우 중요합니다. 목적과 구문을 일치시켜 팀에서 더 쉽게 공유하고 사용할 수 있도록 할 수 있기 때문입니다. 다음은 프로젝트 간에 따라오는 맞춤 미디어 쿼리입니다.

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

이제 정의되었으므로 다음과 같이 이들 중 하나를 사용할 수 있습니다.

@media (--OSdark) {
  :root {
    
  }
}

CSS 맞춤 속성 라이브러리 Open Props 내에서 사용하는 맞춤 미디어 쿼리의 전체 목록을 찾습니다.

리소스

선택기 중첩이 너무 좋습니다

@nest 이전에는 스타일시트에서 많은 부분이 반복되었습니다. 선택기가 길고 각각 작은 차이를 타겟팅하는 경우 특히 다루기 어려웠습니다. 중첩의 편리성은 프리프로세서를 채택하는 가장 일반적인 이유 중 하나입니다.

@nest이 지나면 반복이 사라집니다. 프리프로세서 지원 중첩의 거의 모든 기능이 CSS에 내장되어 제공됩니다.

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

중첩 선택기에서 article를 반복하지 않는 것 외에도 중첩에 관해 가장 중요한 점은 스타일 지정 컨텍스트가 하나의 스타일 블록 내에 유지된다는 것입니다. 한 선택자와 스타일에서 스타일이 있는 다른 선택자로 이동하는 대신(예 1) 독자는 기사의 맥락 내에서 머물면서 기사 내부의 링크를 볼 수 있습니다. 관계와 스타일 인텐트가 함께 번들로 묶여 있으므로 article가 자체 스타일을 소유한 것처럼 보입니다.

소유권은 중앙 집중화라고도 할 수 있습니다. 스타일시트에서 관련 스타일을 찾는 대신 컨텍스트 내에서 모두 중첩된 항목을 찾을 수 있습니다. 이는 상위-하위 관계뿐만 아니라 하위-상위 관계에서도 작동합니다.

상위 요소가 스타일을 소유하고 하위 요소를 변경하는 대신 다른 상위 컨텍스트에 있을 때 자체를 조정하려는 구성요소 하위 요소를 고려해 보세요.

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

@nest는 전반적으로 더 나은 스타일 조직, 중앙 집중화, 소유권을 지원합니다. 구성요소는 다른 스타일 블록 사이에 배치하는 대신 자체 스타일을 그룹화하고 소유할 수 있습니다. 이 예에서는 작아 보일 수 있지만 편의성과 가독성 모두에 매우 큰 영향을 미칠 수 있습니다.

리소스

스타일 범위 지정하기란 매우 어렵습니다.

브라우저 지원

  • Chrome: 118.
  • Edge: 118.
  • Firefox: 플래그 뒤에 있습니다.
  • Safari: 17.4

소스

@scope 이전에는 CSS의 스타일이 기본적으로 계층화되고 상속되며 전역 범위가 지정되므로 여러 전략이 존재했습니다. 이러한 CSS 기능은 여러 가지 작업에 매우 편리하지만, 구성요소의 스타일이 다양할 수 있는 복잡한 사이트와 애플리케이션의 경우 전역 공간과 계층 구조의 특성으로 인해 스타일이 유출되는 것처럼 느껴질 수 있습니다.

@scope 이후에는 스타일의 범위를 클래스와 같은 컨텍스트 내로만 제한할 수 있을 뿐만 아니라 스타일이 끝나고 더 이상 계층화 또는 상속되지 않는 위치를 명시할 수도 있습니다.

다음 예에서는 BEM 이름 지정 규칙 범위를 실제 의도로 반전시킬 수 있습니다. BEM 선택기가 이름 지정 규칙을 사용하여 header 요소의 색상을 .card 컨테이너로 범위 지정하려고 합니다. 이렇게 하려면 헤더에 이 클래스 이름이 있어야 하며, 그러면 목표가 완료됩니다. @scope를 사용하면 헤더 요소를 마크업하지 않고 동일한 목표를 완료하기 위해 이름 지정 규칙이 필요하지 않습니다.

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

다음은 구성요소별이 아닌 CSS의 전역 범위 특성에 관한 다른 예입니다. 어두운 테마와 밝은 테마는 스타일시트 내에서 공존해야 하며, 여기서 순서는 사용되는 스타일을 결정하는 데 중요합니다. 일반적으로 이는 어두운 테마 스타일이 밝은 테마 뒤에 오는 것을 의미합니다. 이렇게 하면 밝은 테마가 기본 테마로, 어두운 테마가 선택적 스타일로 설정됩니다. @scope로 정렬 및 범위 충돌을 방지합니다.

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

여기에서 스토리를 완료하려면 @scope를 사용하여 스타일 범위가 끝나는 위치를 설정할 수도 있습니다. 이는 어떠한 명명 규칙이나 전처리기로도 수행할 수 없습니다. 이는 특수하며 브라우저에 내장된 CSS만 할 수 있는 작업입니다. 다음 예에서 img 스타일과 .content 스타일은 .media-block의 하위 요소가 .content의 동위 요소이거나 상위 요소일 때만 적용됩니다.

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

리소스

석재 벽돌 레이아웃을 위한 CSS 방법이 없음

그리드가 있는 CSS 마노리조 레이아웃이 도입되기 전에는 열이나 Flexbox가 있는 CSS 메서드가 콘텐츠 순서를 부정확하게 나타내기 때문에 JavaScript가 마노리조 레이아웃을 구현하는 가장 좋은 방법이었습니다.

그리드가 있는 CSS 마저니즘을 사용하면 JavaScript 라이브러리가 필요하지 않으며 콘텐츠 순서가 올바르게 됩니다.

숫자가 위에서 아래로 이동하는 모습을 보여주는 석재 레이아웃의 스크린샷
Smashing Magazine의 이미지 및 데모
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

위의 데모는 다음 CSS로 실행됩니다.

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

누락된 레이아웃 전략으로 확인되었으니 다행입니다. 지금 Firefox에서 사용해 보세요.

리소스

CSS로 사용자가 데이터를 줄일 수 없음

브라우저 지원

  • Chrome: 플래그 뒤에 있습니다.
  • 가장자리: 깃발 뒤쪽에 있습니다.
  • Firefox: 지원되지 않음
  • Safari: 지원되지 않음

소스

prefers-reduced-data 미디어 쿼리 이전에는 JavaScript와 서버가 사용자의 운영체제 또는 브라우저 '데이터 절약 모드' 옵션에 따라 동작을 변경할 수 있었지만 CSS는 불가능했습니다.

prefers-reduced-data 미디어 쿼리 다음에 CSS는 사용자 환경 개선을 조인하여 데이터를 저장하는 데 관여할 수 있습니다.

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

위의 CSS는 이 미디어 스크롤 구성요소에서 사용되며 절약 효과가 상당할 수 있습니다. 방문하는 표시 영역의 크기에 따라 페이지 로드 시 더 많은 절감 효과를 얻을 수 있습니다. 사용자가 미디어 스크롤러와 상호작용할 때 저장은 계속됩니다. 모든 이미지에 loading="lazy" 속성이 있으며, CSS가 요소를 완전히 숨기는 것과 함께 이미지에 대한 네트워크 요청이 전송되지 않습니다.

여러 썸네일과 제목이 표시된 TV 프로그램 캐러셀 인터페이스의 스크린샷

테스트에서는 중간 크기의 표시 영역에서 처음에 40개의 요청과 700kb의 리소스가 로드되었습니다. 사용자가 미디어 선택을 스크롤하면 더 많은 요청과 리소스가 로드됩니다. CSS와 축소된 데이터 미디어 쿼리를 사용하면 10개의 요청과 172KB의 리소스가 로드됩니다. 이는 500KB를 절약한 것이며, 사용자는 아직 미디어를 스크롤하지 않았으므로 추가 요청이 없습니다.

썸네일과 여러 제목이 표시되지 않은 TV 프로그램 캐러셀 인터페이스의 스크린샷

데이터 절약 외에도 데이터 사용량이 줄어든 환경에는 더 많은 이점이 있습니다. 더 많은 제목을 볼 수 있으며 주의를 분산시키는 표지 이미지가 없습니다. 많은 사용자가 데이터를 메가바이트 단위로 결제하기 때문에 데이터 절약 모드로 탐색합니다. CSS가 여기에서 도움이 될 수 있어 정말 좋습니다.

리소스

스크롤 스냅 기능이 너무 제한적임

이러한 스크롤 스냅 제안이 있기 전에는 캐러셀, 슬라이더 또는 갤러리를 관리하기 위해 자체 JavaScript를 작성하면 모든 관찰자와 상태 관리로 인해 빠르게 복잡해질 수 있었습니다. 또한 주의하지 않으면 자연 스크롤 속도가 스크립트에 의해 표준화되어 사용자 상호작용이 약간 부자연스럽고 불편할 수 있습니다.

새로운 API

snapChanging()

브라우저에서 맞추기 하위 요소를 해제하는 즉시 이 이벤트가 실행됩니다. 이렇게 하면 UI가 이제 사용 중이며 새로운 위치에 배치될 것이므로 스냅 하위 요소의 부족과 스크롤러의 불확정 스냅 상태를 반영할 수 있습니다.

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()

브라우저가 새 하위 요소로 스냅되고 스크롤러가 멈추는 즉시 이 이벤트가 실행됩니다. 이렇게 하면 스냅된 하위 요소에 종속된 모든 UI가 업데이트되고 연결을 반영할 수 있습니다.

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

스크롤이 항상 시작 부분에서 시작되는 것은 아닙니다. 왼쪽 또는 오른쪽으로 스와이프하면 다른 이벤트가 트리거되는 스와이프 가능한 구성요소나 페이지가 로드될 때 처음에는 맨 위로 스크롤할 때까지 숨겨지는 검색창을 고려해 보세요. 이 CSS 속성을 사용하면 개발자가 스크롤러가 특정 지점에서 시작해야 한다고 지정할 수 있습니다.

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
:snap-target

이 CSS 선택자는 현재 브라우저에 의해 스냅된 스크롤 스냅 컨테이너의 요소와 일치합니다.

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

이러한 스크롤 스냅 제안이 도입된 후에는 브라우저가 이 작업을 위한 편의를 제공하므로 슬라이더, 캐러셀 또는 갤러리를 만드는 것이 훨씬 쉬워졌습니다. 이제 내장 API를 사용하고 관찰자와 스크롤 조정 코드를 제거할 수 있습니다.

이러한 CSS 및 JS 기능은 아직 초기 단계에 있지만 곧 도입 및 테스트에 도움이 되는 폴리필을 기대해 주세요.

리소스

알려진 상태 간에 전환

toggle() 이전에는 브라우저에 내장된 상태만 스타일 지정 및 상호작용에 활용할 수 있었습니다. 예를 들어 체크박스 입력에는 CSS가 요소를 시각적으로 변경하는 데 사용할 수 있는 입력의 내부 관리 브라우저 상태인 :checked가 있습니다.

toggle() 이후에는 CSS가 변경하고 스타일 지정에 사용할 수 있는 맞춤 상태를 모든 요소에 만들 수 있습니다. 그룹, 사이클링, 방향 전환 등의 기능이 지원됩니다.

다음 예에서는 체크박스 요소 없이 완료 시 목록 항목 취소선과 동일한 효과를 얻을 수 있습니다.

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

관련 CSS toggle() 스타일은 다음과 같습니다.

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}

상태 머신에 익숙하다면 toggle()와 얼마나 많은 교차가 있는지 알 수 있습니다. 이 기능을 사용하면 개발자가 더 많은 상태를 CSS에 빌드할 수 있으므로 상호작용과 상태를 더 명확하고 의미 있는 방식으로 조정할 수 있습니다.

리소스

선택한 요소 맞춤설정

<selectmenu> 이전에는 CSS에서 리치 HTML로 <option> 요소를 맞춤설정하거나 옵션 목록의 표시를 많이 변경할 수 없었습니다. 이로 인해 개발자는 <select>의 기능 대부분을 재생성하는 외부 라이브러리를 로드해야 했으며, 이는 많은 작업이 되었습니다.

<selectmenu> 이후 개발자는 접근성 요구사항을 충족하고 시맨틱 HTML을 제공하면서 옵션 요소에 리치 HTML을 제공하고 필요한 만큼 스타일을 지정할 수 있습니다.

<selectmenu> 설명 페이지에서 가져온 다음 예에는 몇 가지 기본 옵션이 포함된 새로운 선택 메뉴가 생성됩니다.

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

CSS는 요소의 부분을 타겟팅하고 스타일을 지정할 수 있습니다.

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

빨간색 강조 색상이 있는 선택 메뉴입니다.

웹 실험 플래그를 사용 설정한 Canary의 Chromium에서 <selectmenu> 요소를 사용해 볼 수 있습니다. 2023년 이후에는 맞춤설정 가능한 일부 메뉴 요소를 확인하세요.

리소스

요소를 다른 요소에 고정

anchor() 이전에는 개발자가 하위 요소를 상위 요소 내에서 이동하도록 하기 위해 제공된 위치 전략이 position absolute와 relative였습니다.

anchor() 이후 개발자는 요소가 하위 요소인지 여부와 관계없이 다른 요소에 요소를 배치할 수 있습니다. 또한 개발자는 배치할 가장자리와 요소 간의 위치 관계를 만드는 기타 세부사항을 지정할 수 있습니다.

자세히 알아보려면 설명에서 몇 가지 훌륭한 예시와 코드 샘플이 제공됩니다.

리소스