Frontend/CSS

프론트엔드 CSS 요소의 레이아웃[위치, 정렬] - display, position, flexible layout

쏠솔랄라 2023. 2. 17. 20:00

 

 

CSS 요소의 레이아웃[위치, 정렬]

 

display*
position*
flexible layout*
grid layout*
 
미디어쿼리, 컨테이너, 트랜지션, 트랜스폼, 애니메이션...

 

display

 

: 해당 요소를 사용자에게 어떻게 보여줄 것인가

block
        크기를 원하는대로 지정 가능
        한 줄 전체 너비를 차지함
        (div, p, header, footer, h1~h6, ...)


inline
        크기 지정 불가
        안에 있는 컨텐츠만큼 지정
        이웃하는 요소와 나란히 배치되는 특징
        ex. a, span, img, ...


inline-block
        inline과 block 속성 모두를 갖고 있는 것
        이웃하는 요소와 나란히 배치되고, 크기 지정도 가능
        ex. input, ...


none
        보이지 않는 상태
        사용자 화면에서 자리 차지하지 않음, 완전히 사라짐


flex

        flexible layout

 

grid

        grid layout을 다루기 위한 기본 속성

 

 

position (위치지정방식)


static
        (기본값) 요소를 만들면 기본적으로 포지션 속성에 들어가게 된다
        * top, left, right (다른 요소와 겹칠 수 있음)

relative
        지정요소 (static + 내 자신이 기준이 된다)
        * 나 자산이 기준
        * absolute와 함께 쓰인다

absolute ; 절대 위치 지정 방식
        가장 가까운 부모 요소의 지정 요소(relative)에 상대적으로 배치
        단 지정요소가 없다면 뷰포트를 기준으로 배치되는 경우가 있음

        내가 설정한 위치 기준으로 
            1. 조건이 없다면 : 무조건 뷰포트를 기준으로 나누어짐

                * 절대위치
                * 다른 요소와 상관업싱 겹치도록 올라간다

fixed
        뷰포트(사용자 화면)에 스크롤과 상관없이 배치

sticky : fixed + relative
        가장 가까운 스크롤이 되는 조상과 표 관련 요소 기준으로 지정한 값이 넘으면 마치 fixed처럼 고정
        내가 정해준 기준이 넘으면 fixed로 전환

 

flexible layout

 

display: flex (부모요소)

        대부분의 웹사이트는 수직으로 구성

        레이아웃 구성 시 대부분의 태그는 블록태그이기 때문에 
        수직구성은 어렵지 않게 구현 가능
        그러나 수평 구성을 구현하는 것은 쉬운 일이 아님

        또한, 요소 내 자식들을 한 요소 기준으로 
        수직, 수평 가운데 정렬하는 일 또한 쉽지 않음

        이러한 문제를 해결하기 위해 유연하게 ("flexible") 빈 공간을 채우고
        자식을 어떠한 방향으로든 (수직, 수평) 정렬할 수 있으며
        부모 요소의 크기를 넘어섰을 때 
        자동 줄바꿈이나 컨텐츠 내 수평 수직 가운데 정렬 또한 조절할 수 있는 레이아웃이 유행
    
   => 수직, 수평하기 쉽게 유연하게 배치하는 레이아웃

flex-wrap
            : 플렉스 라인(부모요소)에 더이상 여유공간이 없을 때
            그 이후의 요소를 줄바꿈 할 것인지 여부를 설정할 수 있음

justify-content
            : 플렉스 요소의 수평방향 정렬 방식
            ex. flex-start, center, flex-end, space-between

align-items
            : 플렉스 요소의 수직방향 정렬 방식

flex-direction 
            : 정렬 방향 (수평, 수직)

flex-grow, flex-shrink
            : 얼마만큼 크기를 차지할지, 얼마만큼 축소할지

 

 


 

 

Exercise 1

 

