CSS 레이아웃 튜토리얼: 고전적인 접근 방식에서 최신 기술까지

게시 됨: 2022-03-11

CSS를 마스터하지 않고 웹 레이아웃을 마스터하는 것은 육지에서 수영을 배우는 것과 거의 같습니다. 그러나 수영을 한 번 마스터하면 평생 유지되는 기술인 수영과 달리 CSS를 마스터하는 것은 CSS 자체가 계속해서 진화하고 있기 때문에 결코 끝나지 않는 과정입니다.

여러 브라우저(동일한 브라우저의 다른 버전에서도)에서 CSS 구현 및 지원의 차이와 CSS 권장 사항의 채택 비율이 다르기 때문에 문제가 더욱 악화됩니다. 10년이 훨씬 넘는 기간 동안 웹 디자이너와 개발자는 각각의 새 브라우저 버전에서 지원되는 추가 CSS3 기능의 산발적이고 일관성 없는 버스트와 씨름해 왔습니다.

그러나 CSS를 마스터하는 것은 견고한 웹 디자이너나 개발자에게 절대적으로 필요합니다. 이 기사에서는 고전적인 CSS2 기술에서 CSS3의 최신 레이아웃 접근 방식에 이르기까지 몇 가지 기본적인 CSS 레이아웃 원칙을 안내합니다.

참고: 이 기사의 모든 코드 샘플은 HTML5 요소와 Sass 구문을 사용합니다. 전체 작업 코드는 https://github.com/laureanoarcanio/css-layout-examples에서 복제할 수 있습니다.

사용 사례

기술을 배우는 가장 좋은 방법 중 하나는 지원하려는 특정 사용 사례 또는 해결하려는 특정 문제를 갖는 것입니다. 이를 위해 특정 요구 사항 집합이 있는 사용 사례에 중점을 둘 것입니다.

우리의 사용 사례는 몇 가지 동적 동작이 있는 웹 앱 레이아웃으로 구성됩니다. 머리글, 바닥글, 탐색 메뉴 및 하위 탐색과 같은 페이지의 고정 요소와 스크롤 가능한 콘텐츠 섹션이 있습니다. 구체적인 레이아웃 요구 사항은 다음과 같습니다.

  • 기본 레이아웃
    • 머리글, 바닥글, 탐색 메뉴 및 하위 탐색은 모두 스크롤 시 고정된 상태로 유지됩니다.
    • 탐색 및 하위 탐색 요소는 모든 수직 여유 공간을 차지합니다.
    • 콘텐츠 섹션은 페이지에 남아 있는 모든 여유 공간을 사용하며 스크롤 가능한 영역이 있습니다.
  • 동적 동작
    • 탐색 메뉴는 기본적으로 아이콘만 표시하지만 텍스트도 표시하도록 확장할 수 있습니다(그런 다음 다시 축소하여 아이콘만 표시할 수 있음).
  • 레이아웃 변형
    • 탐색 메뉴 옆에 하위 탐색이 있는 페이지도 있고 없는 페이지도 있습니다.

클래식 CSS2 기법을 사용한 CSS 튜토리얼

CSS 튜토리얼

우선, 다음은 클래식 CSS를 사용하여 샘플 구현에 사용할 HTML5 마크업입니다.

 <body class="layout-classic"> <header></header> <nav></nav> <aside></aside> <main></main> <footer></footer> </body>

고정 포지셔닝

CSS2에서는 고정 위치 지정을 사용하는 위치 지정 레이아웃 모델을 사용하여 페이지의 고정 요소(머리글, 바닥글 등)를 얻을 수 있습니다.

또한 z-index CSS 속성을 사용하여 고정된 요소가 페이지의 다른 콘텐츠 "위에" 유지되도록 합니다. z-index 속성은 요소의 스택 순서를 지정합니다. 여기서 스택 순서가 더 큰 요소는 항상 스택 순서가 낮은 요소의 "위에" 있습니다. z-index 속성은 위치 지정 요소에서만 작동합니다. 이 예에서는 고정된 요소가 시각적으로 맨 앞에 유지되도록 하기 위해 z-index 값 20(기본값보다 높음)을 임의로 사용합니다.

또한 width 속성을 100%로 설정하여 브라우저에서 요소에 대해 사용 가능한 모든 공간을 가로로 사용하도록 지시합니다.

 #header, #footer { position: fixed; width: 100%; z-index: 20; } #header { top: 0; height: 5em; } #footer { bottom: 0; height: 3em; }

