4 minute read

반응형 웹

사용자의 화면 크기에 맞춰 내부의 요소의 크기가 변하는 것을 반응형 웹 (Responsible Web)이라고 한다.

1. 단위 사용

 일반적으로 웹 퍼블리셔가 만드는 디자인 파일은 단위가 px로 되어 있다. 이를 그대로 CSS에 반영해도 되겠지만, px 단위를 그대로 사용하는 것은 부적절하다. px은 화면 상의 픽셀 크기를 고정해버리기 때문에 화면의 크기가 바뀌어도 요소의 크기가 변하지 않아야 하는 경우에 적합하다. px 단위는 절대적인 크기가 필요한 경우에 알맞는 단위이다.

 이를 대체할 수단으로 사용할 수 있는 단위가 remem이다. rem은 root element의 약자로, 최상위 블록인 html 태그에 정해진 font-size를 기준으로 크기를 결정한다. 만약 html 태그에 정의된 font-size가 16px이라면 1rem은 16px, 2rem은 32px이다.

 전체적인 CSS에 px 대신 rem 단위를 쓰는 이유는 간단하다. 모든 요소의 크기를 px 단위로 만든다면 크기를 수정해야 할 때 각각의 요소에 있는 사이즈를 일일이 수정해줘야 한다. 반대로 모든 요소의 크기를 rem으로 만든다면, 일일이 수정할 필요 없이 html의 font-size만 수정해주면 끝이다.

 이와 비슷한 단위인 em은 element의 약자인데, html의 font-size가 아니라 부모의 font-size를 기준으로 한다. rem의 경우 html의 font-size를 바꾸면 전역적으로 그 스타일이 적용되지만, em의 경우는 부모의 font-size에 따라 스타일이 적용되기에 더 유연하게 사용이 가능하다.

 또 다른 단위로 vwvh가 있다. 이 두 단위는 뷰포트 (viewport, 사용자가 보는 화면 사이즈)를 기준으로 한다. vw는 화면의 가로 사이즈를 기준으로 한 비율이며 vh는 화면의 세로 사이즈를 기준으로 한 비율이다. 100vw는 화면 가로 사이즈, 100vh는 화면 세로 사이즈이다.

 이 외에도 부모의 크기를 기준으로 사이즈를 결정하는 %가 있다. 일반적으로는 px을 대체하기 위한 단위로 rem과 em을 주류로 사용하지만, %의 경우에는 사이즈가 부모를 기준으로 한 비율일 때 적절하다.

기본 단위로는 rem 사용, 나머지는 상황에 맞게!


2. 단위 사용 (심화)

 단순히 단위만 맞춰 쓰는 게 아니라, 더 복잡한 계산을 통해 사이즈를 알맞게 만들 수 있는 방법이 존재한다.

 calc() 함수는 사이즈 끼리의 연산을 가능하게 한다. 예를 들어 화면의 총 가로 사이즈보다 40px 작은 크기가 필요하다면? calc(100vw - 40px) 과 같은 식으로 적을 수 있다. calc()를 사용하면 단위를 여러 개 조합해서 사이즈를 만들 수 있게 된다.

 또 다른 유용한 함수로 clamp()가 있다. 반응형 웹을 만들다 보면 요소의 크기가 원하지 않을 정도로 작아지거나 커지는 상황이 발생한다. 특히 vw, vh, %와 같은 비율 관련 함수를 쓸 때 더욱 그렇다. calc()를 사용하다 보면 복잡한 계산을 하다 보니 요소의 크기가 원하는 크기를 벗어나는 것을 계산하기 어렵다. 이때 clamp() 함수는 요소의 최소 사이즈와 최대 사이즈를 제한해주는 역할을 한다. clamp(최소 사이즈, 권장 사이즈, 최대 사이즈) 로 사용하는데, 최소 사이즈 ~ 최대 사이즈를 벗어나지 않는 선에서 권장 사이즈가 적용된다. 예를 들어서 clamp(200px, 25vw, 300px)은 기본적으로 25vw 사이즈를 적용하지만, 화면의 크기가 바뀌어도 200px ~ 300px을 벗어나지 않는다.


 앞서 사이즈의 기본 단위로는 rem을 쓴다고 했는데, 이는 html 태그의 font-size 기준이다. html 태그의 기본 font-size는 16px이다. UI 디자인에서는 8pt 그리드 시스템을 사용하기도 하므로 16px을 그대로 사용해서 계산을 해도 좋지만, 매번 rem 단위를 쓸 때마다 16px을 기준으로 해서 계산을 하는 것은 매우 번거로운 일이다. 따라서 rem을 그대로 사용하되, html 태그의 font-size를 변경하여 사용하기 편하게 만들 수 있다.

 rem 단위를 사용할 때는 html 태그의 font-size를 62.5% 로 설정해 주는 것이 좋다. 이는 10px과 동등한 사이즈이다. 따라서 앞으로 1rem을 사용할 때는 10px이 적용되는 것이므로, 원하는 사이즈를 쉽게 계산해서 쓸 수 있게 된다. font-size를 10px이 아니라 굳이 62.5%로 설정한 것은 브라우저의 기본 폰트 크기를 사용할 수 있게 하기 위함인데, 사용자가 어떻게 설정하느냐에 따라서 브라우저의 기본 폰트 사이즈를 변경해 둘 수 있다. 그런데 font-size를 10px로 적어 버리면 사용자의 설정을 무시하고 10px이 고정으로 적용된다. 62.5%와 같이 비율을 사용하면 사용자가 설정한 브라우저 기본 폰트 크기에 맞춰서 유동적인 사이즈를 적용할 수 있다.


