[CSS] 요소를 내가 원하는곳에 배치할래!! (with display,position)

Muru·2024년 11월 6일
0

1. display 속성

display 속성은 요소가 웹 페이지에서 어떻게 표시될것인가 정하는 속성이다.
해당 속성으로 공간과 배치를 적절하게 배치 하는것이 가능해진다.

display : flex , display : grid는 정말 정말 많이 쓰이므로 잘 숙지하자.

1.1 : display : none

none 속성값은 해당 요소가 DOM 트리에서 제거된다. 즉 보이지않는것은 당연하고 레이아웃에서도 없는것으로 된다.

유의 해야할 점으로 속성을 visibility 로주고 hidden 값으로 주는 경우다. 해당 경우는 화면에 표시만 되지 않을뿐 DOM 트리에서는 제거되지 않는다.

1.2 : display : flex

flex 속성값은 flex 박스를 활성화시켜서 자식들을 flex 아이템들을 취급하여 부모요소를 기준으로 아이템들을 배치 및 정렬시킬 수 있는 속성이다.
1차원 레이아웃을 구성할때 주로 사용되는 속성이다.

매우 중요하고 자주쓰이는 속성으로 지정해줄수있는 속성값의 종류도 매우 많으므로 잘 숙지 하고 사용해주면 좋다.
종종 display : grid와 우위비교하는 글이 보이는데 사이드프로젝트를 진행하면서 느낀점은 두 개 모두 장단이 있을뿐 어느것이 우위에 있지는 않은것 같다. 오히려 혼합하면서 많이 사용하는듯.

1.3 : display : grid

grid 속성값은 그리드 레이아웃을 구성하여 2차원 방식으로 레이아웃을 설계한다.
흔히 카드목록 또는 전체 페이지 레이아웃 틀을 잡는데 사용 된다.
부모 컨테이너 박스에 display : grid를 설정해주고
grid-template-columns 및 grid-template-rows를 설정하여 행열의 토대를 잡아주면 된다.

코드

App.js
    <div className={styles.container}>
      <div className={styles.item}>1</div>
      <div className={styles.item}>2</div>
      <div className={styles.item}>3</div>
      <div className={styles.item}>4</div>
      <div className={styles.item}>5</div>
      <div className={styles.item}>6</div>
      <div className={styles.item}>7</div>
      <div className={styles.item}>8</div>
    </div>
    
    
 Css
    
.container {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  grid-template-rows:repeat(2,minmax(200px,auto)) ;

}

.item {
  display: flex; /* 내부 콘텐츠를 수평/수직 정렬하기 위해 flexbox 사용 */
  justify-content: center; /* 내부 콘텐츠 수평 가운데 정렬 */
  align-items: center; /* 내부 콘텐츠 수직 가운데 정렬 */

  background-color: lightblue;
  border: 1px solid #333;
  text-align: center;
  padding: 20px;
}

1.4 : display : block

block 속성값은 요소를 블록레벨 요소로 만든다. 흔하게 쓰는 태그로 <div>태그,<p>태그,<h1~6>태그가 있다.

가로 영역을 모두 차지하며 항상 줄바꿈이 되어 새로운 라인에서 시작된다.

여백 지정(padding,margin 등) : 모든 방향 가능
width,height 지정 : 가능

물론 인라인레벨 요소를 가지는 태그들을 display:block 값을 지정하여 블록레벨 요소로 만드는것도 가능하다. 즉 다음과 같은 인라인 레벨 요소(<span>태그,<a>태그,<img>태그)를 블록레벨 요소로 변경하는것이 가능하다는 소리다.

1.5 : display : inline

inline 속성값은 block 속성값과는 반대로 인라인 레벨 요소로 만든다. 마찬가지로
<div>태그,<p>태그,<h1~6>태그들을 인라인 레벨 요소로 변경하는것이 가능하다.

width나 height는 따로 지정해주는것이 불가능하다. 딱 요소만큼의 요소 크기를 가진다. 또한 줄바꿈이 되지 않는다.

여백 지정(padding,margin 등) : 가로만 가능
width,height 지정 : 불가능

1.6 : display : inline-block

inline-block 속성값은 인라인 요소처럼 가로로 나란히 표시되지만 블록 요소처럼 width와 height를 설정할 수 있다.
속성값에 특징이 나와있듯이 줄바꿈이 되지않으면서 width와 height를 지정해주고싶을때 해당 속성을 사용하면 적절하겠다.

// 두개의 div 박스를 inline-block으로 지정하여 나란히 배치되게끔하고 width과 height도 지정이 가능!!
<div style="display: inline-block; width: 60px;">
  <img src="흑백코딩러.jpg" alt="Profile" style="width: 100%; height: auto;">
</div>
<div style="display: inline-block; vertical-align: top; width: 200px; padding-left: 10px;">
  <h4>나야</h4>
  <p>들기름</p>
</div>

1.7 : display : table

넣을까 말까하다가 넣은 속성값 table 되겠다.
table 속성값은 속성값의 이름그대로 행과 열로 테이블을 표현할때 사용 될 수 있다.

다만 flex값이나 grid값이 나오기전에는 정말 많이 사용했었지만 이제는 grid와 flex로 대체할 수 있는 것 같고 table 속성값을 지정해주지 않으면 특정 기능을 구현 못하는것은 아직까지 못본것같다.



2. position 속성

2.1 : position : static

어떠한 position을 지정해주지 않았을때 적용되는 속성값이 static.

static 속성값은 일반적인 흐름에 따라 배치가된다.

  • left,right,top,bottom의 속성을 사용해줄 수 없다 (효과가없음)

