블로그

content-visibility: 리스트 가상화 없이 화면 밖 렌더링을 건너뛰는 법

댓글 천 개짜리 목록이 느리게 렌더링되어 react-window를 꺼내 듭니다 – 그런데 부드러운 스크롤을 얻는 대가로 Ctrl+F, 페이지 인쇄, 그리고 스크린 리더 탐색 일부를 잃게 됩니다. 화면 밖 요소들이 DOM에서 물리적으로 사라져버리기 때문입니다. content-visibility는 같은 문제를 다른 방식으로 풉니다 – 요소는 DOM에 그대로 남아 있고, 브라우저는 화면 근처에 오기 전까지 비용이 큰 레이아웃과 페인트 작업만 건너뜁니다. 그리고 놀랍게도, 그 안의 텍스트를 검색할 때는 일시적으로 다시 드러내 줄 수도 있습니다.

Popover API와 네이티브 <dialog>: 처음부터 직접 만드는 모달의 종말

접근성 글에서 다룬, display:none으로 감췄지만 접근성 트리에는 여전히 남아 있던 모달은 div로 처음부터 직접 만든 모달에서 비롯된 실수의 한 예였습니다. 진짜 질문은 애초에 왜 그것을 처음부터 만들어야 했는가입니다. 네이티브 <dialog>와 popover 속성이 공짜로 제공하는 것 – 톱 레이어, 포커스 트랩, light dismiss – 이 무엇인지, 그리고 이 두 메커니즘이 서로 헷갈리면 곧바로 접근성이 떨어지는 인터페이스로 이어질 만큼 다른 지점이 어디인지 살펴봅니다.

CSS @layer: 캐스케이드 레이어가 특이성 전쟁을 끝내는 방법

유틸리티 클래스 .mt-4는 나중에 추가되었으니 논리적으로는 이겨야 할 것 같은데도 .card .card__header .card__title 규칙에 집니다. 이는 우연이 아니라 특이성이 설계된 대로 정확히 작동하고 있는 것입니다. @layer는 특이성과 함께가 아니라 그보다 앞서 작동하는, 충돌 해결의 완전히 새로운 축을 도입합니다 – 그리고 어찌나 직관에 어긋나는지, 웹상의 일부 문서조차 잘못 설명하는 함정이 하나 있습니다.

CSS :has() — 안에서 무슨 일이 일어나는지 아는 부모

폼 필드는 내부의 input이 유효하지 않을 때 빨간색으로 강조되어야 합니다. 간단해 보이는 일입니다 – 다만 CSS는 25년 동안 요소에게 그 내부에서 무슨 일이 일어나고 있는지 물어볼 방법이 없었고, 오직 그 반대 방향만 가능했습니다. :has()가 이 방향을 어떻게 뒤집는지, 일반적인 결합자와 어떻게 다른지, 그리고 이 새로운 힘이 실제로 성능에 어떤 대가를 치르게 하는지 살펴봅니다.

컨테이너 쿼리: 뷰포트가 아니라 자신의 컨테이너를 아는 컴포넌트

같은 상품 카드가 그리드에서는 근사하게 보이지만, 미디어 쿼리를 정성껏 짜놓았음에도 좁은 사이드바에서는 무너집니다. 문제는 코드에 있는 게 아니라 미디어 쿼리가 던지는 질문 자체에 있습니다 – 화면의 너비를 묻는 것이지, 컴포넌트가 실제로 받은 공간을 묻는 게 아니라는 것이죠. 컨테이너 쿼리가 이 질문을 원래 있어야 할 자리로 옮기는 방법과, 요소가 '쿼리 컨테이너'가 될 때 내부에서 실제로 무슨 일이 벌어지는지 살펴봅니다.

CSS Houdini 활용: 일반 CSS에서는 불가능한 커스텀 효과 만들기

CSS Houdini는 하나의 기술이 아니라, 성숙도가 저마다 크게 다른 여러 명세의 모음입니다. 오늘날 실제 프로덕션에 사용할 수 있는 부분은 어디인지, @property와 paint worklet이 실제로 어떻게 작동하는지, 그리고 나머지가 왜 아직 실험 단계에 머물러 있는지 확인해 보세요.