<!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>Display</title>
  </head>
  <style>
    span {
      width: 200px;
      height: 200px;
      border-radius: 30%;
      background-color: orange;
      display: inline-block;
    }

    ul > li {
      display: inline-block;
      margin: 0 15px;
    }

    input {
      display: block;
      width: 300px;
      margin-bottom: 10px;
    }
  </style>
  <body>
    <span>500</span>
    <hr />
    <!--직선-->
    <ul>
      <li>example1</li>
      <li>example2</li>
      <li>example3</li>
    </ul>
    <hr />
    <input />
    <input />
  </body>
</html>

 


 
 
Exercise 2
 
 
<!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>Document</title>
  </head>
  <style>
    div {
      background-color: #333;
      color: #fff;
      margin: 15px;
    }

    .display {
      display: none;
    }

    .visible {
      visibility: hidden;
    }

    .opacity {
      opacity: 0;
    }

    /*
    display: none; 영역을 차지하고 있지 않음 ; 아예 사라짐 ; 클릭 불가
    visibility: hidden; 영역을 차지하고 있으나 클릭 금지
    opacity: 0; (0~1) 영역을 차지하고 있고 클릭 가능
   
    ** 주의
        opacity는 안에 있는 내용물(컨텐츠)도 투명하게 만들기 때문에
    배경색을 투명하게 만들 때는 rgba를 쓰는 게 좋다
   
    */

    button {
      padding: 16px;
      background-color: rgb(180, 255, 255);
      color: blue;
      border: none;
      border-radius: 8px;
      cursor: pinter;
    }

    button:hover {
      opacity: 0.7;
    }

    button:disabled {
      /* 버튼이 비활성화되어 있다 */
      background-color: crimson;
      counter-reset: #333;
    }
  </style>
  <body>
    <div>
      <p>display: none 속성은 사용자 화면에서 사라집니다</p>
      <p class="display">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad eaque
        laudantium, necessitatibus aspernatur quisquam exercitationem inventore!
        Dicta neque repudiandae ipsam, veniam ipsa tenetur nulla unde quis eum
        quo id quaerat.
      </p>
    </div>
    <div>
      <p>visibility : hidden 속성은 사용자 화면에서 사라집니다</p>
      <p class="visible">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad eaque
        laudantium, necessitatibus aspernatur quisquam exercitationem inventore!
        Dicta neque repudiandae ipsam, veniam ipsa tenetur nulla unde quis eum
        quo id quaerat.
      </p>
    </div>
    <div>
      <p>opacity: 0 속성은 사용자 화면에서 사라집니다</p>
      <p class="opacity">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad eaque
        laudantium, necessitatibus aspernatur quisquam exercitationem inventore!
        Dicta neque repudiandae ipsam, veniam ipsa tenetur nulla unde quis eum
        quo id quaerat.
      </p>
    </div>
    <div>
      <button disabled>LOGIN</button>
    </div>
  </body>
</html>

 


 

 

Exercise 3 상대위치

<!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>position</title>
    <style>
      .static {
        width: 200px;
        height: 200px;
        background: #ff1493;
        padding: 20px;
        margin-left: 50px;
        margin-bottom: 10px;
      }

      .relative {
        width: 400px;
        height: 200px;
        background-color: #00bfff;
        padding: 20px;
        position: relative;
        top: 20px;
        left: 100px; /* 현재의 위치를 기준으로 왼쪽에서 오른쪽으로 100px이동 */
      }

      /* 현재 지정된 위치를 기준으로 그 요소를 기준으로 상대적으로 위치 설정*/
    </style>
  </head>
  <body>
    <h2>상대위치 지정 방식</h2>
    <div class="static">일반 위치 지정 방식</div>
    <div class="relative">상대 위치 지정 방식</div>
  </body>
</html>

 

 


 

Exercise고정위치

 

