본문 바로가기
CSS

CSS 접근성과 기본 설정에 대한 고찰

by Vintz 2021. 12. 12.
반응형

나는 개인적으로 CSS는 처음 설정을 어떻게 해야 할지가 항상 고민이었다. 그 이유는 사용자 에이전트 스타일시트(user agent stylesheet)때문이었다. 이게 은근 프로젝트를 진행할 때 신경쓰이고 피곤한 부분이었다.

  1. '기본 속성을 가지는 요소를 처음부터 초기화를 해야하나?'
  2. '요소, 클래스에 스타일을 적용할 때마다 초기화를 할까?'

1번의 경우엔 사용하지 않는 요소까지 초기화를 한단 생각에 찝찝했고, 2번의 경우엔 초기화 하는 것을 놓치거나 그때 그때 적용하다보니 '이게 유지보수에 과연 좋은 방법일까'란 생각이 들었다. 그렇게 시간이 흐르다가 좋은 CSS 초기설정 코드를 보게 되었다. 해당 코드는 최소한의 기본적인 초기설정과 접근성까지 신경을 써서 작성한 코드였다. 많은 경험 속에 나온 코드라 생각해서 바로 적용을 했고, 만족스러웠다.

/* 변수 설정, 유지보수에 좋다 */
:root {
  --fs-300: 0.6875rem;
  --fs-400: 0.8125rem;
  --fs-500: 1.25rem;

  --bg-dark: #424242;
  --bg-primary: #fff;
  --bg-accent: #ab47bc;
  --bg-datk-light: #707070;

  --border-primary-400: 2px solid #a775f1;
}

/* Box sizing 규칙 */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* margin 기본값 제거 */
body,
h1,
h2,
h3,
h4,
p {
  margin: 0;
}

/* 기본 스타일 제거 */
ul,
ol {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* 핵심 root 기본값 설정 */
html:focus-within {
  scroll-behavior: smooth;
}

/* 핵심 body 기본값 설정 */
body {
  min-height: 100vh;
  text-rendering: optimizeSpeed;
  line-height: 1.5;
}

/* 클래스가 없는 a 요소는 기본 스타일을 가져옴, 문자의 가독성을 위함 */
a:not([class]) {
  text-decoration-skip-ink: auto;
}

/* 이미지 작업을 좀 더 쉽게 해준다 */
img,
picture {
  max-width: 100%;
  display: block;
}

/* 폰트 상속(Inherit) */
input,
button,
textarea,
select {
  font: inherit;
}

/* 모든 애니메이션 제거, transitions과 smooth scroll을 보고싶지 않은 사용자를 위함 */
@media (prefers-reduced-motion: reduce) {
  html:focus-within {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

:root를 통한 변수 설정

:root는 문서 트리의 루트 요소를 선택한다. HTML의 루트 요소는 <html> 요소이므로 :root는 해당 요소보다 명시도(우선순위)가 더 낮다는 점을 제외하면 html 선택자와 같다.

 

따라서 전역변수 설정을 통해 스타일을 적용할 때 해당 변수를 사용하고, 변경사항이 있을 시 변수를 수정하면 변수를 사용한 곳에 스타일이 모두 적용된다.

Box sizing 규칙

box-sizing: border-box는 테두리(border)와 안쪽 여백(padding)의 크기도 요소의 크기가 된다. 예를 들어 width100px로 설정하고 borderpadding을 추가하면, 콘텐츠 영역이 줄어들어서 총 너비 100px을 유지한다. 일반적으로 이 경우가 크기를 조절할 때 가장 쉽다. 부모 컨테이너의 크기를 넘을 일이 적기 때문이다.

html:focus-within

이 방법은 ctl+f 또는 cmd+f로 검색하는 사람들을 위한 CSS 트릭이다.

html {
  scroll-behavior: smooth;
}

만약 위와 같이 scroll-behavior: smooth를 적용한 사이트에서 단어 검색을 할 경우 부드러운 스크롤이 적용이 되어 검색하는 시간이 지체가 된다. 이것에 대해 사용자는 꽤 짜증이 나나 보다. 사이트 내에 콘텐츠가 많을 경우 그럴 것 같긴 하다.

html:focus-within {
  scroll-behavior: smooth;
}

위와 같이 설정을 하면 대부분의 경우 해결이 된다.

<a href="#link-down">아래로 이동</a>

...

<h2 id="link-down">개발전용 차선</h2>

위 예시는 <a> 요소를 클릭하면 정상적으로 scroll-behavior: smooth가 적용이 된다. 하지만 <h2> 요소는 일반적으로 'focusable'하지 않다. 따라서 html에 적용한 scroll-behavior: smooth가 적용되지 않는다.

 

만약 smooth를 유지하고 싶다면 아래와 같이 하면 된다.

<h2 tabindex="-1" id="link-down">개발전용 차선</h2>

text-rendering: optimizeSpeed

body의 핵심(core) 기본값이라고는 하는데, 사실 잘 모르겠다. 텍스트를 그릴 때 렌더링 속도를 강조한다는데 다른 것과 크게 영향을 끼치지 않을 것 같아서 추가했다.

text-decoration-skip-ink: auto

클래스가 없는 <a> 요소의 경우 기본 스타일을 가져오도록 했다. 이렇게 하는게 문자의 가독성이 더 좋다.

https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration-skip-ink

애니메이션 동작 축소하기

너무 과한 애니메이션은 사용자에게 불편함을 줄 수 있다. 또한 배터리가 부족한 경우나 보급형 스마트폰 및 컴퓨터를 사용하는 사람들에게 도움을 줄 수 있다. reduce는 사용자가 시스템에 애니메이션 동작을 최소화하도록 설정했다는 것을 의미한다. 가급적이면 필수적이지 않은 동작은 모두 제거된다.

@media (prefers-reduced-motion: reduce) {
  html:focus-within {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

참고

Learn grid the easy way - Kevin Powell
Fixing Smooth Scrolling with Find-on-Page - CSS Tricks
Twitter - Chris Coyier
반응형