[CSS] CSS 4장. css 레이아웃 위치잡기, Floats, flexbox ,grid, 반응형 디자인, 미디어 쿼리

 

1. CSS 레이아웃

 

뷰포트와 관련하여 박스를 올바른 장소에 배치하는 방법을 살펴보겠습니다. CSS 페이지 레이아웃 기술은 웹페이지에 포함될 요소들을 가져와 일반적인 레이아웃 흐름에서의 기본 위치, 주변의 다른 요소, 부모 컨테이너, 기본 뷰포트 및 윈동우의 요소와 관련하여 해당 요소가 어디에 위치할지 제어할 수 있습니다.

 

  • 일반 흐름(normal flow)
  • display 속성
  • 플렉스박스(Flexbox)
  • 그리드(Grid)
  • 플로트(Floats)
  • 포지셔닝
  • 테이블 레이아웃
  • 다단 레이아웃

각각의 기술은 저마다 용도와 장단점이 있고, 어떤 기술도 단독으로 사용하도록 설계되지 않았습니다. 각 레이아웃 기술이 어떤 용도로 설계된 것인지 이해하게 되면 해당 작업에 가장 적합한 도구가 어떤 것인지 파악할 수 있습니다.

 

일반 흐름(normal flow)

 

일반 흐름(normal flow)은 페이지 레이아웃을 제어하기 위해 아무것도 하지 않을 경우, 브라우저가 기본값으로 HTML 페이지를 배치하는 방법을 말합니다. 

    <p>I like Dog</p>

    <ul>
        <li>강아지 먹이 구매</li>
        <li>운동</li>
        <li>구매하기</li>
    </ul>

    <p>끝</p>

 

기본적으로 브라우저는 이 코드를 다음과 같이 표시합니다.

 

HTML이 소스 코드에 나타나는 순서 그대로 표시되는지, 첫 번째 단락과 정렬되지 않은 목록, 두 번째 단락 등 요소들이 서로 겹쳐있는지 확인해보세요. 요소들이 서로 나란히 표시되는 요소를 인라인(inline)요소라고 하며, 다른 요소 아래 하나씩 표시되는 요소를 블록(block)요소라고 합니다.

 

페이지의 많은 요소에서 일반 흐름(normal flow)은 필요한 레이아웃을 정확히 생성합니다. 그라나 더 복잡한 레이아웃의 경우, CSS에서 사용할 수 있는 몇 가지 도구를 사용하여 이 기본 동작을 변경해야 합니다. 잘 구조화된 HTML 문서로 시작하는 것이 아주 중요한 이유는 기본 레이아웃과 충돌하지 않는 레이아웃으로 작업할 수 있기 때문입니다.

 

CSS에서 요소가 배치되는 방식을 변경시키는 메서드는 다음과 같습니다.

  • display 속성 - block, inline 또는 inline-block과 같은 기준 속성값은 일반 흐름(normal flwo) 속에서 요소가 동작하는 방식을 변경할 수 있습니다. 예를 들면 블록 요소를 인라인 요소로 동작하게 할 수도 있습니다. 
  • 플로트(Floats) - float 속성의 값은 예로 left로 적용하면 흔히 매거진 레이아웃에 속한 이미지가 텍스트를 자신의 주변에 떠 있게 하는 방식과 같이 블록 수준 요소가 어떤 요소의 한쪽 측면으로 밀려나도록 할 수 있습니다.
  • position 속성 - 다른 박스 내부에 있는 박스의 배치를 정밀하게 제어할 수 있습니다. 일반 흐름에서는 정적(static) 포지셔닝이 기본값이지만, 브라우저 뷰포트에 고정하는 등 다른 값을 사용하여 요소를 다르게 배치할 수 있습니다.
  • 테이블 레이아웃 - HTML 테이블의 일부 스타일을 지정하기 위해 고안된 기능으로, display: table 관련 속성을 사용하여 테이블 관련 속성을 비테이블 요소에서도 사용할 수 있습니다.
  • 다단 레이아웃 - 다단 레이아웃 속성을 사용하면 마치 신문처럼 블록 콘텐츠를 단 형태로 배치되도록 만들 수 있습니다.

디스플레이(display)  속성

 

CSS 상에서 페이지 레이아웃을 구현하는 주요 방법은 display 속성에 포함된 모든 속성의 값을 지정하는 것입니다. 이 속성을 사용하면 무언가를 표시하는 기본값으로 변경할 수 있습니다.일반 흐름(normal flow)상의 모든 요소에는 기본display

 

속성값, 즉 요소가 작동하도록 설정된 기본 방식을 가지고 있습니다. 예를 들어 영어로 된 단락이 다른 대상 요소 바로 밑에 표시되는 것은 그들 요소의 스타일이 display:block으로 지정되었기 때문입니다.

 

