반응형 웹 디자인의 새로운 시대에 마이크로 및 매크로 레이아웃을 제어합니다.
오늘날의 반응형 디자인
오늘날 '반응형 디자인'이라는 용어를 사용하면 디자인 크기를 모바일 크기에서 태블릿 크기, 데스크톱 크기로 조절할 때 미디어 쿼리를 사용하여 레이아웃을 변경하는 것을 떠올리게 됩니다.
하지만 곧 반응형 디자인에 대한 이러한 인식은 페이지 레이아웃에 표를 사용하는 것처럼 시대에 뒤떨어진 것으로 간주될 수 있습니다.
뷰포트 기반 미디어 쿼리는 강력한 도구를 제공하지만 세밀함이 많이 부족합니다. 이러한 컴포넌트는 사용자 요구사항에 응답하는 기능과 반응형 스타일을 컴포넌트 자체에 삽입하는 기능이 없습니다.
전역 뷰포트 정보를 사용하여 구성요소의 스타일을 지정할 수 있지만, 구성요소가 여전히 자체 스타일을 소유하지는 않으며 디자인 시스템이 페이지 기반이 아닌 구성요소 기반인 경우에는 작동하지 않습니다.
좋은 소식은 생태계가 변화하고 있으며 그 속도가 매우 빠르다는 것입니다. CSS가 진화하고 있으며 반응형 디자인의 새로운 시대가 바로 눈앞에 다가오고 있습니다.
이러한 현상은 약 10년마다 발생합니다. 10년 전인 2010~2012년경에는 모바일 및 반응형 디자인과 CSS3의 등장으로 큰 변화가 있었습니다.
따라서 생태계는 CSS에 상당히 큰 변화가 있을 준비가 되었습니다. Chrome 및 웹 플랫폼 전반의 엔지니어들이 반응형 디자인의 다음 시대를 위한 프로토타입을 제작하고 사양을 지정하며 구현을 시작하고 있습니다.
이러한 업데이트에는 사용자 환경설정 기반 미디어 기능, 컨테이너 쿼리, 폴더블 화면과 같은 새로운 화면 유형의 미디어 쿼리가 포함됩니다.
사용자에게 응답함
새로운 사용자 환경설정 미디어 기능을 사용하면 사용자의 고유한 환경설정 및 요구사항에 맞게 웹 환경을 설정할 수 있습니다. 즉, 환경설정 미디어 기능을 사용하면 사용자 환경을 사용자의 환경에 맞게 조정할 수 있습니다.
사용자 환경설정 미디어 기능에는 다음이 포함됩니다.
prefers-reduced-motion
prefers-contrast
prefers-reduced-transparency
prefers-color-scheme
inverted-colors
- 기타
환경설정 기능은 사용자가 운영체제에서 설정한 환경설정을 가져와 특히 접근성 기능이 필요한 사용자를 위해 더 강력하고 맞춤화된 웹 환경을 구축하는 데 도움이 됩니다.
prefers-reduced-motion
운영체제 환경설정을 모션 감소로 설정한 사용자는 일반적으로 컴퓨터를 사용할 때 애니메이션을 더 적게 요청합니다. 따라서 웹을 사용하는 동안 화려한 인트로 화면, 카드 플립 애니메이션, 복잡한 로더 또는 기타 화려한 애니메이션을 선호하지 않을 수 있습니다.
prefers-reduced-motion
를 사용하면 모션 감소를 염두에 두고 페이지를 디자인하고 이 환경설정을 사용 설정하지 않은 사용자를 위해 모션이 향상된 환경을 만들 수 있습니다.
이 카드에는 양면에 정보가 있습니다. 기준이 되는 모션 감소 환경은 이 정보를 보여주는 크로스페이드이고 모션 개선 환경은 카드 플립입니다.
모션은 온라인에서 정보를 전달하는 데 매우 중요하므로 prefers-reduced-motion이 '모션 없음'을 의미해서는 안 됩니다. 대신 불필요한 움직임 없이 사용자를 안내하는 견고한 기준 환경을 제공하고 이러한 접근성 요구사항이나 선호사항이 없는 사용자를 위해 점진적으로 환경을 개선하세요.
prefers-color-scheme
또 다른 환경설정 미디어 기능은 prefers-color-scheme
입니다. 이 기능을 사용하면 사용자가 선호하는 테마에 맞게 UI를 맞춤설정할 수 있습니다. 사용자는 데스크톱이든 모바일이든 운영체제에서 밝은 테마, 어두운 테마 또는 자동 테마의 환경설정을 설정할 수 있으며, 이는 시간에 따라 변경됩니다.
CSS 맞춤 속성을 사용하여 페이지를 설정하면 색상 값을 쉽게 전환할 수 있습니다. backgroundColor
및 textOnPrimary
와 같은 색상 테마 값을 빠르게 업데이트하여 미디어 쿼리 내에서 새 테마에 동적으로 조정할 수 있습니다.
이러한 환경설정 쿼리의 일부를 더 쉽게 테스트하려면 매번 시스템 환경설정을 여는 대신 에뮬레이션을 위한 DevTools를 사용하면 됩니다.
어두운 테마용 디자인
어두운 테마용으로 디자인할 때는 배경과 텍스트 색상을 반전하거나 어두운 스크롤바를 사용하는 것만이 아닙니다. 몇 가지 고려해야 할 사항이 있습니다. 예를 들어 시각적 떨림을 줄이려면 어두운 배경에서 색상의 채도를 낮춰야 할 수 있습니다.
그림자를 사용하여 깊이를 만들고 요소를 앞으로 그리는 대신 요소의 background-color에서 빛을 사용하여 요소를 앞으로 그릴 수 있습니다. 어두운 배경에서는 그림자가 그다지 효과적이지 않기 때문입니다.
어두운 테마는 더 맞춤설정된 사용자 환경을 제공할 뿐만 아니라 AMOLED 화면의 배터리 수명도 크게 개선할 수 있습니다. 이러한 화면은 최신 고급형 휴대전화에서 볼 수 있으며, 휴대기기 전반에서 점점 더 인기를 얻고 있습니다.
어두운 테마에 관한 2018년 Android 연구에 따르면 화면 밝기와 전반적인 사용자 인터페이스에 따라 최대 60%의 전원 소모를 절약할 수 있습니다. 60% 라는 통계는 앱 UI에 어두운 테마를 사용한 YouTube 재생 화면과 밝은 테마를 사용한 일시중지된 동영상(화면 밝기 100%)을 비교한 결과입니다.
가능하면 항상 사용자에게 어두운 테마 환경을 제공해야 합니다.
컨테이너에 반응함
CSS에서 가장 흥미로운 신규 영역 중 하나는 컨테이너 쿼리(요소 쿼리라고도 함)입니다. 페이지 기반 반응형 디자인에서 컨테이너 기반 반응형 디자인으로의 전환이 디자인 생태계의 진화에 미치는 영향을 과소평가하기는 어렵습니다.
다음은 컨테이너 쿼리가 제공하는 강력한 기능의 예입니다. 상위 컨테이너를 기반으로 링크 목록, 글꼴 크기, 전체 레이아웃을 비롯한 카드 요소의 스타일을 조작할 수 있습니다.
이 예에서는 CSS 그리드를 사용하여 만든 레이아웃에서 공간을 차지하는 두 가지 서로 다른 컨테이너 크기의 동일한 구성요소 2개를 보여줍니다. 각 구성요소는 고유한 공간 할당에 맞게 조정되고 그에 따라 스타일이 지정됩니다.
이러한 유연성은 미디어 쿼리만으로는 불가능합니다.
컨테이너 쿼리는 반응형 디자인에 훨씬 더 동적인 접근 방식을 제공합니다. 즉, 이 카드 구성요소를 사이드바 또는 영웅 섹션에 배치하거나 페이지의 본문 내 그리드 내에 배치하면 구성요소 자체가 표시 영역이 아닌 컨테이너에 따라 반응형 정보와 크기를 소유합니다.
이를 위해서는 @container
at-rule이 필요합니다. 이는 @media
를 사용한 미디어 쿼리와 비슷한 방식으로 작동하지만, @container
는 뷰포트 및 사용자 에이전트가 아닌 상위 컨테이너에서 정보를 쿼리합니다.
.card {
container-type: inline-size;
}
@container (max-width: 850px) {
.links {
display: none;
}
.time {
font-size: 1.25rem;
}
/* ... */
}
먼저 상위 요소에 포함을 설정합니다. 그런 다음 @container
쿼리를 작성하여 min-width
또는 max-width
를 사용하여 컨테이너 내의 요소에 크기에 따라 스타일을 지정합니다.
위 코드는 max-width
를 사용하고 링크를 display:none
로 설정하며 컨테이너의 너비가 850px
보다 작을 때 시간 글꼴 크기를 줄입니다.
컨테이너 쿼리 카드
이 데모 플랜트 웹사이트에서 히어로의 제품 카드, 최근 본 항목의 사이드바, 제품 그리드 등 각 제품 카드는 모두 동일한 마크업을 사용하는 동일한 구성요소입니다.
이 전체 레이아웃을 만드는 데 사용되는 미디어 쿼리는 없으며 컨테이너 쿼리만 있습니다. 이렇게 하면 각 제품 카드가 공간을 채우기 위해 적절한 레이아웃으로 전환될 수 있습니다. 예를 들어 그리드는 minmax 열 레이아웃을 사용하여 요소가 공간으로 흐르도록 하고 공간이 너무 압축되면(즉, 최소 크기에 도달하면) 그리드의 레이아웃을 다시 설정합니다.
.product {
container-type: inline-size;
}
@container (min-width: 350px) {
.card-container {
padding: 0.5rem 0 0;
display: flex;
}
.card-container button {
/* ... */
}
}
그리드에 350px
이상의 공간이 있으면 카드 레이아웃이 기본 flex-direction이 'row'인 display: flex
로 설정되어 가로로 이동합니다.
공간이 부족하면 제품 카드가 쌓입니다. 각 제품 카드는 자체적으로 스타일을 지정합니다. 이는 전역 스타일만으로는 불가능한 일입니다.
컨테이너 쿼리와 미디어 쿼리 혼합
컨테이너 쿼리의 사용 사례는 매우 다양하며 그중 하나가 캘린더 구성요소입니다. 컨테이너 쿼리를 사용하여 상위 요소의 사용 가능한 너비를 기반으로 캘린더 일정 및 기타 세그먼트의 레이아웃을 다시 지정할 수 있습니다.
이 데모 컨테이너는 쿼리를 실행하여 캘린더의 날짜 및 요일의 레이아웃과 스타일을 변경하고, 예약된 일정의 여백과 글꼴 크기를 조정하여 공간에 더 잘 맞도록 합니다.
그런 다음 미디어 쿼리를 사용하여 작은 화면 크기에 맞게 전체 레이아웃을 이동합니다. 이 예는 미디어 쿼리 (전역 또는 매크로 스타일 조정)와 컨테이너 쿼리 (컨테이너의 하위 요소 및 마이크로 스타일 조정)를 결합하는 것이 얼마나 강력한지 보여줍니다.
이제 동일한 UI 구성요소 내에서 매크로 및 마이크로 레이아웃을 고려하여 매우 섬세한 디자인 결정을 내릴 수 있습니다.
현재 컨테이너 쿼리 사용
이제 Chrome Canary에서 플래그를 사용해 이 데모를 실행할 수 있습니다. Canary의 about://flags
로 이동하여 #enable-container-queries
플래그를 사용 설정합니다.
이렇게 하면 contain
속성의 @container
, inline-size
, block-size
값과 LayoutNG 그리드 구현을 지원할 수 있습니다.
이 플래그는 해당하는 Chrome DevTools 기능도 사용 설정합니다. DevTools에서 컨테이너 쿼리를 검사하고 디버그하는 방법을 알아보세요.
범위가 지정된 스타일
컨테이너 쿼리를 기반으로 빌드하려면 @scope
를 사용한 범위 지정된 스타일을 사용하여 선택기의 도달 범위를 제한합니다.
범위가 지정된 스타일을 사용하면 구성요소별 스타일을 지정하여 이름 충돌을 방지할 수 있습니다. 이는 CSS 모듈과 같은 많은 프레임워크와 플러그인에서 이미 프레임워크 내에서 할 수 있는 작업입니다. 범위 지정된 스타일을 사용하면 마크업을 조정할 필요 없이 읽기 쉬운 CSS로 구성요소에 캡슐화된 스타일을 기본적으로 작성할 수 있습니다.
/* @scope (<root>#) [to (<boundary>#)]? { … } */
@scope (.tabs) to (.panel) {
:scope { /* targeting the scope root */ }
.light-theme :scope .tab { /* contextual styles */ }
}
범위를 지정하면 상한과 하한을 지정할 수 있는 '도넛 모양' 선택기를 만들 수 있습니다. @scope
규칙에 포함된 선택자는 이러한 한도 간에 일치합니다.
탭 패널이 이러한 예입니다. 탭 패널에서는 탭에 범위가 지정된 스타일을 적용하고 싶지만 탭 내 패널은 이러한 범위가 지정된 스타일의 영향을 받지 않도록 해야 합니다.
폼 팩터에 맞게 반응
반응형 디자인의 새로운 시대에 관한 대화의 다음 주제는 폼 팩터의 변화와 웹 커뮤니티로서 설계해야 할 점의 증가하는 가능성 (예: 모양 변환 화면 또는 가상 현실)입니다.
폴더블 또는 유연한 화면, 화면 확장을 위한 설계는 오늘날 폼 팩터 변화를 볼 수 있는 한 가지 예입니다. 화면 확장은 이러한 새로운 폼 팩터와 요구사항을 충족하기 위해 개발 중인 또 다른 사양입니다.
화면 확장을 위한 실험용 미디어 쿼리가 도움이 될 수 있습니다. 현재 @media
(spanning: <type of fold>)
와 같이 동작합니다. 이 데모에서는 열이 두 개인 그리드 레이아웃을 설정합니다. 하나는 너비가 --sidebar-width(기본값: 5rem)이고 다른 하나는 1fr
입니다. 레이아웃이 단일 세로 접힌 듀얼 화면에서 표시되면 --sidebar-width
값이 왼쪽 접힌 부분의 환경 값으로 업데이트됩니다.
:root {
--sidebar-width: 5rem;
}
@media (spanning: single-fold-vertical) {
--sidebar-width: env(fold-left);
}
main {
display: grid;
grid-template-columns: var(--sidebar-width) 1fr;
}
이렇게 하면 사이드바(이 경우 탐색)가 폴드 중 하나의 공간을 채우고 앱 UI가 다른 폴드의 공간을 채우는 레이아웃을 사용할 수 있습니다. 이렇게 하면 UI에 '주름'이 생기지 않습니다.
Chrome DevTools 에뮬레이터에서 폴더블 화면을 테스트하여 브라우저에서 직접 화면 확장을 디버그하고 프로토타입을 만들 수 있습니다.
결론
평면 화면을 넘어 UI 디자인을 살펴보는 것도 컨테이너 쿼리와 범위 지정된 스타일이 중요한 또 다른 이유입니다. 이를 통해 페이지 레이아웃, 전역 스타일, 사용자 스타일에서 구성요소 스타일을 분리하여 더 탄력적인 반응형 디자인을 구현할 수 있습니다. 즉, 이제 화면을 넓게 아우르는 미묘한 차이를 포함하여 페이지 기반 미디어 쿼리를 사용하여 매크로 레이아웃을 설계할 수 있습니다. 동시에 구성요소에 컨테이너 쿼리와 함께 마이크로 레이아웃을 사용하고 사용자 환경설정 기반 미디어 쿼리를 추가하여 사용자의 고유한 환경설정 및 요구사항에 따라 사용자 환경을 맞춤설정합니다.
이가 새로운 반응형입니다.
매크로 레이아웃과 마이크로 레이아웃을 결합하고 그 위에 사용자 맞춤설정과 폼 팩터를 고려합니다.
이러한 변화만으로도 웹 디자인 방식에 상당한 변화가 있을 것입니다. 하지만 두 가지를 함께 고려하면 반응형 디자인을 개념화하는 방식에 있어 상당한 변화가 있음을 알 수 있습니다. 이제 뷰포트 크기를 넘어 반응형 디자인을 고려하고 더 나은 구성요소 기반 맞춤 환경을 위해 이러한 모든 새로운 축을 고려해야 할 때입니다.
반응형 디자인의 새로운 시대가 도래했습니다. 지금 바로 직접 살펴보세요.
web.dev/learnCSS
지금은 CSS 실력을 높이고 기본사항을 다시 살펴보고 싶으신가요? 저희 팀에서 web.dev에 완전히 무료인 새로운 CSS 과정과 참조 자료를 출시합니다. web.dev/learnCSS를 통해 액세스할 수 있습니다.
반응형 디자인의 다음 시대와 함께 제공될 몇 가지 원시 요소에 관한 개요를 즐기셨기를 바라며, 웹 디자인의 미래에 미칠 영향에 대해 저만큼이나 기대하시기 바랍니다.
이는 UI 커뮤니티로서 구성요소 기반 스타일과 새로운 폼 팩터를 수용하고 사용자 반응형 환경을 만드는 큰 기회가 됩니다.