3. Flex 또는 Grid 사용

 사이즈를 결정할 때 width나 height에 의존하는 것이 아닌, flex나 grid를 통해서 더 레이아웃에 친화적인 사이즈를 만들어낼 수 있다. 보통 flex는 요소들을 한 줄로 배치할 때 강력하고, grid는 행과 열을 이용하여 요소들을 배치하는 데 효과적이다. 이 두 가지를 조합해서 사용하는 게 좋은 방법인데, grid로 전체적인 레이아웃을 만들어 놓고, 그 안에 한 줄로 배치해야 하는 요소들이 있다면 거기에 flex를 적용하는 것이다.

 먼저 그리드를 적용하는 방법은 display: grid를 사용하는 것이다. display 속성을 grid로 설정하면 해당 요소가 그리드 컨테이너가 된다. grid-template-columns와 grid-template-rows를 통해 내부의 레이아웃을 설정할 수 있다. 예를 들어 grid-template-columns: 100px 100px 200px; 을 적용한다면 각각의 column이 100px, 100px, 200px 크기로 설정된다.

 여기에서 유용하게 사용할 수 있는 것이 바로 fr 단위이다. fr은 fraction의 약자로, 이것을 이용해 비율에 맞춘 레이아웃을 만들어낼 수 있다. 예를 들어 grid-template-columns: 1fr 1fr 2fr 500px; 을 적용한다면 전체 사이즈에서 500px을 빼고, 나머지 남는 구역을 각각의 column이 1:1:2의 비율로 나눠 가진다.

 추가적으로 알고 있으면 좋은 함수가 바로 repeat()인데, 앞에 들어오는 파라미터가 반복 횟수, 뒤에 들어오는 파라미터가 크기이다. 예를 들어 repeat(5, 1fr) 이라고 적으면 1fr이 5번 반복된다.

 여기에 minmax() 함수를 적용하는 것도 유용한데, minmax() 함수는 최소값과 최대값을 설정할 수 있게 해주는 함수이다. 예를 들어 minmax(100px, auto) 라고 적으면 최소한 100px, 최대는 자유롭게 늘어나도록 사이즈가 설정된다.

 repeat() 함수를 응용해서 사용할 수 있는 방법 중에 auto-fillauto-fit을 사용하는 방법이 있다. 반복 횟수를 뜻하는 앞쪽 파라미터에 숫자 대신 auto-fill을 적으면, 개수가 미리 정해지지 않고 채울 수 있는 만큼 채워지게 된다. 예를 들어 repeat(auto-fit, 500px) 을 사용하면 500px로 채울 수 있는 개수만큼 반복되게 된다. auto-fill과 auto-fit은 모두 채울 수 있는 만큼 반복을 해서 채운다는 공통점이 있지만, 남는 공간을 어떻게 처리하느냐에서 차이가 생긴다. auto-fill은 남는 공간을 빈 칸처럼 남겨두는 반면, auto-fit은 기존 칸을 늘려서 빈 공간이 없도록 채워버린다. 따라서 repeat(auto-fit, minmax(200px, 1fr)) 과 같이 활용하면 빈 공간 없이 레이아웃을 꽉 채울 수 있다.

 그 다음으로, 여러 요소를 한 줄로 배치해야 할 때는 Flexbox가 더 강력하다. 이를 적용하는 방법은 display: flex;를 쓰는 것인데, 그러면 해당 요소가 flex 컨테이너가 된다.

Updated: