레이아웃

CSS 팟캐스트 - 009: 레이아웃

개발자로 일하고 있고 디자이너가 동료가 새 웹사이트 디자인을 맡기라고 상상해 보세요. 이 디자인에는 표시 영역 너비와 높이를 고려하는 2차원 레이아웃은 물론 유동적이고 유연해야 하는 레이아웃 등 온갖 종류의 흥미로운 레이아웃과 구성이 있습니다. CSS로 이러한 스타일을 지정하는 가장 좋은 방법은 어떻게 결정할까요?

CSS는 가로축, 세로축 또는 둘 다에서 레이아웃 문제를 해결하는 다양한 방법을 제공합니다. 컨텍스트에 맞는 레이아웃 방법을 선택하는 것은 어려울 수 있으며 종종 문제를 해결하기 위해 두 가지 이상의 레이아웃 방법이 필요할 수 있습니다. 이를 위해 다음 모듈에서는 이러한 결정을 내리는 데 도움이 되는 각 CSS 레이아웃 메커니즘의 고유한 기능을 알아봅니다.

레이아웃: 간략한 기록

웹의 초기에는 간단한 문서보다 더 복잡한 디자인이 <table> 요소를 사용하여 배치되었습니다. 90년대 후반에 브라우저에서 CSS가 널리 사용되면서 HTML을 시각적 스타일에서 쉽게 구분할 수 있게 되었습니다. CSS는 개발자가 HTML을 터치하지 않고도 웹사이트의 디자인과 분위기를 완전히 바꿀 수 있는 가능성을 열어주었습니다. 이 새로운 기능은 CSS의 강력한 기능을 입증하여 더 많은 개발자가 기능을 배우도록 장려하기 위해 제작된 CSS Zen Garden과 같은 프로젝트에 영감을 주었습니다.

웹 디자인 및 브라우저 기술에 대한 요구가 변화하면서 CSS도 발전했습니다. Rachel Andrew의 도움말에서 CSS 레이아웃과 Google의 레이아웃에 대한 접근 방식이 시간이 지남에 따라 어떻게 발전했는지 확인할 수 있습니다.

1996년부터 2021년까지 수년간 CSS가 어떻게 발전해 왔는지 보여주는 타임라인

레이아웃: 현재와 미래

최신 CSS는 놀랍도록 강력한 레이아웃 도구를 제공합니다. 레이아웃 전용 시스템이 있으므로 다음 모듈에서 Flexbox와 그리드를 자세히 살펴보기 전에 사용 가능한 기능을 개략적으로 살펴보겠습니다.

display 속성 이해

display 속성은 두 가지 작업을 합니다. 가장 먼저 할 일은 적용되는 상자가 인라인으로 작동하는지, 블록으로 작동하는지 확인하는 것입니다.

.my-element {
  display: inline;
}

인라인 요소는 문장 내 단어처럼 동작합니다. 인라인 방향으로 나란히 놓입니다. <span><strong>과 같은 요소는 일반적으로 <p> (단락)와 같은 포함 요소 내에서 텍스트 조각에 스타일을 지정하는 데 사용되며 기본적으로 인라인입니다. 또한 주변 공백도 보존합니다.

상자의 다양한 크기와 각 크기 조정 섹션의 시작 및 끝 위치를 보여주는 다이어그램

인라인 요소에는 너비와 높이를 명시적으로 설정할 수 없습니다. 블록 수준의 여백과 패딩은 주변 요소에 의해 무시됩니다.

.my-element {
    display: block;
}

블록 요소는 나란히 배치되지 않습니다. 새로운 제품 라인을 직접 만듭니다. 다른 CSS 코드에서 변경하지 않는 한 블록 요소는 인라인 크기까지 확장되므로 가로 쓰기 모드에서 전체 너비로 확장됩니다. 블록 요소의 모든 변의 여백이 적용됩니다.

.my-element {
    display: flex;
}

display 속성은 요소의 하위 요소가 동작하는 방식도 결정합니다. 예를 들어 display 속성을 display: flex로 설정하면 상자가 블록 수준 상자가 되고 하위 요소도 Flex 항목으로 변환됩니다. 이렇게 하면 정렬, 순서, 흐름을 제어하는 Flex 속성이 사용 설정됩니다.

Flexbox 및 그리드

여러 요소의 레이아웃 규칙을 만드는 두 가지 기본 레이아웃 메커니즘은 flexboxgrid입니다. 유사점은 공유하지만 서로 다른 레이아웃 문제를 해결하도록 설계되었습니다.

플렉스박스

.my-element {
    display: flex;
}

Flexbox는 1차원 레이아웃의 레이아웃 메커니즘입니다. 가로 또는 세로로 한 축에 걸친 레이아웃입니다. 기본적으로 Flexbox는 요소의 하위 요소를 인라인 방향으로 나란히 정렬하고 블록 방향으로 확장하므로 모두 동일한 높이가 됩니다.

