1. box-sizing

: box model 을 사용할 때 지정하는 속성 중 하나로, 기존 box model 사용 시의 불편함을 없애려고 만들었다.

 

기존의 문제점

holy grail layout 등을 만들면서 box model을 사용하여 padding, border, width 등을 지정할 때, html 태그의 width가 여러 float 속성을 적용한 요소들의 width의 합과 맞아떨어져야 보기좋은 레이아웃이 만들어지는데, 이때 각 요소들의 border과 margin 값을 고려하여(추가로 더해서) width 값을 예상해야 하는 불편함이 있었다.

ex) element1의 width는 300, border는 10, element2의 width는 400, border는 15, margin은 20일 경우

-> html태그의 width는 300 + 10*2 + 400 + 15*2 + 20*2 = 790으로 지정해야 오차가 없다.

 

특히 다음의 세 가지 경우에 width 값을 계산하기 복잡했다.

 

경우1) 두 element의 border 값이 다를 경우

<html>
  <head>
    <style>
        #red{border:10px solid red ; padding:10px ; margin:10px ; width:150px ; box-sizing:content-box}
        #blue{border:30px solid blue ; padding:10px ; margin:10px ; width:150px ; box-sizing:content-box}
    </style>
  </head>
  <body>
        <div id="red">Ryan</div>
        <div id="blue">Ryan</div>
  </body>
</html>

경우2) 두 element의 padding 값이 다를 경우

#red{border:10px solid red ; padding:10px ; margin:10px ; width:150px ; box-sizing:content-box}
#blue{border:10px solid blue ; padding:30px ; margin:10px ; width:150px ; box-sizing:content-box}

경우3) 두 element의 margin 값이 다를 경우

#red{border:10px solid red ; padding:10px ; margin:10px ; width:150px ; box-sizing:content-box}
#blue{border:10px solid blue ; padding:10px ; margin:30px ; width:150px ; box-sizing:content-box}

=> 이 경우마다 width를 직접 margin, padding, border 값을 고려해서 계산해야 했으므로 이 문제를 해결하기 위해서 box-sizing 속성이 추가되었다.

 

그러면 box-sizing 속성은 정확히 무엇인가?

위의 문제는 width 속성이 'border를 포함하지 않은 컨텐츠만의 너비'를 기준으로 했기 때문에 발생했다.

위 사진에서처럼, width의 기본값 속성은 정확히 말하면 border 안의 content(하얀 부분) 이므로, 빨간 선처럼 문서의 시작점에서부터 500px의 거리를 재면 당연히 이 상자는 너비를 초과한다.

그러나 box-sizing 속성에서 다른 값을 기준으로 하면, 어떤 값의 경우 문서의 시작점부터 border 끝까지의 너비를 width의 기준으로 삼을 수도 있다.

이처럼 box-sizing 무엇을 기준으로 width 속성을 결정할 것인지를 직접 지정할 수 있게 해 준다.

* 다만 width가 꼭 content의 순수 너비는 아니다. 위처럼 다른 속성값(value)을 사용한다면, 가령 '시작점부터 box 끝의 "거리"' 처럼, "거리"의 의미로 사용될 수도 있다.

 

이 속성은 2가지 값을 가진다:

1) box-sizing:content-box

: 기본값. width를 border, margin, padding을 일절 포함하지 않은 content만의 너비라고 지정.

-border를 설정하면 상자의 너비가 달라짐.

-width가 content 영역의 너비라는 의미로 사용됨.

 

2) box-sizing:border-box

: width를 border를 포함한 element의 너비라고 지정.

-border를 설정해도 상자의 너비가 달라지지 않음. 대신에 안의 content 영역이 줄어듬.

-width가 시작점부터 border의 끝까지의 거리라는 의미로 사용됨.

 

2. flex

: 레이아웃을 쉽게 잡기 위해 사용하는, 레이아웃을 위해서 고안된 도구.

cf) position, float 속성을 이용해도 레이아웃을 구현할 수 있지만, flex는 레이아웃을 제 1 목적으로 만든 도구이다.

 

