국비교육(22-23)

116일차(1)/CSS(15) : CSS3 Flex 활용(3)

서리/Seori 2023. 3. 27. 17:37

116일차(1)/CSS(15) : CSS3 Flex 활용(3)

 

 

Step08_example_gallery.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step08_example_gallery.html</title>
    <style>
        html{
            /* width와 height에 padding과 border-width 를 포함시키기 */
            box-sizing: border-box;
        }
        .container{
            width: 90%;            
            /* 가운데정렬 하기 위한 css */
            margin: 0 auto;
        }
        .cards{            
            background-color: antiquewhite;
            display: flex;
            flex-wrap: wrap;
            flex-direction: row;
            align-items: flex-start;
            justify-content: space-between;
            row-gap:20px;
        }
        .cards img{
            width: 30%;            
            border: 3px solid #000;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Gallery 예제</h1>
        <div class="cards">
            <img src="images/image1.png">
            <img src="images/image2.png">
            <img src="images/image3.png">
            <img src="images/image4.png">
            <img src="images/image5.png">
            <img src="images/image6.png">
            <img src="images/image1.png">
            <img src="images/image2.png">
            <img src="images/image3.png">
        </div>
    </div>    
</body>
</html>

 

- box-sizing: border-box; 로 CSS를 지정하면

 예를 들어 어떤 컨텐츠가 있고 bordrer(빨간색), padding(초록색)이 있다고 할 때

 

 

- contents의 width, height에 padding과 border의 크기를 포함하겠다는 뜻이다!

- 원래 width라고 하면 컨텐츠의 크기만 말하는데, 

  box-sizing: border-box padding, border 크기도 width에 포함시켜서 계산하는 것을 말한다.

 

- margin: 0 auto; 는 가운데 정렬을 가능하게 하는 CSS

 

 

 

- 100vh => 100% view height

- 웹브라우저의 높이를 기준으로 100%를 잡겠다는 것

  웹브라우저의 크기가 크면 크게 잡고, 좁으면 작게 잡겠다는 것

 

display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: flex-start;

 

- cards에 적용한 css

 

flex-wrap: wrap;

- container 가 아래 컨텐츠들을 감싸도록 할 수 있다.

- 이 css가 없으면 cards의 이미지들이 container 밖으로 빠져나감

 

 

- 이런 형태로 정렬된다.

 

 

- 이미지 사이의 행, 열 사이의 거리 동일하게, 양 끝에 있는 카드는 container 에 붙어있도록 설정 추가

 

 

 

- 이렇게 갤러리 형태로 수정해보았다.

 


 

Step08_example_layout.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step08_example_layout.html</title>
    <style>
        * {
            box-sizing: border-box; 
        }
        .container {
            display: flex;
            min-height: 100vh;
            flex-direction: column;
            margin: 0;
        }
        #main {
            display: flex;
            /*
                flex 속성
                - flex-grow, flex-shrink, flex-basis 를 한번에 적용하기 위한 속성이다.
                - flex : 1 1 200px 은 grow 1, shrink 1, basis 200px 의 의미이다.
                - flex : 1 은 grow 1, shrink 1, basis 0px 의 의미이다.
                  남는 공간을 모두 가지겠다는 의미로 생각하면 된다.
            */
            flex: 1;
        }
        #main > article {
            flex: 1;
            order: 1;
        }
        #main > nav, 
        #main > aside {
            flex: 0 0 20vw;
        }
        #main > nav {
            background: #D7E8D4;
            order: 3;
        }
        #main > aside {
            background: beige;
            order: 2;
        }
        header, footer {
            background: yellowgreen;
            height: 20vh;
        }
        header, footer, article, nav, aside {
            padding: 1em;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>Header</header>
        <div id="main">
            <article>Article</article>
            <nav>Nav 요소</nav>
            <aside>Side contents</aside>
        </div>
        <footer>Footer</footer>
    </div>
</body>
</html>

 

 

 

- 각각은 블록 요소이기 때문에 기본적으로는 이렇게 세로로 쭉 쌓인다.

- 여기에 CSS를 적용해서 배치해볼 것!

 

 

- main div를 flex 로 지정해서 한줄로 배치되도록 했다.

 

 

- 빨간색 박스(container), 초록색 박스(main)에 모두 flex가 적용되어 있다.

- 이렇게 flex를 중첩시켜서 만들 수도 있다.

 (flex 안에 있는 자식 요소에서 또 flex를 적용하는 것이 가능!)

- 이렇게 순서대로 아래쪽으로 배치된 이유는 flex-direction: column; 이기 때문

 

 

- flex: 0 0 20vw; 라고 작성한 부분은

 지난 글에서 연습한 flex 속성 (grow, shrink, basis 등을 한번에 배치한 것이다.)

 

 

fl

border: 00000;  라고 작성하는 것과 같다.

margin: 10px; 은 전체에 각각 margin 적용하는것

 

이와 비슷하게

- flex : 1 1 200px 은 grow 1, shrink 1, basis 200px 의 의미이다.
                - flex : 1 은 grow 1, shrink 1, basis 0px 의 의미이다.

 

 

 

 

 

 

- 헤더, 메인, 푸터는 높이를 경쟁한다.

- 이 3개의 요소 중에서 flex 속성 1 을 가지고 있는 것은 Main뿐이다. 그래서 Main이 남는 공간을 전부 차지하게 되는 것!

 

 

- 100vh  브라우저 창의 높이를 감지해서 그 전체 높이를 100%로 잡고 배치한 것이다.

 

 

- 이렇게 하면 높이를 줄여도 화면을 꽉 채울 수 있다.

 

 

- 헤더, 푸터가 브라우저 높이의 20%씩을 가지게 되어 있으므로, 나머지 60%를 Main이 가진다.

 

 

- flex의 하위요소들에서도 flex 속성을 적용할 수 있다.

- Main부분은 가로로 배치되었다. 기본이 row속성이므로 row 축을 기본으로 가짐

- flex: 1; 로 지정해놓은 요소들이 폭을 경쟁한다!

 

- flex: 1; 은 안드로이드의 layout_weight 요소와 같다고 생각하면 된다.

 

 

- nav, side요소는  0이다. 그러므로 flex: 1 인 article 요소가 남은 폭을 가져간다.

 

 

- 지정된 order 값, 정렬 순서로 인해 위와 같이 정렬되었다. row인 경우 기본적으로 이렇게 정렬된다!

 


 

Step08_example_layout2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step08_example_layout2.html</title>
    <style>
        *{
            box-sizing: border-box;
        }
        .container{
            display: flex;
            flex-direction: row;
            min-height: 100vh;
            margin: 0;
        }
        .col-1{
            background: #D7E8D4;
            flex: 1;
        }
        .col-2{
            flex: 5;
            display: flex;
            flex-direction: column;
        }
        .content {
            display: flex;
            flex-direction: row;
        }
        /*
            artivle 은 flex: 3, aside는 flex: 1, 부모 요소의 flex-direction: row 이기 때문에
            artivle과 aside는 폭(width)을 3:1로 나눠 가지게 된다.
        */
        .content > article {
            flex: 3;
            min-height: 60vh;
        }
        .content > aside {
            background: beige;
            flex: 1;
        }
        header, footer {
            background: yellowgreen;
            height: 20vh;
        }
        header, footer, article, nav, aside {
            padding: 1em;
        }
    </style>
</head>
<body>
    <div class="container">
        <nav class="col-1">Nav</nav>
        <div class="col-2">
            <header>Header</header>
            <div class="content">
                <article>Article</article>
                <aside>Side contents</aside>
            </div>
            <Footer>Footer</Footer>
        </div>
    </div>
</body>
</html>

 

 

 

- row로 배치하되, 폼을 1:5로 나누어 가진다.

 

- col-2 클래스의 내용도 flex를 사용해 column으로 배치해준다.

 

 

- 그러면 이러한 배치로 출력된다.

 

 

- flex가 세번 나온다. 각각 가로배치, 세로배치, 가로배치 한 것으로 보면 된다.

1) nav, container 배치 (가로축 기준)