단락 내부 일부 텍스트 주변에 링크를 만들면, 해당 링크는 나머지 텍스트와 함께 인라인을 유지하며 새 줄로 넘어가는 행갈이를 하지 않습니다. 이는 <a> 태그 요소가 기본값으로 display:inline 이기 때문입니다.

 

이러한 기본값 display 속성을 변경할 수 있습니다. 예를 들어 <li>요소는 기본값으로 display:block이므로 영어 문서상에서 다른 대상 요소 바로 밑에 표시됩니다. display 속성값을 inline 으로 변경하면 문장에서 단어가 나란히 표시되는 것처럼 목록 항목이 나란히 표시됩니다. 모든 요소에 대해 display 속성을 변경할 수 있다는 것은 HTML 요소들이 어떻게 보일지 신경 쓰지 않고, 해당 HTML 요소의 의미론적 의의를 선택할 수 있다는 것 입니다.

 

display:flex 설정하기

 

wrapper 클래스를 가진 컨테이너에 display:flex를 추가해 열로 정령해보겠습니다. 

 <div class="wrapper">
        <div class="box 1">box1</div>
        <div class="box 2">box2</div>
        <div class="box 3">box3</div>
 </div>
.wrapper {
    display:flex;
}

div > .box {
 background-color: greenyellow;
 padding:25px;
 border-radius: 50%;
}

 

 

플렉스 속성 설정하기

 

플렉스 콘테이너에 적용할 수 있는 속성 외 플렉스 항목에 적용할 수 있는 속성도 있습니다.

.wrapper {
    display:flex;
}

div > .box {
 background-color: greenyellow;
 padding:25px;
 border-radius: 50%;
 flex:1;
}

 

display: grid 설정하기

 

플렉스박스와 마찬가지로 디스플레이 속성에 display:grid라는 특정 값을 지정하면 그리드 레이아웃으로 활성화할 수 있습니다. grid-template-rowgrid-template-columns 속성을 사용하여 부모 요소에 대한 행과 열 칸을 정의합니다.

.wrapper {
    display:grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 100px 100px;
    grid-gap:10px;
}

* {
    
    box-sizing: border-box;
}

div > .box {
 background-color: greenyellow;
 padding:25px;
 border-radius: 50%;
 flex:1;
 border-radius: 5px;
 padding: 1em;
}
    <div class="wrapper">
        <div class="box 1">box1</div>
        <div class="box 2">box2</div>
        <div class="box 3">box3</div>
        <div class="box 4">box4</div>
        <div class="box 5">box5</div>
        <div class="box 6">box6</div>
    </div>

 

그리드에 항목 배치하기 

 

그리드가 있으면 위에 표시된 자동 배치 동작에 의존하지 않고, 명시적으로 항목을 그리드에 배치할 수 있습니다. 아래 다음 예제에서 동일한 그리드를 정의했지만, 이번에는 세개의 하위 항목을 정의했습니다. gird-column 과 gird-row를 사용해서 각 항목의 시작 및 끝 줄을 설정할 수 있습니다.

.wrapper {
    display:grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 100px 100px;
    grid-gap:10px;
}

* {
    
    box-sizing: border-box;
}

div > .box {
 background-color: greenyellow;
 padding:25px;
 border-radius: 50%;
 flex:1;
 border-radius: 5px;
 padding: 1em;
}

.box:nth-child(1) {
    grid-column: 2 / 4;
    grid-row: 1;
}

.box:nth-child(2) {
    grid-column: 1;
    grid-row: 1 / 3;
}

.box:nth-child(3) {
    grid-row:2;
    grid-column: 3;
}

 

플로트(Floats)

 

요소를 플로팅 하면 일반 흐름(normal flow)에서 해당 요소와 그 뒤에 따르는 블록 수준 요소의 동작이 변경됩니다. 플로팅된 요소는 왼쪽이나 오른쪽으로 이동되어 일반 흐름(normal flow)에서 벗어나게 되며 주변 콘텐츠가 그 주위에 떠 있습니다.

 

  • left - 요소를 왼쪽으로 띄움
  • right - 요소를 오른쪽으로 띄움
  • none - 플로팅 지정 X , 기본값
  • inherit - 플로팅 속성의 값을 요소의 부모 요소에서 상속하도록 지정
    <h1>Floats</h1>

    <div class="box">float</div>

    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor,
        eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum
        luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet.
        Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, 
        viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. 
        In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. 
        Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus.
        Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget 
        fermentum sapien.
    </p>
