8/18/2018

사이트 및 블로그의 기본 레이아웃 만들기

사이트 또는 블로그의 레이아웃을 만들어보겠습니다.

일반적인 레이아웃은 상단/중단/하단으로 나누어지며, 상단엔 사이트의 제목과 주요 메뉴가 있고, 중단은 본문 영역과 메뉴 영역으로 나뉘게되며, 하단엔 사이트에 대한 정보가 있습니다.

대략 이런 구성으로 되어있지요.

사이드바(side bar)가 오른쪽이 아닌 왼쪽에 있을 수도 있고, 양쪽에 다 있을 수도 있고, 버튼을 누르면 나타나는것도 있습니다.

이 게시물에서는 일반적인, 사이드바가 오른쪽에 있는 경우만을 예로 들었습니다. 왜 사이드바가 오른쪽에 있냐면, 개인적인 생각이지만 보통 글을 읽을 때 왼쪽부터 오른쪽으로 읽으며 오른쪽 끝까지 읽었다면 다음줄의 왼쪽부터 오른쪽까지 읽게 됩니다. 즉, 왼쪽이 '시작'이 되기 때문이며, 일반적으로 무언가 볼 때 왼쪽 상단부터 보게됩니다. 그렇기 때문에 본문이 중심이라면 본문을 왼쪽에 두겠다는게 제 생각입니다.

또한 부득이하게 CSS나 Java script가 작동되지 않을 경우나 2단 레이아웃에서 1단 레이아웃으로 변경될 경우, 사이드바보다 본문이 위에있는게 사용하기 편리하므로 본문을 먼저 작성하게되며, 먼저 작성하게되면 왼쪽에 위치하게 됩니다. 물론 이 설정은 바꿀 수 있습니다.

먼저 기본적인 HTML파일을 생성합니다.

<!doctype html>
<html>
<head>
    <title>레이아웃</title>
</head>
<body>
<div id="wrap">
    <header id="header">
        <h1>#사이트 제목</h1>
    </header>
    <nav id="nav">
        <ul>
            <li>메뉴 1</li>
            <li>메뉴 2</li>
            <li>메뉴 3</li>   
        </ul>       
    </nav>
    <section id="container">
        <div class="content">
            <article>
                # 본문
            </article>           
        </div>
        <aside id="aside">
            # 사이드바
        </aside>
    </section>
    <footer id="footer">
        # 푸터       
    </footer>
</div>
</body>
</html>

HTML파일을 열어보면 심심한 화면을 볼 수 있습니다.

이제 각 요소들을 구분할 수 있게 CSS를 적용합니다. CSS는 <head> ~ </head>내부의 <style> ~ </style>의 내부에 작성합니다.