2.2 : position : relative

realtive 속성값은 일반적인 흐름에 따라 배치가 된다.

????????? 그럼 static이랑 다를게 없는데 ????????

static의 배치를 기준으로 요소의 실질적 위치는 그대로 두면서
offSet(top,right,bottom,left)을 설정하고 싶은경우 사용 될 수 있다.

다음 코드를 보자
 App.js
    <>
    <div className={styles["box"]}>BOX1</div>
    <div className={`${styles["box"]} ${styles["box-relatvie"]} `}>BOX2</div>
    <div className={styles["box"]}>BOX3</div>
    </>
    
 CSS
  .box {
  width:200px;
  height: 100px;
  background-color: red;
  margin : 10px;
  }

.box-relatvie {
  position: relative;
  top:400px;  
  left:400px;
  outline: 10px solid blue; /* 원래 위치를 확인하기 위한 테두리 */
  }
    


BOX2의 위치는 문서상 흐름에 따라 배치되고, 배치된기준으로 TOP에서 400px떨어지고, left에서 400px 떨어지는 offSet이 설정되었다. 문서상 위치는 BOX1과 BOX3의 사이 그대로임을 숙지하자.
offSet을 설정할경우 다른 요소를 덮어버리는 경우나 실행 흐름의 예상치 못한 결과가 일어날수 있으므로 미세한 움직임이 아니면 사용하는것을 지양하는것이 좋다.


다른 방식으로 쓰이는 방법은 realtive를 적용한 부모요소를 기준점으로 자식요소를 absolute속성을 지정하여 레이아웃을 배치해주고 싶을때 사용 할 수 있다.

2.3 : position : absolute

absolute 속성값은 일반적인 흐름에 따라 배치가 되지 않는다.
absolute 속성값은 가장 가까운 position: relative, absolute, fixed, sticky를 가진 부모 요소를 기준으로 위치한다. 만약 기준점이 없다면 뷰포트를 기준으로 삼는다.
부모 요소를 기준으로하여 offSet(top,right,bottom,left)의 위치를 지정하여 해당 위치로 배치가되며, 다른 요소에 영향을 주지 않는다.

2.4 : position : fixed

fixed 속성값은 일반적인 흐름에 따라 배치가 되지 않는다.

  • 뷰포트를 기준으로 한 위치에 배치된다.
  • 스크롤되어도 움직이지 않는 고정된 자리를 갖게 된다.

2.5 : position : sticky

sticky 속성값은 상대적 위치와 고정된 위치의 특징들을 동적으로 전환되도록 해주는 CSS 속성이다. 즉 relative와 fixed를 왔다갔다 한다.
해당 속성을 사용하여 스크롤에 따른 특정 header 동적 렌더링을 구현해 볼 수 있다.

stikcy의 동작 방식은 다음과 같다.
1. 브라우저가 처음 랜더링 되었을 때 sticky 요소는 문서 흐름에 따라 일반적인 위치에 배치 된다.
2. 스크롤이 지정된 위치에 도달할 때까지 sticky 요소는 일반적인 흐름대로 따라 이동 한다.
3. 스크롤의 좌표가 지정된 위치에 도달하면 sticky 요소가 지정된 위치에 고정된다.
이제 지정된 위치 이하로 스크롤해도 해당 위치에 고정되어 유지된다.
4. 부모요소의 끝에 도달하면 sticky한 속성이 풀려 다시 동적으로 상대적 위치로 포지션이 잡힌다.

다음과 같은 기능을 만들어 볼 수 있다.

부모요소를 기준으로(height가 100vh), sticky 요소가 적용된 자식요소가 부모요소의 top:0을 도달한다면 fixed된것처럼 고정된다. sticky 요소가 부모의 컨테이너 밖으로 나가게된다면 fixed속성은 풀리고 다시 relative한 속성을 가지게되고. 다음 요소가 top:0에 도달하여 fixed되어 고정된다.

코드들
App.js

import React from "react";
import styles from "./App.module.css";

const App = () => {
  return (
      <div className={styles.container}>
        <div className={`${styles.slide} ${styles["slide-one"]}`}>
          <h1>첫 번째 이미지 - 흑</h1>
        </div>
        <div className={`${styles.slide} ${styles["slide-two"]}`}>
          <h1>두 번째 이미지 - 백</h1>
        </div>
        <div className={`${styles.slide} ${styles["slide-three"]}`}>
          <h1>세 번째 이미지 - 요</h1>
        </div>
        <div className={`${styles.slide} ${styles["slide-four"]}`}>
          <h1>네 번째 이미지 - 리</h1>
        </div>
      </div>
  );
};

export default App;

App.module.css

.container {
  height: 100vh;
  font-family: Lora, serif;
  overflow-x: hidden;
}

.slide {
  position: sticky;
  top:0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  letter-spacing: 0.2em;
  color: white;
  background-size: cover;
  background-position: center;
}

.slide h1 {
  font-size: 250%;
  text-shadow: 0 2px 2px black;
}

.slide-one {
  background-image: url("https://i.loli.net/2019/11/23/cnKl1Ykd5rZCVwm.jpg");

}

.slide-two {
  background-image: url("https://i.loli.net/2019/10/18/uXF1Kx7lzELB6wf.jpg");

}

.slide-three {
  background-image: url("https://i.loli.net/2019/11/16/FLnzi5Kq4tkRZSm.jpg");
}

.slide-four {
  background-image: url("https://i.loli.net/2019/10/18/buDT4YS6zUMfHst.jpg");
}```
profile
Developer

0개의 댓글