특징

: 항상 같이 다니는 부모-자식 관계의 element가 있다.

<container>
	<item>
    </item>
</container>

부모 <container> 과 자식 <item>은 항상 같이 다닌다.

그리고 각 태그에는 서로 다른 속성을 부여할 수 있다.

* 이때 둘은 부모-자식 '태그' 가 아니라 '요소들(elements)'이다.

실제로 구현하려면 id나 class의 이름을 저렇게 정의하거나, 혹은 이름도 다르게 지정해도 된다. 중요한 것은 부모-자식 관계의 태그가 있어야 flex를 사용할 수 있다는 것이다.

 

적용하기

적용하려면 바깥(부모) 태그의 display 속성값이 flex로 되어있어야 한다.

<html>
<head>
   <meta charset="utf-8">
    <style>
        .container{
            display:flex ; <!-- 이 속성이 있어야 flex 사용가능 -->
            width : 200px ; height:200px ; background-color:lightblue
        }
        .item{
            background-color:lightpink ; border:1px solid white ; text-align:center
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item">A</div>
        <div class="item">B</div>
        <div class="item">C</div>
        <div class="item">D</div>
        <div class="item">E</div>
        <div class="item">F</div>
        <div class="item">G</div>
    </div>
</body>
</html>

우선은 flex 속성 중, 부모 태그에 적용되는 속성을 먼저 알아보자.

1. flex-direction 속성

여기서 display:flex 속성 아래에 바로 direction, 즉 방향을 설정할 수 있다.

이 속성은 부모 태그에 지정한다!

**단, display 속성값이 flex가 아니라면 적용되지 않는다.

flex-direction 속성의 경우 4가지 값을 가질 수 있다. 각 값에 따라 글자가 써지는 방향이 달라진다!

: row , row-reverse , column , column-reverse. 

1) row : 기본값. 왼쪽부터 글자가 써짐.

 .container{
            display:flex ; 
            flex-direction: row ;
            width : 200px ; height:200px ; background-color:lightblue
        }

 

2) row-reverse : 오른쪽부터 글자가 써짐. 글자가 써지는 방향이 반대 방향!

* text-align : right 이랑은 다름. 얘는 아예 글자의 순서도 반대가 되어버림.

flex-direction : row-reverse

3) column : 위쪽부터 글자가 써짐.

flex-direction : column

4) column-reverse : 아래쪽부터 글자가 써짐.

flex-direction : column-reverse

다음은 flex 속성 중, 자식 태그에 사용되는 속성을 알아볼 것이다.

 

1. flex-basis 속성

: 개별적 자식 태그에 적용 가능함. flex : display 속성이 이미 적용된 상태에서, 몇몇의 자식 태그 요소에게만 너비/길이값을 부여해주는 속성이다.

만약 flex-direction 속성이 적용되어 있다면, 값이 row 이면 너비, column이면 높이 값으로 적용된다.

        .item{   <!-- 개별 item 요소의 너비(row이므로)를 40px으로 증가 -->
            background-color:lightpink ; border:1px solid white ; text-align:center;
            flex-basis:40px

이렇게 자식 태그 전체에 적용할 수도 있고, 

        .item:nth-child(2){
            flex-basis:200px
        }

이렇게 하나의 개별 요소에만 적용할 수도 있다.

* 이때, nth-child(N)에서, flex-direction 방향의 순서에 따라 N번째 요소에 적용된다.

ex)

        .container{
            display:flex ; 
            flex-direction : row-reverse;  <!-- flex-direction 방향 다르다면? -->
            height:300px ; background-color:lightblue
        }
        .item{
            background-color:lightpink ; border:1px solid white ; text-align:center;
        }
        .item:nth-child(2){
            flex-basis:200px
        }

flex-direction 방향이 row-reverse인 경우, 맨 오른쪽부터 1번째, 2번째, ... 이렇게 순서가 매겨진다.

