CSS 반응형 웹, 미디어 쿼리(Media Query)와 뷰포트(Viewport) 메타 태그

포스트 썸네일 이미지

이전 포스트에서는 '멀티 컬럼'을 통해 텍스트 흐름을 제어하는 법을 알아보았다.

오늘의 포스트에서는 웹사이트 전체가 기기 화면 크기에 맞게 변화하는 방법을 알아보겠다.


반응형 웹의 핵심인 미디어 쿼리Media Query의 기본 개념을 익히고, 이전에 만든 Holy Grail 레이아웃을 모바일에 최적화된 형태로 변신시켜 보자.




이전 포스트




생활코딩 CSS 수업 영상: Media Query 기본





1. 반응형 웹(Responsive Web)이란?

반응형 웹Responsive Web은 하나의 웹사이트가 접속하는 기기(PC, 태블릿, 스마트폰 등)의 화면 크기에 반응하여 레이아웃을 스스로 바꾸는 것을 말한다.


  • 과거 방식: PC용 사이트와 모바일용 사이트(m.daum.net 등)를 따로 만들었다. 관리하기가 매우 번거로웠다.
  • 반응형 방식: 코드는 하나만 짜고, 화면 너비에 따라 CSS만 다르게 적용한다. 유지보수가 쉽고 사용자 경험이 일관적이다.



2. 미디어 쿼리(Media Query)란?

미디어 쿼리Media Query는 반응형 웹을 가능하게 하는 '조건부 CSS'다.

브라우저에게 "만약 화면 너비가 특정 사이즈 이하라면, 이 스타일을 적용해."라고 명령하는 것이다.


위의 생활코딩 수업 영상에서 사용한 코드를 확인해 보자.





<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        @media (max-width:600px) {
            body {
                background-color: green;
            }
        }
        @media (max-width:500px) {
            body {
                background-color: red;
            }
        }
        @media (min-width:601px) {
            body {
                background-color: blue;
            }
        }
    </style>
</head>
<body>
    <ul>
        <li>~500px : red</li>
        <li>501~600px : green</li>
        <li>601px~ : blue</li>
    </ul>
</body>
</html>




3. 미디어 쿼리의 코드

  • @media: Media Query의 시작을 알린다.
  • max-width: "최대 이 너비까지는(지정한 px 값 이하일 때는) 이 스타일을 적용해" (주로 모바일 스타일을 입힐 때 사용)
  • min-width: "최소 이 너비부터는(지정한 px 값 이상일 때는) 이 스타일을 적용해" (주로 큰 화면 스타일을 입힐 때 사용)




캐스케이딩Cascading에 의해서 아래에 있는 코드를 더 우선시한다.




4. Viewport 메타 태그

미디어 쿼리가 반응형 웹의 엔진이라면, 뷰포트 메타 태그는 그 엔진에 정확한 데이터를 전달하는 센서와 같다.


<meta name="viewport" content="width=device-width, initial-scale=1.0">

이 코드가 있어야 미디어 쿼리가 제대로 작동한다.

현대의 웹사이트에는 반드시 들어가야 하는 필수적인 코드라고 생각하자.





생활코딩 CSS 수업 영상: Media Query 응용





이전에 Flexbox를 이용해서 Holy Grail 레이아웃을 만들었었다.

그때의 코드를 다음과 같이 수정했다.