항목은 같은 축에 유지되며 공간이 부족해도 줄바꿈되지 않습니다. 대신 서로 같은 줄로 뭉치려고 할 것입니다. 이 동작은 align-items, justify-content, flex-wrap 속성을 사용하여 변경할 수 있습니다.

또한 Flexbox는 하위 요소를 flex 항목으로 변환합니다. 즉, Flex 컨테이너 내에서 하위 요소가 동작하는 방식에 대한 규칙을 작성할 수 있습니다. 개별 항목의 정렬, 순서, 양쪽 맞춤을 변경할 수 있습니다. flex 속성을 사용하여 축소 또는 확장 방식을 변경할 수도 있습니다.

.my-element div {
    flex: 1 0 auto;
}

flex 속성은 flex-grow, flex-shrink, flex-basis의 약칭입니다. 위의 예시를 다음과 같이 확장할 수 있습니다.

.my-element div {
 flex-grow: 1;
 flex-shrink: 0;
 flex-basis: auto;
}

개발자는 이러한 하위 수준 규칙을 제공하여 콘텐츠 및 표시 영역 크기에서 문제가 발생할 때 레이아웃이 어떻게 동작해야 하는지 브라우저에 힌트를 줍니다. 따라서 반응형 웹 디자인에 매우 유용한 메커니즘입니다.

그리드

.my-element {
    display: grid;
}

그리드는 여러 가지 측면에서 flexbox와 비슷하지만, 단일 축 레이아웃 (세로 또는 가로 공간) 대신 다중 축 레이아웃을 제어하도록 설계되었습니다.

그리드를 사용하면 display: grid가 있는 요소에 레이아웃 규칙을 작성할 수 있으며 repeat()minmax() 함수와 같은 레이아웃 스타일 지정을 위한 몇 가지 새로운 프리미티브가 도입되었습니다. 한 가지 유용한 그리드 단위는 fr 단위(남은 공간의 일부)로, 3개의 CSS 속성을 사용하여 각 항목 사이에 간격이 있는 기존의 12개의 열 그리드를 빌드할 수 있습니다.