이때 .item : nth-child(2) 라면, 오른쪽으로 세었을 때를 기준으로 2번째 요소에 해당 속성이 적용되는 것이다.

 

2. flex-grow 속성

: 위의 경우는 컨텐츠의 너비/높이값이 화면 전체(여기서는 부모 태그의 영역)를 채우기 부족해서 여백이 항상 남았다.

만약 너비/높이에서의 여백을 없애고 컨텐츠 영역으로 고르게 채우고 싶을 때 이 속성을 사용한다.

* display : flex 인 상태에서만 사용가능!

* flex-grow 속성은 양수 값을 가질 수 있다.

 

경우1) 전체 자식태그에서 flex-grow : 0 => 기본값

경우2) 전체 자식태그에서 flex-grow : 1 => 전체 너비/높이를 모든 자식태그 요소가 골고루 나눠 가짐

        .item{
            background-color:lightpink ; border:1px solid white ; text-align:center;
            flex-grow:1
        }

여백이 사라지고 컨텐츠가 남은 여백을 골고루 받았다.

경우3) 일부 자식태그에서 flex-grow : 1, 나머지는 0 => 일부 자식태그가 전체 너비/높이를 나눠 가짐

        .item:nth-child(2n+3){
            flex-grow:1
        }

3, 5, 7 번째 요소만 너비를 나눠 가졌다.

경우4) flex-grow 의 값이 2 이상이라면?

ex) A의 flex-grow : a , B의 flex-grow : b 인 경우,

나머지 요소들은 원래 컨텐츠 너비만큼만 차지.

A는 나머지 여백의 a/(a+b) 만큼, B는 b/(a+b) 만큼만 차지.

* 3개 이상의 요소들이어도 마찬가지! ex) a/(a+b+c)

        .item:nth-child(3){
            flex-grow:1
        }
        .item:nth-child(4){
            flex-grow:3
        }

전체 여백이 4라면, C와 D가 1:3의 비율로 여백을 가져간다.

3. flex-shrink 속성

전제조건이 있다.

더보기

1) display : flex 인 상태

2) 해당 자식태그 요소의 flex-basis 값이 설정된 상태

에서 창 너비/높이가 줄어들어서 원래 요소들의 크기보다 작아질 때, 어떤 요소의 너비/높이를 줄일지를 결정함

경우1) 기본값 : 모든 요소가 flex-shrink : 0 인 경우

=> 어떤 요소도 창이 줄어들 때 너비/높이가 줄어들지 않는다.

경우2) 하나의 요소가 flex-shrink : 1인 경우

=> 창이 작아지면 해당 요소의 너비/높이만 이에 비례해서 줄어든다.

        .item:nth-child(1){
            flex-basis:600px ; flex-shrink:1
        }    

기본 상태(창 너비가 충분)
창 너비가 줄어든 상태. A의 영역만 아까보다 줄어들고 나머지 영역의 너비는 그대로 남아있음.

경우3) 몇 개의 flex-shrink 값이 2 이상인 경우

flex-grow 와 비슷. 서로 파이를 나눠 먹는 것과 같다.

=> A의 flex-shrink : a , B의 flex-shrink : b 인 경우, A는 줄어든 면적의 a/(a+b) , B는 b/(a+b) 만큼 줄어든다.

        .item:nth-child(1){
            flex-basis:300px ; flex-shrink:1
        }
        .item:nth-child(2){
            flex-basis:300px ; flex-shrink:4
        }

기본 상태. A와 B의 너비가 같음.
창 너비가 줄어든 상태. A보다 B의 너비가 더 많이 줄어들었다.

 

3. flex 속성으로 holy grail layout 구현하기

아까 언급한 flex-direction , flex-basis , flex-grow , flex-shrink 속성을 이용하면 float 과 position을 사용하는 것보다 더 쉽게 레이아웃을 구현할 수 있었다.

더보기

layout 구현 시 중요하게 사용했던 속성

1) flex-direction

: 세로로 배치될 header, segment(메인 컨텐츠), footer 부분은 flex-direction : column으로 설정,

