본문 바로가기
About IT/웹 개발

알고 쓰는 서브 픽셀: 웹 개발자와 디자이너의 협업을 위한 필수 지식

by yjin_fe 2024. 12. 22.

목차

1. 들어가며

2. 서브 픽셀 기술이란?

3. 서브 픽셀 렌더링 vs. 서브 픽셀 정밀도

4. 서브 픽셀 정밀도가 중요한 CSS 속성들

  (1) 적용되는 속성들

  (2) 적용되지 않는 속성들

5. 마무리

 

들어가며

웹 서비스를 개발하며 디자이너와 협업하다 보면, 다음과 같은 상황을 마주할 수 있습니다.

디자인 시안에 border: 1.55px가 적혀있는데, 개발자는 “브라우저가 border 소수점 처리를 제대로 하지 못해, 사실상 적용이 안 된다”고 설명합니다. 그러자 디자이너는 “그럼 box-shadow에는 소수점을 쓸 수 있는데, 왜 border는 안 되나요?”라며 반문합니다. 결국 개발자는 “그 둘은 동작 방식이 다르고, 아무튼 border는 소수점 처리가 안 된다”며 직접 브라우저 개발자 도구를 통해 소수점이 적용되지 않는 모습을 보여줍니다.

단순히 "안된다"는 식의 설명보다 그 이유를 제대로 설명해줄 수 있었다면 협업이 더 매끄러웠을 것입니다. 이 글에서는 왜 적용이 안 되는 지를 파고들며 알게 된 서브 픽셀(sub-pixel)의 개념과, 이 기술이 CSS에 어떻게 적용되는지 정리해보려 합니다.

 

 

서브 픽셀 기술이란?

서브 픽셀이라는 단어는 말 그대로 “픽셀 내부의 더 작은 단위”를 뜻합니다. 우리가 흔히 쓰는 디스플레이의 한 픽셀은 대개 R(빨강), G(녹색), B(파랑)라는 세 가지 서브 픽셀이 합쳐져 하나의 색을 표현합니다. 웹 개발에서 서브 픽셀 기술이라고 하면 크게 두 가지로 나눠 설명할 수 있습니다.

  • 서브 픽셀 렌더링(Subpixel Rendering)
    : 텍스트 렌더링에서 픽셀 내부의 R/G/B 채널을 각각 조정해 해상도를 높이는 기법
  • 서브 픽셀 정밀도(Subpixel Precision)
    : CSS에서 요소의 위치, 크기, 그림자 등을 소수점 단위로 배치해 좀 더 부드럽게 렌더링하는 개념

위 두 용어가 비슷해 헷갈리지만, 사실 적용되는 대상과 원리는 조금 다릅니다.

 

 

서브 픽셀 렌더링 vs 서브 픽셀 정밀도

서브 픽셀 렌더링

주로 텍스트를 더 선명하게 표현하기 위해, 픽셀 내부의 R/G/B 서브 픽셀을 각각 다른 밝기로 조정하여 컬러 안티에일리어싱을 수행합니다. 한 픽셀 안에 미세한 색상 변화를 줌으로써 실제 해상도가 더 높은 것처럼 느끼게 만듭니다. 예를 들어 Windows의 ClearType은 이 기술을 활용해 텍스트를 또렷하게 표현합니다.

다만 서브 픽셀 렌더링을 적용할 경우, 글자 테두리에 빨간색·파란색 등이 살짝 번지는 느낌(컬러 프린징)이 나타날 수 있습니다. 이러한 부작용을 감수하는 대신 더 높은 해상도로 인식시키는 것이 서브 픽셀 렌더링의 핵심입니다.

 

서브 픽셀 렌더링 적용 사례

텍스트의 color, font-size, font-weight 등 글자 자체 속성을 조절하면 브라우저/OS가 자동으로 서브 픽셀 렌더링(컬러 안티에일리어싱)을 적용합니다. 다만, 요소에 transform: translateZ(0);opacity: 0.9;처럼 별도 합성 레이어가 생성되는 속성이 들어가면, 그레이스케일 안티에일리어싱으로 전환되는 등 동작이 바뀔 수 있습니다. (브라우저 엔진이 텍스트를 개별 레스터라이징하여 별도 레이어로 올리기 때문)

 

서브 픽셀 정밀도

CSS에서 요소의 위치나 크기를 소수점 단위(예: 0.5px)로 지정해, 화면 상에서 좀 더 부드러운 배치를 구현하는 개념입니다. (오피셜하게 존재하는 용어나 개념이라기 보다는, 텍스트 렌더링에 사용되는 서브 픽셀 렌더링 개념과 구분하기 위한 용어로 봐주시면 좋을 것 같습니다.) 브라우저는 내부적으로 부동소수점 연산을 수행하고, GPU 합성 단계에서 알파 블렌딩으로 가장자리를 처리하여 미세한 차이까지 표현합니다. 따라서 1px 단위보다 더 정교한 UI를 표현할 수 있다는 장점이 있지만, 실제 해상도(DPI)가 낮거나 브라우저 엔진에서의 안티에일리어싱 처리 로직에 따라 표현 결과가 다르게 나타날 수 있습니다. 또한, 극도로 미세한 소수점 단위(예: 0.05px)는 사람의 눈으로 체감하기 어려울 정도로 차이가 거의 없는 경우가 많습니다.

 