자, 머리글과 바닥글입니다. 하지만 #nav#subnav 는 어떻습니까?

CSS 확장

#nav#subnav 의 경우 CSS 확장 이라고 하는 약간 더 정교한 기술을 사용합니다. 이는 요소를 고정 (즉, 페이지의 고정 위치) 또는 절대 (즉, 가장 가까운 위치 의 조상 또는 포함하는 블록에 상대적인 지정된 위치).

수직 확장은 요소의 topbottom 속성을 고정 값으로 설정하여 이루어지므로 요소가 수직으로 확장되어 그에 따라 나머지 수직 공간을 사용합니다. 기본적으로 당신이하고있는 일은 요소의 상단을 페이지 상단에서 특정 거리로 묶고 요소 하단을 페이지 하단에서 특정 거리로 묶는 것이므로 요소가 전체 수직 공간을 채우도록 확장됩니다. 그 두 지점 사이.

마찬가지로 수평 확장은 요소의 leftright 속성을 모두 고정 값으로 설정하여 이루어지므로 요소가 수평으로 확장되어 그에 따라 나머지 수평 공간을 사용합니다.

우리의 사용 사례에서는 수직 확장을 사용해야 합니다.

 #nav, #subnav { position: fixed; top: 6em; /* leave 1em margin below header */ bottom: 4em; /* leave 1em margin above footer */ z-index: 20; } #nav { left: 0; width: 5em; } #subnav { left: 6em; /* leave 1em margin to right of nav */ width: 13em; }

기본(정적) 위치 지정

기본 스크롤 가능한 콘텐츠 영역은 기본(정적) 위치 지정에 의존할 수 있으므로 요소가 문서 흐름에 나타나는 순서대로 렌더링됩니다. 페이지의 다른 모든 항목은 고정된 위치에 있으므로 이 요소는 문서 흐름에 있는 유일한 요소입니다. 결과적으로, 그것을 적절하게 배치하기 위해 우리가 해야 할 일은 고정된 머리글, 바닥글 및 탐색/하위 탐색과 겹치는 것을 피하기 위해 margin 속성을 지정하는 것입니다.

 #main { margin: 6em 0 4em 20em; }

이를 통해 CSS2를 사용하는 사용 사례의 기본 레이아웃 요구 사항을 충족했지만 여전히 동적 기능에 대한 추가 요구 사항을 충족해야 합니다.

클래식 CSS2 기술을 사용한 동적 동작

요구 사항에 따르면 탐색 메뉴는 기본적으로 아이콘만 표시하지만 텍스트도 표시하도록 확장할 수 있습니다(그런 다음 다시 축소하여 아이콘만 표시할 수 있음).

CSS2 및 CSS3 튜토리얼

탐색 메뉴가 확장되었을 때 탐색 메뉴의 너비에 5em 을 추가하는 것으로 시작하겠습니다. 탐색 메뉴 요소에서 동적으로 추가하거나 제거할 수 있는 "확장된" CSS 클래스를 만들어 이를 수행합니다.

 #nav { left: 0; width: 5em; &.expanded { /* Sass notation */ width: 10em; } }

