ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CSS] 미디어 쿼리와 문제점
    프로그래밍/CSS 2024. 6. 8. 13:25
    개요

    1. 미디어 쿼리
    2. 다양한 CSS 기술
    3. 컨테이너 쿼리

     

    최근 몇년간 출시된 많은 CSS의 기능들은 특정 조건에서 적용되도록하는 모습을 보이고 있으며 이러한 상당수는 반응형 디자인과 직접적인 관계가 많은 것들이 있다. 이러한 부분에서 미디어 쿼리는 반응형 레이아웃에서 중요하게 여겨지지만 이러한 새롭게 출시된 CSS와 함께 사용함으로써 더욱 효과적으로 반응형 디자인을 할 수 있다고 한다.

     

     

    ✅ 미디어 쿼리 (Media Query)


     

    📦 미디어 쿼리(Media Query)란?

    CSS의 일부 기능으로 미디어 유형 혹은 특정 장치의 특성에 따라 스타일을 조건부로 적용하는 기능을 뜻한다. 이를통해 다양한 미디어 유형과 다양한 장치에 맞춤으로 스타일과 레이아웃을 조정할 수 있고 이러한 반응형 디자인은 더 나은 UX를 제공할 수 있게 한다.

     

    필요성

    • 모바일 디바이스의 확산에 따른 여러 화면과 디바이스에서 변형되는 레이아웃이 필요해지며 필요성이 대두 되었음(반응형 디자인)
    • 단순 뷰포트만 고려하는 것이 아닌 OS 선호도 및 입력 장치의 종류 등을 기반으로 접근성을 높이는 해결책 역할

    장점

    • 반응형 웹 디자인을 통한 UX 상승
    • CSS코드의 모듈화 및 조건부 적용을 통한 유지 보수성 및 가독성 상승

    단점

    • 디바이스의 상황에 맞는 스타일을 제공하기 위해 작성해야하는 코드량의 증가와 복잡성
    • 호환성에 대한 고려 및 성능에 대한 개선문제 고려
    • 적용하지 않은 경우와 비교해 유지 보수를 해야하는 요소가 많아지고 특정 화면 크기나 장치애 대한 꾸준한 고려가 필요


    📦 기존 문제점

    뷰포드만 고려하는 미디어 쿼리

    • 컴포넌트는 일반적으로 상대적으로 공간에 배치를 하기에 미디어 쿼리의 중단점(break point)로 사용되는 대부분인 witdh, orientaiton과 같은 뷰포트 속성만으로는 콘덴츠가 깨지는 문제 혹은 콘텐츠에 따른 새로운 중단점 설정 등의 문제가 생길 수 있다. 이는 미디어 쿼리는 컨텍스트를 설명하는 정보가 부족하기에 발생하는 문제입니다.

    힘든 관리

    • 컴포넌트는 단순히 부모-자식관계 뿐만아니라 다양한 방식으로 공간을 공유하고 있기에 개발자 입장에서 모든 것을 충족하는 최적의 지점을 찾기는 힘들다. 또한 이는 하드코딩된 값이고 컨텍스트마다 여러 미디어 쿼리가 필요하게 되므로 굉장히 ㄱ복잡해진다. 이러한 점은 스타일을 편집할 때 인스턴스의 수도 점점 많이지며 복잡해진단 것을 의미한다.

    만족스럽지 못한 반응

    • 구현한 반응형 디자인은 특정 고정된 수치를 기반으로 반응하는 일종의 적응형 디자인이며, 유동성이 없어 고려하지 못한 경우에는 그에 따라서 새롭게 스타일을 작성해야하는 고민거리가 생긴다.

     


     

    ✅ 발전된 기술


    2012년 이후 우리는 Flexbox, Grid, 반응형 단위, 수학 함수, 컨테이너 쿼리(초기 단계)와 같은 기술의 등장을 인해 사이즈 조절에 미디어 쿼리보다 나은 선택지가 생겼다. 


    📦 Flexbox

    기존에는 미디어 쿼리와 주로 같이 사용되는 Flexbox는 특정 방향으로 레이아웃을 설정하는 역할, 미디어 쿼리는 특정 뷰포트 너비일 때 방향을 바꾸거나 하는 역할로 나누어 사용이 되었다. 

     

    문제점

    • 뷰포트 너비만 고려하는 반응형 디자인 
    • 재사용과 관리의 어려움
    • 최적의 디바이스에 대한 설정을 모두 하지 않는다면 낮은 반응성을 갖는다.

    개선 후

    main {
      display: flex;
      flex-flow: row wrap;
    }
    
    main article {
      flex: 1 1 400px;
    }
    • Flexbox를 통해 요소에 400px의 너비를 가질 수 있게 하며 반응형으로 사용할 수 있는 공간에 따라서 조정을 할 수있게끔 구현을 하였다. 이는 단순히 중단점을 통한 반응형을 구현했을 때보다 훨씬 나은 모습을 가진다. (아티클 별로 반응형을 구현할 수 있다)

     

    📦 Grid

    Flexbox에 특정 너비값을 조정하고 미디어 쿼리를 다시 사용해야하는 경우도 생기는데 Gird를 통해서 더 나은 코드를 구현할 수도 있다

     

    구현 코드

    main {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
    }
    • Flexbox에서 구현했던 것에서 너비값을 추가로 구현한 형태이다. 실제로 더 짧고 간단해진 코드로 구현할 수 있었다.

     

    📦 수학 함수와 반응형 단위

    min(), max(), clamp()와 같은 수학함수와 vw, vh와 같은 반응형 단위를 통해서 크기 조정과 관련된 대부분의 문제를 해결할 수 있고 중단점을 통해 어렵게 정의하지 않고도 반응형 제한을 설정할 수도 있다.
    • 하한값 또는 상한값을 조절하거나 너비에 따른 높이를 조정할 수 있는 aspect-ratio와 같은 다양한 함수들을과 속성들을 통해서 좀 더세밀하게 반응형 디자인을 구현할 수 있다.

     

    예시

    .min {
      height: 400px;
      width: min(100%, 300px);
    }
    
    .min-and-aspect-ratio {
      aspect-ratio: 1/1; /* or 1 */
      width: min(100%, 300px);
    }
    
    .max {
      height: 400px;
      width: max(50%, 300px);
    }

     

    수학함수와 미디어 쿼리의 조합

    • 디바이스에 따른 반응형 웹을 만들기 위해서 반응형 단위와 수학 함수만으로는 부족한 것이 있으며, 그렇기에 미디어 쿼리와 함께 사용하면서 다양한 기능을 구현할 수 있다.
    • font-size: 뷰포트 너비에 따른 지정도 괜찮지만 미디어 쿼리를 통해서 특정 너비의 값에 따라서 font-size를 변경할 수도 있다.
    h1{
      font-size: clamp(36px, 6vw, 48px);
    }
    
    h2{
      font-size: clamp(22px, 4vw, 28px);
    }
    
    p{
      font-size: clamp(16px, 3vw, 18px);
    }
    • 이뿐만아니라 rem이나 clamp함수를 통해서도 구현할 수 있다.
    html{
      font-family: arial;
      font-size: clamp(12px, 2vw, 18px);
    }
    
    
    h1{
      font-size: 3rem
    }
    
    h2{
      font-size: 1.8rem;
    }
    
    p{
      font-size: 1.2rem;
    }
    
    .samesize{
      font-size: 18px;
    }

     


     

    ✅ 컨테이너 쿼리


    미디어 쿼리가 페이지 전체의 레이아웃을 수정하는 것에 유리하다는 사실은 명확하다 뷰포트 너비가 충분하다면 공간의 배치도 여유롭게 처리할 수 있다. 하지만 동일한 레이아웃을 모바일에서 작동하게 하려면 여러 반응형 부분에서 문제가 있고 이러한 문제를 적은 노력으로 해결할 수 있는 기술이 컨테이너 쿼리이다.


    📦 컨테이너 쿼리란?

    기존에는 미디어 쿼리가 뷰포트의 크기를 기준으로 반응형 디자인을 제작하는 것에 비해 컨테이너 쿼리는 특정 html 요소를 기준으로 반응형 디자인을 제작하게 된다.

     

    사용법

    • size: 인라인 및 블록 기반으로 동작하는 컨테이너 쿼리는 컨테이너에 레이아웃, 스타일 및 크기를 포함해야 한다.
    • inline-block: 컨테이너의 인라인 크기를 기반으로 하기에 요소에 레이아웃, 스타일 및 인라인 크기 포함을 적용해야 한다.
    • normal: 요소는 모든 컨테이너 크기 쿼리에 대한 쿼리 컨테이너가 아니지만 컨테이너 스타일 쿼리에 대한 쿼리 컨테이너로 유지된다.
    <div class='card-container'>
      <div class="card">
        <div class="card-header">
          <img
            src="https://images.unsplash.com/photo-1682289571752-c14e69310e64?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80"
            alt="Nice image" />
        </div>
    
        <div class="card-body">
          <p>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Et voluptate itaque neque totam quod vitae mollitia beatae blanditiis saepe quaerat porro, laborum quasi accusamus voluptates consectetur ipsam tempora, possimus modi.
          </p>
          <button>Details</button>
          <button>Contact me</button>
        </div>
      </div>
    </div>
    
    .card-container {
      container-type: inline-size;
    }
    
    .card {
      display: flex;
      flex-direction: row;
      gap: 1rem;
      border: 1px solid #ccc;
      padding: 1rem;
    }
    
    .card-header {
      max-width: 400px;
    }
    
    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    
    @container (max-width: 500px) {
      .card {
        flex-direction: column;
      }
    }
    • 브라우저 뷰포트가 아닌 특정 크기를 기준으로 욧 스타일을 지정할 수 있고 이러한 것을 통해 반응형 요소를 상세하게 지정할 수 있다. 또한 컨테이너 쿼리에서 새롭게 사용할 수 있는 단위(cqw, cqh...)도 있다
    • IE를 제외한 대부분의 브라우저에서 호환이 가능하나 미디어 쿼리를 완전히 대체하기보다는 혼용해서 사용하는 것을 좀 더 추천하는 커뮤니티가 많다.

     


    반응형에 대해 어떻게 구현하는 것이 가장 효율적인 것인가라는 생각을 가지고 해당 아티클을 읽어보았다. 읽기 전에는 미디어 쿼리를 사용한 서비스가 완전히 반응형까지 구현했다고 생각하고 있었기에 이러한 생각을 뒤집을 수 있는 좋은 기회였다. 단순히 미디어쿼리 뿐만아니라 기존에 사용하고 있던 flex, grid를 비롯한 수학 함수와 반응형 단위를 통해서 더욱 효과적이고 반응성 좋은 서비스를 만들 수 있게 생각이 확장된 좋은 글이였다. 또한 호환성에 문제가 없는 컨테이너 쿼리 또한 프로젝트에 적용해보면서 UX에 대해서 고민을 많이할 수 있는 기회가 되었으면 좋겠다.

     

     

    📌 Reference 

    댓글

Designed by Tistory.