서브 픽셀 정밀도 적용 사례

아래는 서브 픽셀 정밀도를 활용하는 간단한 예시 코드입니다.

box-shadow: 0.5px 0.5px 2px rgba(0, 0, 0, 0.3);
transform: translate(0.5px, 0.5px);
width: 100.3px;
height: 200.25px;
  • box-shadow: 그림자 위치를 반 픽셀만큼 이동시켜 더욱 미묘한 음영을 줄 수 있습니다.
  • transform: 요소를 0.5픽셀만큼 옮겨서 부드러운 이동이나 정렬을 구현합니다.
  • width, height: 1픽셀보다 더 세밀한 요소 크기를 설정할 수도 있으나, 해상도나 브라우저에 따라 실제 체감은 미미할 수 있습니다.

정리

텍스트 렌더링에서의 R/G/B 각각을 제어하는 컬러 안티에일리어싱과 달리, CSS 도형이나 테두리나 그림자에서는 주로 알파(투명도) 기반 안티에일리어싱을 적용해 경계를 부드럽게 만들 뿐, 색상 채널을 개별적으로 조정하지는 않습니다.

두 용어 모두 픽셀보다 더 작은 단위를 다룬다는 점은 같지만, 적용 대상과 렌더링 원리는 다른 차이점이 있습니다.

이번 글에서는 컬러 안티에일리어싱, 알파 안티에일리어싱 등의 개념에 대해서는 깊이 다루지 않습니다.
기회가 된다면 다른 글에서 더 자세히 살펴볼 예정입니다.

 

 

서브 픽셀 정밀도가 중요한 CSS 속성들

CSS 속성 중 서브 픽셀 정밀도가 특히 유의미하게 작용하는 것들이 있습니다. 서브 픽셀 정밀도가 적용되는 속성과 그렇지 않은 속성을 간단히 알아보겠습니다.

적용되는 대표 속성들

box-shadow

  • 그림자 오프셋을 0.5px 단위로 지정하여, 미세하게 사선으로 이동하거나 흐릿함의 정도를 제어 가능
  • GPU가 그림자를 합성할 때 부동소수점으로 계산하므로, 실제 화면에서도 미묘한 차이의 표현이 가능

transform

  • translate(), scale(), rotate() 등에 소수점을 주면 요소가 그만큼 부드럽게 이동하거나 확대/축소됨

width, height

  • width: 100.5px;, height: 200.25px;처럼 정밀한 값 부여 가능
  • 브라우저에 따라 미세하게 알파 블렌딩이 적용되어, 1px과 2px 사이 정도의 너비가 표현될 수 있음
  • 저해상도(일반 DPI) 환경에선 차이가 미미하며, 고해상도(레티나) 환경에서 체감 가능

적용되지 않는 대표 속성들

border, outline

  • border: 0.5px solid #000; 등을 지정해도 브라우저가 제대로 렌더링하지 않는 경우가 많음
  • 저해상도 환경에서는 브라우저가 반올림하거나 흐릿하게 표현하여 사실상 1px 선과 큰 차이가 없음
  • 고해상도(레티나급)에서 일부 브라우저가 0.5px 테두리를 지원하기도 하지만, 이는 알파(그레이스케일) 기반 안티에일리어싱일 뿐이며, 정확히 0.5px가 표현된다고 장담할 수 없음

특정 합성 레이어 관련 속성

  • opacity, filter 등은 텍스트 서브 픽셀 렌더링뿐 아니라, 서브 픽셀 정밀도를 활용한 배치에 영향을 줌
  • 이러한 속성 적용 시, 해당 요소(또는 그 자식 요소)가 별도 합성 레이어로 올라가면서, 비트맵화될 가능성이 높음
  • 즉, 브라우저 엔진이 요소를 이미지처럼 취급하여 그레이스케일 안티에일리어싱만 적용하거나, 레이아웃의 소수점 정보를 제대로 반영하지 못할 수 있음
  • 0.5px 단위를 준다고 해도, 최종 렌더링에서는 해당 요소가 정수 픽셀 수준으로 딱딱 끊기거나, 흐릿하게 블렌딩되어 서브 픽셀 정밀도가 희미해질 수 있음

결국 CSS에서 서브 픽셀 정밀도를 활용하고자 한다면, 합성 레이어나 디스플레이 해상도 등 여러 요소를 함께 고려해야 합니다. 특별한 경우가 아니라면,UI 디자인에서는 정수 픽셀을 우선적으로 사용하는 편이 더 일관적인 UI를 보장한다고 볼 수 있습니다.

 

 

마무리

앞으로도 유사한 상황을 마주하게 된다면, 서브 픽셀 렌더링과 서브 픽셀 정밀도 개념을 기반으로 설명해보는 것은 어떨까요? 개발자와 디자이너 모두 서로 높은 완성도의 UI를 만들기 위해 노력하는 만큼, 충분하게 납득 가능한 설명이 더해진다면 더욱 매끄러운 협업이 가능할 것이라 생각합니다.

 

추가로 더 궁금하신 점이나, 잘못된 점 혹은 보완이 필요한 내용이 있다면 댓글로 의견을 주시면 감사하겠습니다.

 

 

참고

https://issues.chromium.org/issues/40359729

https://selosele.github.io/2020/02/16/sub-pixel-rendering/