2) header, main, footer 배치 (세로축 기준)

3) article, side 배치 (가로축 기준)

 

 

- article과 aside가 각각 flex: 3, flex: 1로 지정했기 때문에 3:1 비율로 화면을 나누어가지게 된 것!

 


 

Step08_example_navbar.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step08_example_navbar.html</title>
    <style>
        .main-nav {
            display: flex;
            background: orangered;
            color: white;
            border-radius: 3px;
            padding: 1em;
            font-family: sans-serif;
        }
        .main-nav > ul {
            list-style-type: none;
            padding: 0;
            margin: 0;
            display: flex;
            flex: 3;
        }
        .main-nav li {
            margin-right: 1em;
        }
        .main-nav li a{
            color: bisque;
            text-decoration: none;
        }
        .main-nav li :hover{
            color: bisque;
            text-decoration: underline;
        }
        .main-nav > form {
            display: flex;
            justify-content: flex-end;
            flex: 1;
        }
        .main-nav input {
            flex: 1;
        }
        .main-nav button {
            background: white;
            border: 0;
            border-radius: 1em;
            color: orangered;
            padding: 0 1em;
            margin-left: .3em;
        }        
        /* 반응형 레이아웃 */
        @media (max-width: 575px){
            .main-nav{
                flex-direction: column;
            }
            .main-nav ul{
                flex-direction: column;
                margin-bottom: 1em;
            }
        }
    </style>
</head>
<body>
    <nav class="main-nav">
        <ul>
            <li><a href="#">Logo</a></li>
            <li><a href="#">Home</a></li>
            <li><a href="#">Study</a></li>
            <li><a href="#">Contacts</a></li>
        </ul>
        <form action="">
            <input type="text" placeholder="Search">
            <button type="submit">Go</button>
        </form>
    </nav>
</body>
</html>

 

 

- css를 적용하지 않았을 때 (기본 block 요소 : 세로로 정렬됨)

 

 

- 목록의 disc(목록 점 표시)를 없애고 기본 패딩, 마진 0으로 수정

 

 

- 이렇게 가지게 된다.

- ul 요소가 폭의 나머지를 전부 가진 것

 

 

- 같은 방식으로 header를 이렇게 만들어보기!

 

 

- 네비의 글씨를 잘 보익 수정하고, 기본 서식을 삭제

- 마우스가 hover되었을 때만 밑줄 적용

 

 

- 지금은 이렇게 가로로 배치되어 있는데,

  브라우저의 전체폭이 576px 이하가 되었을 때 저 검색창을 아래로 배치하도록 할 것!

 

 

- 그러면 폭이 좁아졌을 때는 이렇게 적용된다. (검색창이 자동으로 아래로 내려감)

 

 

.main-nav ul{
	flex-direction: column;
}

 

- 메뉴바도 세로로 배치되도록 만들려면 @media 안에서

  main-nav 클래스의 특정 요소에 flex-direction: column; 을 적용하도록 하면 된다.

 

- flex box, 미디어 쿼리(media query)를 활용하면 반응형 레이아웃도 쉽게 만들 수 있다.