segment(메인 컨텐츠) 안에서 가로로 배치될 nav, main, aside 부분은 flex-direction : row 로 설정.

2) flex-shrink (* 그 전에 flex-basis 값을 지정해야 함)

: 창 크기가 부족할 때, 메인 컨텐츠는 계속 나타나게 하고 싶다면

=> nav와 aside만 flex-shrink : 1 로 설정.

<html>
<head>
   <meta charset="utf-8">
    <style>
        .container{
            display:flex ; 
            flex-direction:column ;
            text-align:center ;
        }
        .content{
            display:flex ;
        }
        header{border-bottom: 1px solid black ; padding-left:20px}
        footer{border-top : 1px solid black ; padding:20px}
        .content nav{border-right : 1px solid black}
        .content aside{border-left : 1px solid black}
        nav,aside{flex-basis : 400px ; flex-shrink:1}
    </style>
</head>
<body>
    <div class="container">
       <header>
           <h1>WELCOME</h1>
       </header>
        <div class="content"><nav><ul>
            <li>Corporis</li> <li>fugit</li> <li>maxime</li> <li>ut</li> <li>veniam</li> <li>quo</li> <li>dolorum</li> <li>repellendus</li> <li>ab</li> <li>soluta</li> <li>voluptates</li> <li>velit</li></ul>
        </nav>
        <segment>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id cum autem pariatur debitis quae delectus eum temporibus animi quis ad, rerum doloremque non distinctio, minus enim, nihil. Dolores officiis, iusto commodi. Harum, accusamus quas pariatur autem odio sequi tempore obcaecati ab commodi, optio assumenda, unde et tenetur quisquam beatae doloribus. Porro hic odio molestias doloremque, vitae laborum voluptatibus quam deleniti placeat. Explicabo consequatur sit nemo animi reiciendis amet ratione quod possimus fuga eos ab, minima aspernatur voluptatum iure aperiam, dolorum, porro totam saepe. </p><p>Aut beatae, deleniti fugit commodi quis distinctio doloribus culpa est recusandae, illum magni itaque magnam a corrupti nam id, dolorum sapiente iste quidem non, velit error reiciendis. Laborum sint veniam sunt in impedit temporibus architecto deleniti dicta tempore, repudiandae dolor facilis aliquid ea distinctio. Assumenda magnam ratione laudantium eligendi molestias quo, natus voluptatum quos ullam rerum unde vel debitis consequuntur porro, ipsam repellat aliquid saepe maxime impedit asperiores fugiat cupiditate dolores beatae. Sequi quas a culpa magnam voluptates quibusdam, consequatur odit inventore fuga suscipit molestiae sed rem quaerat voluptatem velit, mollitia nemo, animi adipisci.</p> <p>Sapiente dignissimos enim reiciendis, iure? Doloribus nostrum officiis placeat temporibus mollitia assumenda quis tempore accusantium eius vitae laboriosam saepe deserunt nihil accusamus impedit, omnis nobis ab cupiditate iste repellendus facilis inventore! In quisquam maxime molestias itaque nam nobis eligendi, rem ullam autem alias quos deleniti, culpa quas dolores illum animi labore repellendus ab! </p>
        </segment>
        <aside>
             Nisi mollitia praesentium id cumque est repellat hic, animi, qui natus assumenda nihil repudiandae asperiores neque laudantium soluta.
        </aside></div>
        <footer>
            GOODBYE
        </footer>
    </div>
</body>
</html>

따로 width, border 등을 계산하지 않고도 선과 배치가 맞아떨어지는 layout을 구현할 수 있다.

 

 

 

 

'front-side > CSS' 카테고리의 다른 글

8. 그래픽  (0) 2021.04.12
7. 레이아웃  (0) 2021.04.07
5. brackets ~ 레이아웃 기초 내용  (0) 2021.04.02
4. 타이포그래피-font ~ 조화  (0) 2021.04.01
3. 선택자 fin ~ 타이포그래피  (0) 2021.03.30

+ Recent posts