.my-element {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

위의 예는 단일 축 레이아웃을 보여줍니다. Flexbox는 주로 항목을 그룹으로 취급하는 반면 그리드를 사용하면 2차원에서 위치를 정밀하게 제어할 수 있습니다. 이 그리드의 첫 번째 항목이 2개의 행과 3개의 열을 차지한다고 정의할 수 있습니다.

.my-element :first-child {
  grid-row: 1/3;
  grid-column: 1/4;
}

grid-rowgrid-column 속성은 그리드의 첫 번째 요소가 첫 번째 열부터 네 번째 열의 시작 부분까지, 그 다음 첫 번째 행부터 세 번째 행까지 확장되도록 지시합니다.

흐름 레이아웃

그리드 또는 Flexbox를 사용하지 않으면 요소가 일반적인 흐름으로 표시됩니다. 일반적인 흐름에 있을 때 항목의 동작과 위치를 조정하는 데 사용할 수 있는 여러 레이아웃 메서드가 있습니다.

인라인 블록

주변 요소가 인라인 요소의 블록 여백과 패딩을 따르지 않는 방식을 기억하시나요? inline-block를 사용하면 이러한 일이 발생할 수 있습니다.

p span {
    display: inline-block;
}

inline-block를 사용하면 블록 수준 요소의 일부 특성을 갖추면서도 텍스트와 함께 인라인으로 흐르는 상자가 생성됩니다.

p span {
    margin-top: 0.5rem;
}

부동

이미지가 텍스트 단락 안에 있는 경우 신문에서처럼 이미지를 둘러싸는 것이 편리하지 않을까요? 부동 소수점 수를 사용하면 됩니다.

img {
    float: left;
    margin-right: 1em;
}

float 속성은 요소가 지정된 방향으로 '부동 소수점 수' 있도록 지시합니다. 이 예의 이미지는 왼쪽으로 떠다니도록 지시합니다. 그러면 동위 요소가 이미지를 '둘러싸기' 때문입니다. 요소에 left, right 또는 inherit를 플로팅하도록 지시할 수 있습니다.

다중 열 레이아웃

전 세계 모든 국가의 목록과 같이 요소 목록이 너무 많으면 사용자가 많은 스크롤과 시간을 낭비할 수 있습니다. 또한 페이지에 과도한 공백이 생길 수도 있습니다. CSS 다중 열을 사용하면 이 값을 여러 열로 분할하여 이 두 가지 문제를 해결할 수 있습니다.

<h1>All countries</h1>
<ul class="countries">
  <li>Argentina</li>
  <li>Aland Islands</li>
  <li>Albania</li>
  <li>Algeria</li>
  <li>American Samoa</li>
  <li>Andorra</li>
  …
</ul>
.countries {
    column-count: 2;
    column-gap: 1em;
}

이렇게 하면 긴 목록이 자동으로 두 개의 열로 분할되고 두 열 사이에 간격이 추가됩니다.

.countries {
    width: 100%;
    column-width: 260px;
    column-gap: 1em;
}

콘텐츠가 분할되는 열 수를 설정하는 대신 column-width를 사용하여 원하는 최소 너비를 정의할 수도 있습니다. 표시 영역에 사용할 수 있는 공간이 많아지면 자동으로 더 많은 열이 생성되고 공간이 줄어들면 열도 줄어듭니다. 이는 반응형 웹 디자인 컨텍스트에서 매우 유용합니다.

포지셔닝

마지막으로 이 레이아웃 메커니즘 개요에서는 배치입니다. position 속성은 문서의 일반적인 흐름에서 요소가 작동하는 방식 및 다른 요소와의 관계를 변경합니다. 사용 가능한 옵션은 relative, absolute, fixed, sticky이며 기본값은 static입니다.

.my-element {
  position: relative;
  top: 10px;
}

이 요소는 문서의 현재 위치에 따라 10픽셀 아래로 이동합니다. 요소에 position: relative을 추가하면 그 요소는 position: absolute가 있는 하위 요소의 포함 블록이 됩니다. 즉, 하위 요소에 절대 위치가 적용된 경우 이제 최상위 상대적 상위 요소가 아닌 이 특정 요소로 위치가 변경됩니다.

.my-element {
  position: relative;
  width: 100px;
  height: 100px;
}

.another-element {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 50px;
    height: 50px;
}

positionabsolute로 설정하면 요소가 현재 문서 흐름에서 분리됩니다. 이는 다음 두 가지를 의미합니다.

  1. 가장 가까운 상대 상위 요소에 top, right, bottom, left를 사용하여 이 요소를 원하는 위치에 배치할 수 있습니다.
  2. 절대 요소 주변의 모든 콘텐츠가 리플로우되어 해당 요소에 남은 공간을 채웁니다.

position 값이 fixed인 요소는 absolute와 유사한 방식으로 동작하며, 상위 요소가 루트 <html> 요소입니다. 고정된 위치 요소는 설정한 top, right, bottom, left 값에 따라 왼쪽 상단에서 고정된 상태로 유지됩니다.

sticky를 사용하여 fixed의 고정된 고정 측면과 relative의 더 예측 가능한 문서 흐름을 준수하는 측면을 확보할 수 있습니다. 이 값을 사용하면 표시 영역이 요소를 지나 스크롤할 때 설정된 top, right, bottom, left 값에 고정된 상태로 유지됩니다.

요약정리

CSS 레이아웃에는 선택의 폭이 넓고 유연성이 높습니다. CSS Flexbox그리드의 기능에 대해 자세히 알아보려면 다음 모듈을 진행하세요.

학습 내용 확인하기

레이아웃에 관한 지식 테스트

display 속성의 두 가지 작업은 무엇인가요?

inline, block 또는 none를 결정합니다.
레이아웃 엔진은 이 상자가 전체 너비인지 여부를 알아야 하며 새 줄이 필요한가요?
그리드 레이아웃 프레임을 결정합니다.
디스플레이 속성은 디스플레이를 그리드로 설정할 수 있지만 레이아웃 프레임과는 아무 관련이 없습니다.
하위 요소의 동작 방식을 결정합니다.
Flexbox와 그리드에는 자녀를 위한 의견과 새로운 기능이 있습니다.
상자를 스크롤해야 하는지 결정합니다.
이것이 overflow 속성입니다.

여러 단락을 열로 채우려면 이 작업에 가장 적합한 CSS 속성은 무엇인가요?

display: grid
그리드는 여러 단락을 열에 넣을 수 있지만 이러한 열은 한 단락에서 다음 단락으로 함께 흐르지 않는 자체 열이 됩니다.
column-count
단락은 잡지나 신문처럼 한 열의 끝에서 다음 열의 시작 부분으로 흐릅니다.
display: flex
Flex를 사용하면 여러 단락을 열에 넣을 수 있지만 이러한 열은 자체 열이 되어 한 단락에서 다음 단락으로 함께 흐르지 않아야 합니다.
float
다시 시도해 보세요.

블록이 흐름에서 벗어난 것은 무엇을 의미하나요?

강가에 붙어 있어요.
여기서 컨텍스트는 지리가 아닌 CSS입니다.
top 또는 left 위치 값이 지정됩니다.
이러한 속성만으로는 흐름에서 벗어나지 않습니다.
더 이상 동위 위치를 기준으로 배치되지 않습니다.
예를 들어 position: absolute가 있는 상자는 이제 다른 동위 요소와의 순서가 아니라 포함 블록을 기준으로 x 및 y 좌표로 배치됩니다.

Flexbox 및 Grid는 기본적으로 하위 요소를 래핑하나요?

flex-wrap: wrap 또는 repeat(auto-fit, 30ch)로 선택해야 합니다.
거짓
Flexbox 및 그리드에는 추가 스타일이 필요한 특별한 래핑 기능이 있습니다.