<style>
        div#wrap { background:#ddd; }
        header#header { background:#fdd; }
        nav#nav { background:#dfd; }
        section#container { background:#ddf; }
            div.content { background:#eee; }
            aside#aside { background:#fef; }
        footer#footer { background:#ffe; }
       
        div#warp, header#header, nav#nav,
        section#container, div.content, aside#aside,
        footer#footer { padding:10px; }
     
        nav#nav ul { margin:0; padding:0; list-style:none; }
        nav#nav ul li { background:#eee; padding:10px; display:inline-block; }
</style>

이제 배경색이 적요되어서 어떤 구조로 되어있는지 알기 쉽게되었습니다.

이제 레이아웃을 위한 플롯(float) 속성을 부여합니다. 가로(width)는 어느정도 여유있게 설정합니다.

div.content { width:60%; float:left; }
side#aside { width:30%; float:right; }

서로 다른줄에 위치하던 본문과 사이드바가 같은 줄에 위치하게되었습니다.

하지만 레이아웃이 깨졌습니다. 본문과 사이드바가 본문과 사이드바를 묶어주는 연파랑색 블록을 벗어난데다가, 푸터 앞에 있는 샵(#)마크가 본문과 사이드바 사이에 들어가있습니다.

플롯(float) 속성을 사용한후에는 항상 초기화를 해줘야 이런 오류가 발생하지 않습니다.

section#container::after { content:""; display:block; clear:both; }

여기서 핵심은 clear:both; 입니다. 이 속성을 설정해야만 플롯이 초기화됩니다.

::after은 선택자의 마지막에 적용되는 CSS입니다. 특이하게 실제로 HTML에 포함되지 않았으나, 마치 HTML에 포함된것 처럼 작동합니다. 이것을 '가상 요소'라고 합니다.

나중에 사용할 가상 선택자도 비슷한건데, 가상 선택자와 가상 요소의 차이는 콜론의 갯수 차이입니다. 둘다 1개 또는 2개씩 사용해도 작동은 되지만, 개발자가 구분하기 쉽도록 가상 선택자는 콜론이 1개, 가상 요소는 콜론을 2개 사용합니다.

아직 그렇게 중요한 사항은 아닙니다.

이제 HTML파일을 열어보면, 레이아웃이 깨지지 않고 잘 적용되고 있는걸 볼 수 있습니다.

가상 요소는 이렇게 은그슬쩍 HTML에 끼어들어가 있습니다.

가상 요소를 사용하지 않고, 직접 코드를 추가하는 방법도 있습니다.

<div style="clear:both;"></div>

결과는 똑같지만, 직접 코드를 추가하는 경우 HTML내부에 무의미한 코드가 있는것이므로 추천하지 않습니다. 이 말은 틀렸다는 말이 아니고, 개인적으로 가상 요소를 이용하는 방법을 추천한다는 얘기입니다.

이제 div#wrap와 div.content, aside#aside에 가로(width)속성을 설정합니다.

<style>
    div#wrap { width:900px; margin:0 auto; background:#ddd; }
    header#header { background:#fdd; }
    nav#nav { background:#dfd; }
    section#container { background:#ddf; }
        div.content { height:250px; background:#eee; }
        aside#aside { height:250px;background:#fef; }
    footer#footer { background:#ffe; }

    div#warp, header#header, nav#nav,
    section#container, div.content, aside#aside,
    footer#footer { padding:10px; }

    nav#nav ul { margin:0; padding:0; list-style:none; }
    nav#nav ul li { background:#eee; padding:10px; display:inline-block; }

    /* ---------- */

    div.content { width:600px; float:left; }
    aside#aside { width:220px; float:right; }

    section#container::after { content:""; display:block; clear:both; }
</style>

흔히 볼 수 있는 사이트의 구성과 같습니다.

하지만 브라우저의 크기를 줄이거나, 스마트폰 또는 태블릿을 이용하여 접속하면 스크린 크기의 문제로 한번에 모두 볼 수 없고 이렇게 가로나 세로에 스크롤바가 생깁니다.

스크롤은 옮기면 되지만, 휴대기기에서 이를 사용하기엔 몹시 어렵습니다.

여기에서 미디어쿼리가 사용됩니다.

@media screen and (max-width: 910px) {
    div#wrap { width:calc(100% - 20px); }
    div.content { width:calc(100% - 20px - 240px - 20px); }
    aside#aside { width:220px; }
}

브라우저의 가로 크기가 미디어쿼리의 조건부에 있는 가로 크기만큼이 되면, 내부에 있는 CSS가 작동되는 원리입니다.

이를 제대로 사용하기 위해선 메타 태그(meta tag)를 사용해야하지만, 이 게시물에서는 일단 없는대로 진행하겠습니다.

위의 미디어쿼리를 설명하자면, 브라우저의 가로 크기가 910px이 될 경우, div#wrap의 가로 크기를 '최대 가로 크기 - 20px'로 변경, div.content 가로 크기를 '최대 가로 크기 - 20px - 240px - 20px'로 변경하는것 입니다.

좀 햇갈리는데, div.content는 최대 넓이에서 여백인 20px을 빼주고, 사이드바의 길이인 240px을 빼줍니다. 이렇게만하면 div.content가 aside#aside와 딱 붙게되니까, 20px을 더 빼줘서 사이에 공간을 만듭니다.

CSS에서 계산이 필요할 땐 calc()를 이용하여 합니다. 여기서 20px를 빼는 이유는, 내부여백(padding)만큼을 빼기 위함입니다.

이제 브라우저의 크기가 줄어들기 때문에 휴대기기로 접속해도 스크롤이 생기지 않습니다. 하지만 그 크기가 너무 작아지게되면 본문의 크기가 불편할 정도로 작아지기 때문에, 본문과 사이드바를 서로 다른 줄에 위치해두는게 더 좋을것 같습니다.

미디어쿼리를 하나 더 추가합니다.

@media screen and (max-width: 650px) {
    div.content,
    aside#aside { width:calc(100% - 20px); float:none; }
}

브라우저의 가로 크기가 650px이 되면 플롯(float)속성을 없애버리고, 가로 크기를 '최대 가로 크기 - 20px'로 설정합니다.

브라우저의 크기가 클 경우, 본문과 사이드바가 같은 줄에 위치해있지만, 브라우저의 크기가 650px이하로 줄어들게 되면 위 화면처럼 서로 다른 줄에 위치하게 됩니다.

게시물 수정