다음은 탐색 토글 아이콘을 클릭하는 사용자에 따라 확장 모드와 축소 모드 사이에서 탐색 메뉴를 동적으로 토글하는 데 사용할 수 있는 JavaScript 코드(이 예에서는 jQuery 사용)의 예입니다.

 $('.layout-classic #nav').on('click', 'li.nav-toggle', function() { $('#nav'').toggleClass('expanded'); });

이를 통해 이제 탐색 메뉴를 동적으로 확장하거나 축소할 수 있습니다. 엄청난.

글쎄, 일종의 훌륭하지만 완전히는 아닙니다. 이제 탐색 메뉴를 확장 및 축소할 수 있지만 페이지의 나머지 부분에서는 제대로 재생되지 않습니다. 확장된 탐색 메뉴는 이제 확실히 원하는 동작이 아닌 하위 탐색과 겹칩니다.

이것은 CSS2의 주요 한계 중 하나를 드러냅니다. 즉, 고정 위치 값으로 하드코딩해야 하는 것이 너무 많습니다. 결과적으로 확장된 탐색 메뉴를 수용하기 위해 위치를 변경해야 하는 페이지의 다른 요소에 대해 더 많은 고정 위치 값을 사용 하여 추가 "확장된" CSS 클래스를 정의해야 합니다.

 #subnav { left: 6em; width: 13em; &.expanded { left: 11em; /* move it on over */ } } #main { margin: 6em 0 4em 20; z-index: 10; &.expanded { margin-left: 25em; /* move it on over */ } }

그런 다음 사용자가 탐색 토글을 클릭할 때 이러한 다른 요소의 동적 조정을 추가하도록 JavaScript 코드를 확장해야 합니다.

 $('.layout-classic #nav').on('click', 'li.nav-toggle', function() { $('#nav, #subnav, #main').toggleClass('expanded'); });

알겠습니다. 그게 더 잘 작동합니다.

클래식 CSS2 기술을 사용한 레이아웃 변형

이제 하위 탐색 메뉴를 숨기는 페이지가 있어야 한다는 요구 사항을 해결해 보겠습니다. 특히 사용자가 기본 탐색 영역에서 "사용자" 아이콘을 클릭할 때 하위 탐색 메뉴가 숨겨지기를 원합니다.

CSS 레이아웃 튜토리얼

따라서 먼저 display: none 을 적용하는 "hidden" 새 클래스를 생성합니다.

 .hidden { display: none; }

그리고 다시 사용자가 사용자 아이콘을 클릭할 때 JavaScript(jQuery)를 사용하여 "숨겨진" CSS 클래스를 #subnav 요소에 적용합니다.

 $('#nav.fa-user').on('click', function() { $('#subnav').toggleClass('hidden'); });

이 추가 기능을 사용하면 사용자가 "users" 아이콘을 클릭할 때 #subnav 요소가 제대로 숨겨지지만 다른 요소가 #subnav 요소에 의해 비워진 공간을 사용하도록 확장되는 대신 해당 요소 가 차지한 공간은 사용되지 않은 상태로 유지 됩니다.

#subnav 요소를 숨길 때 원하는 동작을 얻으려면 인접 형제 선택기 로 알려진 덜 알려져 있지만 매우 유용한 CSS 선택기 중 하나를 사용합니다.

인접 형제 CSS 선택기

인접한 형제 선택기를 사용하면 지정된 첫 번째 요소 바로 다음에 오는 두 번째 요소의 인스턴스만 선택하여 두 개의 요소를 지정할 수 있습니다.

예를 들어 다음은 ID가 subnav 인 요소 바로 다음에 오는 ID가 main 인 요소만 선택합니다.

 #subnav + #main { margin-left: 20em; }

위의 CSS 스니펫은 표시된 #subnav 바로 다음에 오는 경우에만 #main 의 왼쪽 여백을 20em 으로 설정합니다.

그러나 #nav 가 확장되면(이전 코드를 기반으로 expanded 클래스도 #main 에 추가됨) #main 의 왼쪽 여백을 25em으로 이동합니다.

 #subnav + #main.expanded { margin-left: 25em; }

그리고 #subnav 가 숨겨져 있으면 #main 의 왼쪽 여백을 #nav 바로 옆에 6em까지 이동합니다.

 #subnav.hidden + #main { margin-left: 6em; }

(참고: 인접 형제 선택기를 사용할 때의 한 가지 단점은 표시 여부에 관계없이 DOM에 항상 #subnav 가 있어야 한다는 것입니다.)

마지막으로 #subnav 가 숨겨지고 #nav 가 확장되면 #main 의 왼쪽 여백을 11em 으로 설정합니다.

 #subnav.hidden + #main.expanded { margin-left: 11em; }

이를 통해 무거운 JavaScript 코드 없이 모든 것을 연결할 수 있지만 페이지에 요소를 더 추가하면 이 코드가 얼마나 복잡해질 수 있는지 알 수 있습니다. CSS2에서 제대로 작동하려면 위치 값을 하드코딩해야 하는 경우가 많다는 것을 다시 한 번 알 수 있습니다.

CSS3 활용

CSS3는 훨씬 더 사용하기 쉽고 하드코딩된 값에 훨씬 덜 의존할 수 있도록 크게 향상된 기능과 레이아웃 기술을 제공합니다. CSS3는 본질적으로 더 동적인 동작을 지원하도록 설계되었으며 그런 의미에서 더 "프로그래밍 가능"합니다. 사용 사례와 관련하여 이러한 새로운 기능 중 일부를 살펴보겠습니다.

CSS3 calc() 함수

새로운 CSS3 calc() 함수를 사용하여 CSS 속성 값을 동적으로 계산할 수 있습니다(하지만 지원은 브라우저마다 다름). calc() 함수에 제공되는 표현식은 표준 연산자 우선 순위 규칙을 사용하여 기본 산술 연산자( + , - , * , / )를 결합한 간단한 표현식일 수 있습니다.

calc() 함수를 사용하면 CSS2에서 요구하는 값의 하드코딩을 피할 수 있습니다. 우리의 경우 이를 통해 CSS 확장을 보다 동적으로 달성할 수 있습니다. 예를 들어:

 #nav, #subnav { position: fixed; height: calc(100% - 10em); /* replaces */ z-index: 20; }

calc() 함수를 사용하여 위의 height 사양을 사용하면 top:6embottom:4em 을 사용하여 CSS2에서와 동일한 결과를 얻을 수 있지만 훨씬 더 유연하고 적응적인 방식으로 topbottom 위치를 하드코딩할 필요가 없습니다. 가치.

CSS3 플렉스박스 레이아웃

Flexbox는 CSS3에 도입된 새로운 레이아웃입니다(지원은 브라우저마다 다름). 플렉스박스 레이아웃을 사용하면 다양한 화면 크기, 해상도 및 장치에서 예측 가능하게 동작하는 방식으로 페이지의 요소를 더 간단하게 정렬할 수 있습니다. 따라서 반응형 웹 디자인의 맥락에서 특히 유용합니다.

주요 기능은 다음과 같습니다.

  • 자식 요소를 배치하는 것이 훨씬 쉽고 복잡한 레이아웃을 보다 간단하고 깔끔한 코드로 달성할 수 있습니다.
  • 자식 요소는 어떤 방향으로든 배치할 수 있으며 디스플레이 공간에 맞게 유연한 크기를 가질 수 있습니다.
  • 하위 요소는 사용 가능한 여유 공간에 맞게 자동으로 계약을 확장합니다.

Flexbox는 고유한 용어 및 개념 집합을 도입합니다. 그 중 몇 가지는 다음과 같습니다.

  • 플렉스 컨테이너. flex 항목의 컨테이너 요소 역할을 하는 flex 또는 inline-flex 로 설정된 display 속성이 있는 요소입니다.
  • 플렉스 아이템. 플렉스 컨테이너 내의 모든 요소. (참고: 플렉스 컨테이너에 직접 포함된 텍스트는 익명의 플렉스 항목으로 래핑됩니다.)
  • . 모든 flexbox 레이아웃에는 플렉스 항목이 배치되는 기본 축을 지정하는 flex-directio 이 있습니다. 교차 축은 주축에 수직인 축입니다.
  • 윤곽. Flex 항목은 flex-wrap 속성에 따라 한 줄 또는 여러 줄에 배치할 수 있습니다.
  • 치수. 높이 및 너비에 해당하는 flexbox는 main sizecross size 이며, 이는 각각 플렉스 컨테이너의 기본 축과 교차 축의 크기를 지정합니다.

자, 그럼 간단한 소개와 함께 flexbox 레이아웃을 사용하는 경우 사용할 수 있는 대체 마크업이 있습니다.

 <body class="layout-flexbox"> <header></header> <div class="content-area"> <nav></nav> <aside></aside> <main></main> </div> <footer></footer> </body>

예제 사용 사례의 경우 기본 레이아웃(머리글, 콘텐츠, 바닥글)이 세로이므로 열 레이아웃을 사용하도록 flexbox를 설정합니다.

 .layout-flexbox { display: flex; flex-direction: column; }

기본 레이아웃은 수직이지만 콘텐츠 영역(nav, subnav, main)의 요소는 수평으로 배치됩니다. 각 플렉스 컨테이너는 한 방향만 정의할 수 있습니다(즉, 레이아웃이 수평 또는 수직이어야 함). 따라서 레이아웃에 이보다 더 많은 것이 필요한 경우(앱 레이아웃의 일반적인 경우), 각각 다른 방향 레이아웃을 가진 여러 컨테이너를 다른 컨테이너 안에 중첩할 수 있습니다.

그렇기 때문에 #nav , #subnav#main 을 래핑하는 추가 컨테이너( content-area 라고 함)를 추가했습니다. 이런 식으로 전체 레이아웃은 수직이 될 수 있지만 콘텐츠 영역의 콘텐츠는 수평으로 레이아웃될 수 있습니다.

이제 플렉스 항목을 배치하기 위해 flex 의 약어인 flex 속성을 사용할 것입니다 flex: <flex-grow> <flex-shrink> <flex-basis>; . 이 세 가지 플렉스 속성은 다음과 같이 플렉스 항목 사이에 남아 있는 여유 공간을 흐름 방향으로 분배하는 방법을 결정하는 속성입니다.

  • flex-grow: 동일한 컨테이너 내부의 나머지 유연한 항목에 비해 항목이 얼마나 커질 수 있는지 지정합니다.
  • flex-shrink: 동일한 컨테이너 내부의 나머지 유연한 항목에 비해 항목이 축소될 수 있는 방법을 지정합니다.
  • flex-basis: 항목의 초기 크기를 지정합니다(즉, 줄어들거나 커지기 전).

CSS 플렉스 컨테이너: 크로스 vs 메인

flex-growflex-shrink 를 둘 다 0으로 설정하면 항목의 크기가 고정 되고 사용 가능한 여유 공간이 더 많거나 적도록 크기가 커지거나 줄어들지 않습니다. 머리글과 바닥글은 크기가 고정되어 있으므로 다음과 같이 합니다.

 #header { flex: 0 0 5em; } #footer { flex: 0 0 3em; }

항목이 사용 가능한 모든 여유 공간을 차지하도록 하려면 flex-growflex-shrink 값을 모두 1로 설정하고 flex-basis 값을 auto 로 설정합니다. 이것이 우리가 사용 가능한 모든 여유 공간을 차지하기를 원하기 때문에 콘텐츠 영역에 대해 수행하는 작업입니다.

그리고 이전에 말했듯이 content-area 안의 항목이 행 방향으로 배치되기를 원하므로 display: flex 를 추가합니다. 및 flex-direction: row; . 이것은 content-area를 #nav , #subnav 및 `#main에 대한 새로운 플렉스 컨테이너로 만듭니다.

다음은 content-area 용 CSS에 대한 결과입니다.

 .content-area { display: flex; flex-direction: row; flex: 1 1 auto; /* take up all available space */ margin: 1em 0; min-height: 0; /* fixes FF issue with minimum height */ }

콘텐츠 영역에서 #nav#subnav 는 모두 고정된 크기를 가지므로 그에 따라 flex 속성을 설정하면 됩니다.

 #nav { flex: 0 0 5em; margin-right: 1em; overflow-y: auto; } #subnav { flex: 0 0 13em; overflow-y: auto; margin-right: 1em; }

(컨테이너 높이를 초과하고 오버플로하는 콘텐츠를 극복하기 위해 이러한 CSS 사양에 overflow-y: hidden 을 추가했습니다. Chrome에는 실제로 이것이 필요하지 않지만 FireFox는 필요합니다.)

#main 은 나머지 여유 공간을 차지합니다.

 #main { flex: 1 1 auto; overflow-y: auto; }

이 모든 것이 좋아 보이므로 이제 여기에 동적 동작을 추가하고 어떻게 되는지 살펴보겠습니다.

JavaScript는 이전과 동일합니다(여기서 지정하는 CSS 요소 컨테이너 클래스는 layout-flexbox 반면 이전에는 layout-classic 임):

 $('.layout-flexbox #nav').on('click', 'li.nav-toggle', function() { $('#nav').toggleClass('expanded'); });

다음과 같이 expanded 클래스를 CSS에 추가합니다.

 #nav { flex: 0 0 5em; /* collapsed size */ margin-right: 1em; overflow-y: auto; &.expanded { flex: 0 0 10em; /* expanded size */ } }

그리고 짜잔!

flexbox 레이아웃이 우리를 위해 모든 것을 처리하기 때문에 이번에는 너비 변경에 대해 다른 항목에 알릴 필요가 없습니다.

그러면 남은 것은 하위 탐색을 숨기는 것뿐입니다. 그리고 무엇을 추측? 이전과 동일한 JavaScript 코드를 사용하여 추가 변경 없이 "그냥 작동"합니다. Flexbox는 여유 공간에 대해 알고 있으며 추가 코드 없이 레이아웃이 자동으로 작동하도록 합니다. 정말 멋진.

Flexbox는 또한 수직 및 수평 요소를 모두 중앙에 배치하는 몇 가지 흥미로운 방법을 제공합니다. 프리젠테이션 언어가 여유 공간의 개념을 포함하는 것이 얼마나 중요한지, 그리고 이러한 종류의 기술을 사용하여 코드가 얼마나 확장 가능해질 수 있는지 여기에서 깨달았습니다. 반면에 여기의 개념과 표기법은 고전 CSS보다 마스터하는 데 조금 더 걸릴 수 있습니다.

CSS3 그리드 레이아웃

Flexbox 레이아웃이 CSS3의 리딩 에지에 있다면 그리드 레이아웃은 블리딩 에지에 있다고 할 수 있습니다. W3C 사양은 아직 초안 상태이며 여전히 브라우저 지원이 상당히 제한적입니다. (chrome://flags의 '실험적 웹 플랫폼 기능' 플래그를 통해 Chrome에서 활성화됨).

그렇긴 하지만, 나는 개인적으로 이 초안이 혁명적이라고 생각하지 않습니다. 오히려 HTML5 디자인 원칙에 따르면 "저자들 사이에 이미 관행이 널리 퍼져 있으면 금지하거나 새로운 것을 발명하기보다 채택하는 것을 고려하십시오."

따라서 마크업 기반 그리드는 오랫동안 사용되어 왔으며 이제 CSS 그리드 레이아웃은 실제로 동일한 패러다임을 따르고 있으며 마크업 요구 사항이 없는 프레젠테이션 계층에서 모든 이점과 훨씬 더 많은 것을 제공합니다.

일반적인 아이디어는 요소를 배치할 수 있는 미리 정의되거나 고정되거나 유연한 그리드 레이아웃을 갖는 것입니다. flexbox와 마찬가지로 여유 공간 원칙에 따라 작동하며 동일한 요소에서 수직 및 수평 "방향"을 모두 정의할 수 있으므로 코드 크기와 유연성 면에서 이점이 있습니다.

그리드 레이아웃은 2가지 유형의 그리드를 도입합니다. 즉, 명시적암시적 . 단순화를 위해 여기서는 명시적 그리드에 중점을 둘 것입니다.

flexbox와 마찬가지로 Grid 레이아웃은 고유한 용어 및 개념 집합을 도입합니다. 그 중 몇 가지는 다음과 같습니다.

  • 그리드 컨테이너. display 속성이 "grid" 또는 "inline-grid"로 설정된 요소로 미리 정의된 그리드에 위치 지정 및 정렬하여 포함된 요소가 배치됩니다(명시적 모드). 그리드는 그리드 컨테이너의 공간을 그리드 셀로 나누는 가로 및 세로 그리드 선의 교차 세트입니다. 두 세트의 그리드 라인이 있습니다. 하나는 열을 정의하기 위한 것이고 다른 하나는 행을 정의하기 위한 것입니다.
  • 그리드 트랙. 인접한 두 그리드 선 사이의 공간입니다. 각 그리드 트랙에는 열 또는 행의 너비 또는 높이와 경계 그리드 선의 간격을 제어하는 ​​크기 조정 기능이 할당됩니다.
  • 그리드 셀. 두 개의 인접한 행과 두 개의 인접한 기둥 그리드 선 사이의 공간입니다. 그리드 항목을 배치할 때 참조할 수 있는 그리드의 가장 작은 단위입니다.
  • 유연한 길이. 그리드 컨테이너의 여유 공간의 일부를 나타내는 fr 단위로 지정된 차원입니다.

CSS 그리드 레이아웃 스케치

다음은 그리드 레이아웃을 사용하는 경우 사용할 수 있는 대체 마크업입니다.

 <body class="layout-grid"> <header></header> <nav></nav> <aside></aside> <main></main> <footer></footer> </body>

이 레이아웃을 사용하면 flexbox에 대해 했던 것처럼 콘텐츠 영역에 대한 추가 래퍼가 필요하지 않습니다 . 이러한 유형의 레이아웃을 사용하면 동일한 그리드 컨테이너에서 양방향으로 요소 공간 지정을 정의할 수 있기 때문입니다.

이제 CSS를 파헤쳐 보겠습니다.

 .layout-grid { display: grid; grid-template-columns: auto 0 auto 1em 1fr; grid-template-rows: 5em 1em 1fr 1em 3em; }

display: grid; 우리 컨테이너에. grid-template-columnsgrid-template-rows 속성은 각각 그리드 트랙 사이의 공백 목록으로 지정됩니다. 즉, 이러한 값은 그리드 선의 위치가 아닙니다. 오히려 두 트랙 사이 의 공간 을 나타냅니다.

측정 단위는 다음과 같이 지정할 수 있습니다.

  • 길이
  • 그리드 컨테이너 크기의 백분율
  • 열이나 행을 차지하는 내용의 측정, 또는
  • 그리드의 여유 공간의 일부

따라서 grid-template-columns: auto 0 auto 1em 1fr; 우리는 가질 것입니다:

  • 2개의 auto 너비 열을 정의하는 1개의 트랙( #nav space)
  • 1 #subnav 0
  • auto 너비의 2개 열을 정의하는 1개의 트랙( #subnav 공간)
  • 1em 의 1 시궁창
  • #main1fr 을 사용하는 1개의 트랙(남은 모든 공간을 차지함)

여기에서 우리는 트랙에 대한 auto 값을 많이 사용합니다. 이를 통해 라인의 위치와 크기가 최대 내용으로 정의되는 동적 열을 가질 수 있습니다. (따라서 곧 #nav#subnav 요소의 크기를 지정해야 합니다.)

마찬가지로 행 라인의 경우 grid-template-rows: 5em 1em 1fr 1em 3em; 이는 #header#footer 를 고정하고 그 사이의 모든 요소가 1em 거터를 사용하는 동안 남은 여유 공간을 사용하도록 설정합니다.

이제 정의된 그리드에 배치할 실제 요소를 배치하는 방법을 살펴보겠습니다.

 #header { grid-column: 1 / 6; grid-row: 1 / 2; } #footer { grid-column: 1 / 6; grid-row: 5 / 6; } #main { grid-column: 5 / 6; grid-row: 3 / 4; overflow-y: auto; }

이것은 헤더가 그리드 라인 1과 6(전체 너비) 사이에 있고 그리드 라인 1과 2 사이에 행에 대한 것임을 지정합니다. 바닥글과 동일하지만 (처음 두 줄이 아닌) 마지막 두 줄 사이에 있습니다. 그리고 메인 영역은 차지해야 할 공간에 맞게 설정됩니다.

grid-columngrid-row 속성은 각각 grid-column-start / grid-column-endgrid-row-start / grid-row-end 를 지정하기 위한 축약형입니다.

자, 다시 #nav#subnav 로 돌아가십시오. 이전에 #nav#subnav 를 자동 값을 사용하여 트랙에 배치했으므로 이러한 요소의 너비를 지정해야 합니다(확장 모드와 동일하게 너비만 변경하면 그리드 레이아웃이 나머지를 처리합니다).

 #nav { width: 5em; grid-column: 1 / 2; grid-row: 3 / 4; &.expanded { width: 10em; } } #subnav { grid-column: 3 / 4; grid-row: 3 / 4; width: 13em; /* track has gutter of 0, so add margin here */ margin-left: 1em; }

이제 #nav 를 토글하고 #subnav 를 숨기거나 제거할 수 있으며 모든 것이 완벽하게 작동합니다! 그리드 레이아웃을 사용하면 라인에 별칭을 사용할 수 있으므로 결국 그리드를 변경해도 그리드 라인이 아닌 이름에 매핑되므로 코드가 중단되지 않습니다. 더 많은 브라우저에서 이것이 더 널리 지원되기를 확실히 기대하고 있습니다.

결론

고전적인 CSS 기술을 사용하더라도 많은 웹 개발자가 인식하거나 활용하는 것보다 훨씬 더 많은 것을 달성할 수 있습니다. 즉, 이 중 많은 부분이 상당히 지루할 수 있으며 스타일 시트 전체에 걸쳐 값을 반복적으로 하드코딩하는 작업이 포함될 수 있습니다.

CSS3는 프로그래밍하기 훨씬 쉽고 이전 CSS 사양의 지루함을 많이 피하는 훨씬 더 정교하고 유연한 레이아웃 기술을 제공하기 시작했습니다.

CSS2와 CSS3 모두에서 이러한 기술과 패러다임을 마스터하는 것은 사용자 경험과 코드 품질을 모두 최적화하기 위해 CSS가 제공해야 하는 모든 것을 활용하는 데 필수적입니다. 이 기사는 학습해야 할 모든 것과 CSS의 강력함과 유연성으로 달성할 수 있는 모든 것의 빙산의 일각을 나타냅니다. 그것을 가지고!

관련 항목: *SMACSS 탐색: CSS를 위한 확장 가능 및 모듈식 아키텍처*