.box {
    float:left;
    width:100%;
    max-width: 150px;
    height: 150px;
    margin-right: 40px;
    background:#ffd5cd;
    border-radius: 40%;
    text-align: center;
    line-height: 150px;
}

포지셔닝 기술

 

포지셔닝을 사용하면 요소를 일반 흐름(normal flow) 에서 배치되는 위치에서 다른 위치로 이동할 수 있습니다. 포지셔닝은 페이지의 기본 레이아웃을 만드는 방법이 아닌, 페이지에서 특정 항목의 위치를 관리하고 미세 조정하는 데 사용됩니다.

 

그러나 position 속성에 의존하는 특정 레이아웃 패턴을 얻는데 유용한 기술이 있습니다. 포지셔닝을 이해하면 일반 흐름(normal flow)과 항목을 정상적인 흐름에서 벗어나는 것이 무엇을 의미하는지 이해하는데 도움이 됩니다.

 

  • 정적(static) 포지셔닝 - 모든 요소에 기본값으로 부여된 속성. 
  • 상대(relative) 포지셔닝 - 페이징에서 요소의 위치를 수정해 일반 흐름의 위치에 비해 상대적으로 이동하고, 페이지의 다른 요소와 겹치도록 만들 수 있음
  • 절대(absolute) 포지셔닝 - 요소를 페이지의 일반적인 레이아웃 흐름에서 완전히 벗어나 마치 별도의 레이어에 있는 것처럼 이동시킴.
  • 고정(fixed) 포지셔닝- 다른 요소가 아닌 브라우저 뷰포트를 기준으로 요소를 고정한다는 점을 제외하면 절대 포지셔닝과 유사함
  • 스티키(sticky) 포지셔닝  - 사전에 정의된 오프셋에 도달할 때까지 요소가 relative와 같이 작동하고, 그 시점부터 position:fixed와 같이 작동시키는 방법

Flexbox 

 

flexbox는 행과 열 행태로 항목 무리를 배치하는 일차원 레이아웃 메서드로 항목은 부족한 공간에 맞추기 위해 축소되거나 여분의 공간을 채우기 위해 변형됩니다.

 

Flexbox로 레이아웃할 요소 지정

 

먼저 어떤 요소들을 flexbox로 레이아웃할 요소를 선택해야 합니다 .이를 위해 영향을 주고 싶은 요소의 부모 요소에 특별한 display 속성값을 지정합니다. 

section {
  display: flex;
}

 

flex 모델의 측방

 

  • 기본 축(main axix)는 flex item이 배치되고 있는 방향으로 진행하는 축 
  • 교차축(cross axis)는 flex item이 내부에 배치되는 방향에 직각을 이루는 축
  • display:flex이 설정된 부모 요소를 일컬어 flex container
  • flex container  내부에 flexbox로 레이아웃되는 항목을 일컬어 flex item이라 함

flexbox는 기본 축이 진행되는 방향(자식 flexbox들이 컨테이너 내부에 배치되는 방향)을 지정하는 flex-direction 속성을 제공합니다. 기본값으로 이것을 row로 설정되어 브라우저의 기본 언어가 작동하는 방향(영어 버전인 경우 왼쪽에서 오른쪽)을 따라 일려로 배치됩니다.

section {
  display: flex;
  flex-direction: column;
}

 

이로써 항목 무리를 열 레이아웃으로 되돌려 놓는걸 확인할 수 있습니다. 해당 항목들은 어떤 내용의 CSS를 추가하기 이전 상황과 유사합니다. 

 

접기 

레이아웃에서 너비 또는 높이가 고정 크기를 갖고 있어 생기는 한 가지 문제는 결국 flexbox 자식 요소가 컨테이너에서 대열이탈하면서 레이아웃이 깨집니다. 여기서 우리는 자식들이 정말로 소속 컨테이너에서 이탈하는 모습을 확인할 수 있습니다. 이것을 해소하는 방법은 다음 선언을 추가해주는 겁니다.

  flex-wrap: wrap;

 

또한, 다음 선언문을 <article> 규칙 부분에 추가합니다.

  flex: 200px;

 

flex-flow 약칭 

 

flex 자체를 약칭으로 줄일 수 있습니다 예를 들면 다음 코드를 작성해봅니다.

// flex-direction: row;
// flex-wrap: wrap;

/* 변경후 */
flex-flow: row wrap;

 

flex item의 flex 크기 고정

article {
  flex: 1;
}

 

이것은 각 flex item이 기본 축을 따라 남은 공간을 어느 정도나 점유할지 결정하는 단위가 없는 비율값입니다. 이 경우 각각 <article> 요소에 1의 값을 부여하고 있는데, 이는 padding과 여백이 지정된 이후 남은 여분의 공간을 모두 동등한 크기로 점유한다는 뜻입니다. 그것은 비율로, 각 flex-item에 400000의 값을 부여하면 정확히 동일한 효과가 있음을 의미합니다.