<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        .container {
            display: flex;
            flex-direction: column;
        }
        header {
            border-bottom: 1px solid gray;
            padding-left: 20px;
        }
        footer {
            border-top: 1px solid gray;
            padding: 20px;
            text-align: center;
        }
        .content {
            display: flex;
        }
        .content nav {
            border-right: 1px solid gray;
        }
        .content aside {
            border-left: 1px solid gray;    
        }
        @media(max-width: 500px) {
            .content {
                flex-direction: column;
            }
            .content nav, .content aside {
            border: none;
            flex-basis: auto;
            }
            main {
                order: 0;
            }
            nav {
                order: 1;
            }
            aside {
                order: 2;
            }
        }
        nav, aside {
            flex-basis: 150px;
            flex-shrink: 0;
        }
        main {
            padding: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>생활코딩</h1>
        </header>
        <section class="content">
            <nav>
                <ul>
                    <li>html</li>
                    <li>css</li>
                    <li>javascript</li>
                </ul>
            </nav>
            <main>
                Lorem ipsum dolor sit amet consectetur, adipisicing elit. Minus ipsam reiciendis voluptates soluta delectus, quo at tenetur numquam illum possimus a quia! Aperiam perferendis error deserunt amet fuga, porro deleniti quos, optio saepe veniam ipsum suscipit voluptate expedita facilis quidem, nisi provident commodi libero aliquid assumenda repellendus. Harum temporibus distinctio, dolor neque ut laudantium reprehenderit praesentium molestiae deleniti officia vel ea provident, quaerat tempora facilis quasi non eaque aliquam optio vitae, aut consequatur rerum eius? Blanditiis necessitatibus ad tenetur deserunt, vel impedit, doloremque ab est debitis sed minima possimus et suscipit, rem ipsa odio soluta ipsum at dolores alias recusandae? Dolores iste harum fugiat magni voluptates necessitatibus molestias accusantium officia doloremque aperiam provident, laboriosam facere, vel, et hic unde perspiciatis quisquam ea minus dicta. Aut neque doloribus iusto laborum cumque. Nobis asperiores, odio rem dignissimos a deserunt unde eaque esse atque qui consectetur illum id minus est quae assumenda aut modi velit consequuntur necessitatibus dolorem error provident soluta! Molestiae unde nihil voluptate consectetur ducimus qui rem iusto deleniti excepturi. Tenetur, sapiente reiciendis, consectetur eum dolor eos quaerat mollitia esse facere aperiam quos quidem! Porro dignissimos corporis iure? Cupiditate, odio dignissimos molestias illum quos eum nihil tempore atque non doloribus exercitationem, perspiciatis assumenda esse autem expedita dolorem et architecto sint. Consequatur eos inventore natus atque debitis pariatur fuga culpa rem delectus enim incidunt quod sit, vero tempore sequi cupiditate voluptatem aliquid distinctio cumque a quasi nobis quidem? Iste quam ab adipisci perspiciatis sunt cum quia, eius repellendus in! Adipisci esse tenetur quas, labore sequi assumenda maxime, placeat, delectus reiciendis mollitia nesciunt doloribus. Cum, nam natus? Ex molestias cum aliquid sed autem non minima officiis ipsum magni corporis nam vitae quam, dignissimos veritatis ipsa velit. Natus vitae exercitationem deleniti incidunt, itaque esse, maiores expedita ex consequatur, sapiente repellat quam non reprehenderit eligendi ipsa sunt modi libero! Quasi, nobis neque distinctio harum ad veniam enim dolorem eum eligendi voluptatibus voluptas fuga veritatis tempore.
            </main>
            <aside>
                AD
            </aside>
        </section>
        <footer>
            <a href="https://opentutorials.org/course/1">홈페이지</a>
        </footer>
    </div>
</body>
</html>

코드 상단에 <meta name="viewport" content="width=device-width, initial-scale=1.0">가 추가되었다.

앞서 설명한 것처럼, 이 코드가 있어야만 아래에 작성한 미디어 쿼리가 모바일 기기에서 정상적으로 작동한다.


@media(max-width: 500px) { ... }로 인해 화면 너비가 500px 이하가 되었을 때의 동작이 정의되었다.

.contentflex-direction이 기본값(row)에서 column으로 바뀌면서 방향이 전환된다.

즉, PC에서는 [메뉴 | 본문 | 광고]가 가로로 나란히 보이다가, 모바일(500px 이하)에서는 위아래로 쌓이게 된다.


flex-basis: auto;border: none;을 통해 고정되어 있던 메뉴 너비를 풀고 구분선을 제거하여 모바일 화면에 최적화했다.


order 속성을 이용해서 모바일 화면에서는 메인 콘텐츠를 맨 위로 올렸다.




다음 포스트

이 글이 도움이 됐거나 유익했다면 스크롤을 조금만 더 내려서 댓글을 남겨주세요. (비로그인도 가능합니다!)
응원이나 피드백이 담긴 댓글은 제가 계속 블로그를 해나갈 수 있는 원동력이 됩니다. 😊

지인에게 보여주고 싶은 글이었다면 URL을 복사해서 메신저나 소셜 미디어에 공유해 주세요.

댓글 쓰기

0 Comments

문의하기 양식