CSS 변수 - 변수(Variable)로 반응형 웹 구현

반응형 웹을 구현하는 방법은 여러가지가 있습니다.

대표적인 방법은 미디어쿼리 (@media())를 사용하는 방법이며, 미디어쿼리에 해상도별, 또는 디바이스별 CSS를 재정의하게 됩니다.

변수를 이용하면 재정의하는 미디어쿼리 CSS를 획기적으로 단축할 수 있으며, 레이아웃 관리도 간편하게 할 수 있습니다.

짧게 구성한 홈페이지 HTML 내용은 다음과 같습니다.

<!DOCTYPE html>
<html lang="en">
<body>
    <header>
        <ul id="navbar" class="menu">
            <li>홈</li>
            <li>상품</li>
            <li>오시는길</li>
            <li>문의</li>
        </ul>
    </header>
    <main>
        <div class="content">
            <div class="item"><h2>커피</h2><button>상세보기</button></div>
            <div class="item"><h2>음료</h2><button>상세보기</button></div>
            <div class="item"><h2>케잌</h2><button>상세보기</button></div>
            <div class="item"><h2>굿즈</h2><button>상세보기</button></div>
        </div>
    </main>
    <footer>
        <p>Copyright 2020 Baristas All right reserved.</p>
    </footer>
</body>
</html>

다음과 같은 CSS 레이아웃을 적용하면

:root{
    --textcolor: #484848;
    --hover: #080;
    --pagebgcolor: #fff;
    --bgcolor: #f0f0f0;
    --buttonbg: #e0e0e0;
}
html, body{
    color: var(--textcolor);
    background-color: var(--pagebgcolor);
}
header, main, footer{
    display: block;
    max-width: 933px;
    margin: 0 auto;
    box-sizing: border-box;
    background-color: var(--bgcolor);
}
.menu{
    display: grid;
    list-style: none;
    text-align: center;
    margin: 0;
    padding: 0;
}
.menu li{
    font-size: 1.125em;
    font-weight: bold;
    grid-area: 1;
    padding: 1.25em 0;
}
.content{
    display: grid;
    grid-template-columns: 49% 49%;
    column-gap: 2%;
    row-gap: 1em;
    width: 100%;
    padding: 20px;
    box-sizing: border-box;
}
.content .item{
    display: inline-block;
    text-align: center;
    padding: 3em 0;
    background-size: cover;
    border-radius: 2em;
}
.content .item:nth-child(1){background-image: url(./backup/828/img/var1.jpg);}
.content .item:nth-child(2){background-image: url(./backup/828/img/var2.jpg);}
.content .item:nth-child(3){background-image: url(./backup/828/img/var3.jpg);}
.content .item:nth-child(4){background-image: url(./backup/828/img/var4.jpg);}
.content .item button{
    background-color: var(--buttonbg);
    color: var(--textcolor);
    padding: 1em 3em;
    border: 0;
    font-size: 1.125em;
    font-weight: bold;
}
.menu li:hover, .content .item button:hover{
    color: var(--hover);
    cursor: pointer;
}
footer{
    padding: 1em 0;
    text-align: center;
}

다음과 같은 간단한 웹페이지가 만들어집니다.

완성된 HTML 웹페이지

본문의 2x2로 표시되는 컨텐츠 내용은 레이아웃 너비가 줄어드는데 따라서 너비가 자동으로 줄어들기는 하지만, 모바일에서 좀 더 보기 좋도록 한 줄에 1개씩 박스가 표시되도록 변수를 사용해 레이아웃을 바꿔보겠습니다.

컨텐츠 영역의 그리드 설정 값은 다음과 같습니다. "grid-template-columns" 속성에 그리드가 한 행에 2개씩 표시되도록 퍼센트 값을 설정했습니다.

.content{
    display: grid;
    grid-template-columns: 49% 49%;
    column-gap: 2%;
    row-gap: 1em;
    width: 100%;
    padding: 20px;
    box-sizing: border-box;
}

미디어쿼리로 반응형 레이아웃을 만들기 위한 변수명 "--grid" 를 ":root" 가상 클래스에 선언해 전역으로 사용할 수 있도록 하고 "grid-template-columns" 속성 값을 선언한 변수로 변경합니다.

:root{
    --grid: 49% 49%; /* 기본 그리드 값으로 변수 선언 */
}
.content{
    display: grid;
    grid-template-columns: var(--grid); /* 그리드 변수로 속성값 변경 */
    column-gap: 2%;
    row-gap: 1em;
    width: 100%;
    padding: 20px;
    box-sizing: border-box;
}

가로 너비가 600px 이하면 모바일 레이아웃으로 변경이 되도록 하기로 하고 다음과 같이 미디어쿼리를 작성해 CSS 파일 하단에 추가합니다.

@media screen and (max-width:599px){
    :root{
        --grid: 100%;
    }
}

웹 브라우저 너비사 600px 미만이 되면 "--grid" 변수 값이 오버라이딩(Overriding) 되면서 그리드 너비가 100% 가 되고, 한 행에 1개씩 아이템이 표시되게 됩니다.

미디어 쿼리로 ".content" 클래스를 재정의 할 필요 없이 변수 값만 조정해주면 되기 때문에 더 적은 CSS 코드량으로 복잡한 반응형 레이아웃을 만들 수 있습니다.