article:nth-of-type(3) {
  flex: 2;
}

 

새로 고침 시 세 번쨰 <article>이 다른 두 개보다 사용 가능한 너비의 두 배나 많이 점유한다는 것을 알 수 있습니다. 또한 flex 값 내에서 최소 크기 값을 지정할 수 있습니다.

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 2 200px;
}

 

수평 및 수직 정렬 

 

flexbox 기능을 사용해 기본 축 또는 교차축을 따라 flex item을 정렬할 수 있습니다.

div {
  display: flex;
  align-items: center;
  justify-content: space-around;
}

 

페이지를 새로 고침하면 div 태그요소들이 수평 및 수직으로 중심에 위치하게 됩니다. align-items 속성을 flex-item이 교차축 어디에 놓일 지 제어합니다. 속성 값은 기본값으로 stretch이며 이 값은 교차축 방향으로 부모 요소를 채우기 위해 모든

 

flex-item을 연장합니다. 부모가 교차 축 방향으로 고정폭이 주어지지 않았다면 모든 flex-item이 최장 항목만큼 길어집니다. center 값은 항목 무리가 자기들 고유한 면적을 유지하는 동시에 교차 축을 따라 중심에 놓이게 만듭니다.

 

Grid

 

CSS 그리드 레이아웃은 웹 페이지를 위한 이차원 레이아웃 시스템으로, 콘텐츠를 행과 열에 배치할 수 있습니다.

    <div class="container">
      <div>하나</div>
      <div>둘</div>
      <div>셋</div>
      <div>넷</div>
      <div>다섯</div>
      <div>여섯</div>
      <div>일곱</div>
    </div>
.container {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}
.container > div {
  border: 1px solid red;
  padding: 10px;
}

 

fr 단위를 포함한 가변 그리드

 

길이를 백분율을 사용해 그리드를 생성하는 것 외에 fr 단위를 사용해 그리드 행과 열을 기반적으로 조정할 수 있습니다. 그리드 컨테이너에서 그리드 행과 열의 크기를 유연하게 조정할 수 있는 사용 가능한 공간의 한 분율을 나타냅니다.

.container2 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

 

fr 단위는 공간을 비례적으로 분배합니다. 

.container2 {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
}

 

첫번째 트랙은 사용 가능한 공간의 2fr을 차지하고 다른 두 트랙은 1fr을 차지해 첫 번째 트랙이 더 커집니다. fr 단위와 고정 길이 단위를 혼합할 수 있습니다. 이 경우 고정 트랙에 필요한 공간이 먼저 소진된 후 나머지 공간이 다른 트랙에 분배됩니다.

 

반응형 디자인 

반응형 웹 설계 는 웹 페이지가 모든 화면 크기와 해상도에 잘 렌더링되도록 하면서 사용성을 보장하는 웹 디자인 접근 방식입니다. 멀티 디바이스 웹을 위한 디자인 방식으로, HTML은 기본적으로 반응형 또는 유동적입니다.CSS 없이 HTML만 포함된 웹 페이지를 만들고 창을 조정하면 브라우저는 뷰포트에 맞게 텍스트를 자동으로 리플로우 합니다.

 

미디어 쿼리

 

미디어 쿼리를 사용하면 일련의 텍스트를 실행하고 CSS를 선택적으로 적용해 사용자의 요구에 맞게 페이지의 스타일을 지정할 수 있습니다.

@media screen and (max-width: 1200px) {
  .container {
    background-color: red;
  }
}

 

스타일시트 내 여러 미디어 쿼리를 추가해 다양한 화면의 크기에 적합한 전체 레이아웃 또는 일부를 조정할 수 있습니다. 미디어 쿼리를 사용할 때 일반적인 접근 방식을 화면이 좁은 디바이스(휴대폰)를 위해 간단한 단일 열 레이아웃을 만든 다음 화면이 더 넓은지 확인하고 화면 너비가 충분하다고 판단되면 다중 열 레이아웃을 구현합니다.

 

 

참고 자료

 

CSS 레이아웃 입문서 - Web 개발 학습하기 | MDN

이 문서에서는 이전 모듈에서 이미 다뤘던 CSS 레이아웃 기능, 예를 들어 다양한 display 속성값의 차이 등을 복습하고, 이번 과정에서 다룰 몇 가지 CSS 개념을 소개합니다.

developer.mozilla.org

 

 

GitHub - CSS-STR/css-bloging

Contribute to CSS-STR/css-bloging development by creating an account on GitHub.

github.com

 

LIST