<!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>position</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      header {
        position: fixed;
        width: 100%;
        height: 100px;
        background-color: rgb(247, 255, 177);
      }
      main {
        padding-top: 100px;
        height: 200vh;
        /* position-fixed는 다른 요소와 겹치는 속성이 있기 때문에
          padding을 주어 컨텐츠를 fixed 요소 크기만큼 이동시킨다 */
      }
      aside {
        width: 100px;
        height: 500px;
        background-color: #d9d9;
        position: fixed;
        bottom: 10%;
        right: 10%;
      }
      #modal-background {
        background-color: rgba(0, 0, 0, 0.7);
        /* opacity: 0.7; */
        color: rgb(247, 255, 177);
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100vh;
        z-index: 1; /* 기본값: 0, 숫자가 높을수록 겹치는 요소와 비교하여 해당 요소의 위치가 위로 올라온다 */
      }
    </style>
  </head>
  <body>
    <div id="modal-background">모달백그라운드</div>
    <header>안녕하세요</header>
    <main>
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Numquam, commodi
      quia! Nemo illo voluptate corporis? Ullam suscipit odit, vero repellendus
      impedit inventore repudiandae debitis sequi officiis rem modi odio
      necessitatibus. Lorem ipsum dolor sit amet consectetur adipisicing elit.
      Ad, laudantium odio! Dolor amet quidem architecto ducimus sapiente laborum
      maxime, nisi distinctio inventore, odio odit magni blanditiis at. Maiores,
      eveniet necessitatibus. Lorem ipsum dolor sit amet consectetur adipisicing
      elit. Repellat asperiores nisi, adipisci placeat laudantium dolorem? Non
      voluptatem dicta quidem ducimus architecto unde soluta, laboriosam aliquid
      voluptate, laudantium assumenda qui obcaecati. Lorem ipsum dolor, sit amet
      consectetur adipisicing elit. Earum voluptatibus aliquid vero accusantium
      inventore consequuntur nobis unde quis porro maxime fugiat laboriosam
      magni, beatae soluta harum odit architecto voluptatum sunt?
    </main>
    <aside></aside>
  </body>
</html>

 

 


 

 

Exercise 5

 

<!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>절대위치</title>
    <style>
      #wrapper {
        width: 500px;
        height: 500px;
        border: 3px solid #f00;
        position: relative;
      }
      .box {
        width: 50px;
        height: 50px;
        background-color: #ff1477;
        color: #fff;
        position: absolute;
      }
      .ab1 {
        top: 0; /* top에서부터 0만큼 당김 */
        right: 0;
      }
      .ab2 {
        bottom: 0;
        left: 0;
      }
      .ab3 {
        top: 200px;
        left: 200px;
      }
      .ab4 {
        top: 250px;
        right: 70px;
      }

      #alert {
        width: 300px;
        height: 200px;
        position: absolute;
        background-color: aqua;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }

      #example {
        width: 100%;
        background-color: darkblue;
      }
    </style>
  </head>
  <body>
    <div id="alert"></div>
    <h2>절대 위치 지정 방식</h2>
    <div id="wrapper">
      <div id="example">example</div>
      <div class="box ab1">1</div>
      <div class="box ab2">2</div>
      <div class="box ab3">3</div>
      <div class="box ab4">4</div>
    </div>
  </body>
</html>
 
 

 

 

Exercise 6 포지션

 

<!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>Document</title>
    <style>
      /* common css */
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      header {
        width: 100%;
        height: 80px;
        background-color: #667321;
        position: fixed;
      }

      footer {
        width: 100%;
        height: 300px;
        background-color: bisque;
        position: fixed;
      }

      #container {
        padding-top: 80px;
      }

      /* banner */

      #banner {
        width: 100%;
        background-color: #259682;
        height: 340px;
      }

      #banner > ul {
        list-style: none;
        width: 980px;
        height: 100%;
        background-color: #772299;
        margin: 0 auto; /* 수평 가운데 정렬 방법 중 하나 */
        display: flex; /* 수평 정렬 */
        overflow: hidden;
        /*
            슬라이드 배너: translate
            투명 배너: opacity
       */
      }

      #banner > ul > li {
        min-width: 100%; /* 최소길이 */
        height: 100%;
        /* display: inline-block; */
        /* position: absolute; */
        /* zindex: 100, 200, 300, 400*/
      }

      main {
        /* width: 980;
          margin: 0 auto; */
        height: 200vh;
        background-color: rgb(255, 125, 190);
      }

      main > aside {
        position: sticky;
        background-color: darksalmon;
        width: 320px;
        height: 100vh;
        top: 80px;
      }
    </style>
  </head>

  <body>
    <header></header>
    <div id="container">
      <section id="banner">
        <ul>
          <li>banner1</li>
          <li>banner2</li>
          <li>banner3</li>
          <li>banner4</li>
          <li>banner5</li>
        </ul>
      </section>
      <main>
        <aside>123</aside>
        <section></section>
      </main>
    </div>
    <footer></footer>
  </body>
</html>

 

 


 

 

Exercise 7 플렉스

 
<!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>flex</title>
    <style>
      * {
        padding: 0;
        margin: 0;
        box-sizing: border-box;
        list-style: none;
      }

      .flex {
        display: flex;
        width: 800px;
        height: 300px;
        border: 3px solid blue;
      }

      ul.flex {
        justify-content: center;
        justify-content: flex-end;
        align-items: center;
        align-items: flex-start;
        align-items: flex-end;
      }

      ul.flex > li {
        border: 3px solid #000;
        min-width: 100px;
        height: 80px;
        background-color: yellowgreen;
        /* 자식요소의 수직, 수평 가운데 정렬 ** li가 아님 */
        display: flex;
        justify-content: center;
        align-items: center;
      }

      div.flex {
        /*
        수직 수평 방향을 설정할 수 있고 사용하는 이유는
        수직 요소를 가운데정렬 하기 위해
        */
        flex-wrap: wrap;
        /* 부모요소에 height가 정해져 있다면 해당 길이의 줄 수 만큼 나누어 갖고 나머지 높이는 여백으로 채운다 */
        justify-content: center;
        justify-content: space-around;
        /* space-around : 각 요소에 동일한 여백 ; 기준은 항상 부모 요소임 ; 중간이 시작과 끝의 두 배 ; 시작--중간--끝 */
        justify-content: space-between;
        /* space-between : 요소들 사이에 여백(시작과 끝을 부모 요소 끝에 붙인다) */
        justify-content: space-evenly;
        /* space-evenly : 요소들 주변에 일정 여백 ; 부모 요소 기준으로 일정하게 띄워 놓는 것 ; 시작-중간-끝*/
      }

      div.flex > div {
        width: 33%;
        height: 100px;
        background-color: green;
        border: 1px solid #222;
      }
    </style>
  </head>
  <body>
    <h2>display flex</h2>
    <ul class="flex">
      <li>content_1</li>
      <li>content_2</li>
      <li>content_3</li>
      <li>content_4</li>
    </ul>
    <div class="flex">
      <div>content_1</div>
      <div>content_2</div>
      <div>content_3</div>
      <div>content_4</div>
    </div>
  </body>
</html>

 

 


 

 

Exercise 8 플랙스 2

 

<!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>Document</title>
    <style>
      * {
        margin: 0;
      }
      .flex-center {
        display: flex;
        justify-content: center;
        align-items: center;
      }

      .flex-align-center {
        display: flex;
        align-items: center;
      }

      div {
        width: 380;
        padding: 17px;
        background-color: #e7e7e7;
      }

      header {
        width: 100%;
        height: 100px;
        background-color: rgb(203, 255, 242);
      }

      footer {
        width: 100%;
        height: 300px;
        background-color: #419e9e;
      }

      div > form {
        justify-content: center;
        display: flex;

        align-items: center;
      }
    </style>
  </head>
  <body>
 

    <header></header>
    <main>
      <div class="flex-center">flex</div>
      <div>
        <form style="width: 280px; background-color: red">
          <p><input /></p>
          <p><input /></p>
          <p><input /></p>
          <p><input />회원가입</p>
        </form>
      </div>
    </main>
    <footer></footer>
  </body>
</html>