언제, 어떤 경우에 어떤 unit을 쓰는게 좋은지 한번 알아보자!
많은 unit은 두가지 카테고리로 나눠질 수 있다.
- 절대적 unit : px
- 상대적 unit : %, v*, em, rem
언제, 어떤걸 쓰는게 좋을까?
1/ 부모요소의 사이즈에 따라서 사이즈가 변경되어야 한다면 → %, em
2/ 부모요소의 사이즈에 상관없이 브라우저 사이즈에 따라 변경되어야 한다면 → v*, rem
3/ 요소의 너비와 높이에 따라서 사이즈가 변경되어야 한다면 → %, v*
4/ font 사이즈에 따라서 사이즈가 변경되어야한다면 → em, rem
# em vs rem 어떤 차이점이 있나요?
- em: relative to parent element
- rem : relative to root element
em vs rem 어떤게 더 낫다라는게 없다.
어떤 design인지에 따라서, 우리가 정확하게 원하는 기능이 무엇인지에 따라서 em을 쓰는게 더 적절할 때도 있고, rem을 쓰는게 더 적절할 때도 있다.
ex1) 'Like' 버튼의 컴포넌트를 만든다고 해보자.
## rem 사용할 경우
버튼의 글자를 rem을 쓰게되면, rem은 root에 따라서 크기가 결정되기 때문에
page의 가장 상위 요소인 body에서 컴포넌트를 쓸 때나 다른 컴포넌트 안에서 컴포넌트를 쓸 때의 크기가 전혀 변동사항이 없다.
'Like'버튼의 컴포넌트는 rem을 사용하고 있기 때문에, 부모 container에 있는 폰트 크기와는 상관없이 페이지에 어떤 박스안에서 사용해도 크기가 일정하게 고정되어있다.
1/ em 사용할 경우
em을 이용해서 컴포넌트를 만든다면
상위에서 썼을 때와, 부모요소에서 사용했을 때 'Like'버튼의 컴포넌트 크기 차이가 생기게 된다.
em은 부모요소의 font사이즈에 상대적으로 변하기 때문.
따라서,
- 페이지 어디에서 사용되어져도 사이즈가 그대로 고정되어야 한다면 : rem을 이용해서 스타일링 하는게 맞다.
- 컴포넌트가 어디에서 사용되느냐에 따라서 즉, 부모 요소에 따라서 유동적으로 변경되어야한다면 : em
em을 사용했을 경우에는 부모 요소인 body의 font-size가 16px이므로
- level1은 부모의 2em이므로16 * 2 === 32px
- level2 : 부모의 2em이므로 32px * 2 === 64px
- level3 : 부모의 2em이므로 64px * 2 === 128px
이렇게 2배씩 계산이 되어진다.
## em의 단점
이렇게 폰트 사이즈가 각각 얼마인지 즉각적으로 알기가 힘들다.
em은 직관적으로 알아보기가 힘들다.
2/ rem 사용할 경우
rem은 한번에 계산이 잘 된다.
root 요소(브라우저-보통 body태그)에서 16px를 이용하고 있기 때문에, 어떤 level에서 사용되느냐에 상관없이 무조건 2rem은 32px.
font-size가 고정적이다.
따라서, 폰트사이즈를 결정할때는 em보다는 rem을 더 선호.
3/ em 예시 (padding)
# padding이 px값일 경우
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>em vs rem</title>
<link rel="stylesheet" href="em_demo.css" />
</head>
<body>
<h1>Hello, dream coders</h1>
</body>
</html>
/* em_demo.css */
h1 {
display: inline-block;
font-size: 5em;
background-color: mediumaquamarine;
padding: 10px;
}
font-size는 5em을 사용해서 반응형으로 만들었지만, padding은 10px로 고정되어있다.
(대부분의 브라우저에서 'body'태그의 기본 'font-size'는 16px. 따라서 위 글자의 font-size는 80px.)
그래서 브라우저의 font-size를 변경하면 font-size는 변경되지만, padding은 10px로 고정되어있다.
# padding이 em값일 경우
padding도 font-size에 따라 변경시키고싶다면, 1em 이렇게 상대적인 값으로 주면 된다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>em vs rem</title>
<link rel="stylesheet" href="em_demo.css" />
</head>
<body>
<h1>Hello, dream coders</h1>
</body>
</html>
h1 {
display: inline-block;
font-size: 5em;
background-color: mediumaquamarine;
padding: 1em;
}
1em은 현재 요소의 font-size에 상대적인 크기를 나타냅니다.
즉, padding 속성에 1em 값을 주면, 그 요소의 현재 font-size와 동일한 크기의 여백이 적용됩니다.
** em은 현재 요소의 font-size, 또는 부모 요소의 font-size의 상대적인 크기이다.
예시)
부모 요소의 font-size가 16px, 현재 요소의 font-size가 1em, padidng이 1em일 경우
- 현재 요소의 font-size : 16px * 1 = 16px
- padding : 16px(현재 요소의 font-size) * 1 = 16px
Q. 부모 요소의 font-size와 현재 요소의 font-size가 다르다면, em은 어떤 값의 상대적 크기인가?
→ 현재 요소의 font-size를 따른다.
<!DOCTYPE html>
<html lang="en">
<body>
<h1>Hello, dream coders</h1>
</body>
</html>
h1 {
display: inline-block;
font-size: 5em;
background-color: mediumaquamarine;
padding: 1em;
}
위 예시를 보면,
- 부모 요소(body)의 font-size : 16px
- 현재 요소(h1)의 font-size : 5em이므로 16px * 5 = 80px
- padding : 현재요소의 font-size인 80px * 1 = 80px
media query를 이용해서 screen마다 font-size가 변경이 되면,
font-size에 맞게 padding이 1em으로 변경되기 때문에 조금 더 반응형으로 컴포넌트를 만들 수 있다.
h1 {
display: inline-block;
font-size: 5em;
background-color: mediumaquamarine;
padding: 1em;
}
@media screen and (max-width: 780px) {
h1 {
font-size: 3em; /* 16px * 3 = 48px; */
}
}
@media screen and (max-width: 680px) {
h1 {
font-size: 1.5em; /* 16px * 1.5 = 24px; */
}
}
너비가 1~680px까지는
font-size : 16px * 1.5 === 24px;
padding : 24px * 1 === 24px;
너비가 681~780px까지는
font-size : 16px * 3 === 48px;
padding : 48px * 1 === 48px;
이렇게 font-size에 맞게 padding이 변경된다.
4/ em vs rem demo
브라우저의 사이즈가 작아지면 font-size를 줄이는 것으로 만들어보자.
component의 width는 50%로,
em, rem도 반응형 unit이지만, font-size에 비례해서 변하므로
contents를 유동적으로 만들기 위해서는 %를 이용하는게 더 좋다.
<!-- rem_demo.html -->
<!DOCTYPE html>
<html lang="en">
<body>
<section class="component">
<header class="title">Master Front-end ✨</header>
<p class="contents">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sapiente
veniam, nulla porro distinctio aliquid, quos quidem odio consectetur
aperiam, delectus cum. Deserunt facilis excepturi similique natus minus
deleniti rem sit?
</p>
</section>
</body>
</html>
/* rem_demo.css */
.component {
width: 50%;
border: 1px solid burlywood;
font-size: 2rem; /* 16px * 2 = 32px */
}
.title {
padding: 0.5em; /* 부모요소 font-size인 32px * 0.5 = 16px */
background-color: burlywood;
}
.contents {
font-size: 1rem; /* 16px * 1 = 16px */
padding: 0.5em; /* font-size인 16px * 0.5 = 8px */
}
@media screen and (max-width: 780px) {
.component {
font-size: 1.5rem; /* 16 x 1.5 = 24px */
}
}
padding에 0.5em을 사용한다는 것은, 기존의 contents에 적용된 font-size의 0.5배로 계산이 되어진다.
그래서 font-size가 변경이 되면 padding이 조정이 되어진다.
- title에서의 padding : 16px
- contents에서의 padding: 8px
padding을 em을 써서 em은 현재요소의 font-size에 상대적으로 결정된다.
따라서, title의 font-size가 contents의 font-size보다 크기 때문에 조금 더 많은 padding이 들어간다.
수직적으로 정렬이 되지 않은 것처럼 보인다.
그래서 padding으로 em을 쓰는거 좋지만, 고정적인 padding을 유지하고 싶다면 rem을 사용하는 것이 좋다.
위아래는 font-size에 맞춰서 조정되도록 하는 것이 좋고 → em
양쪽은 0.5 rem을 사용해서 현재 font-size에 상관없도록 만드는 것이 좋다. → rem
.component {
width: 50%;
border: 1px solid burlywood;
font-size: 2rem;
}
.title {
padding: 0.5em 0.5rem;/* 위아래는 font-size에 맞게 조정. 양쪽은 font-size와 상관없이 고정된 값 */
background-color: burlywood;
}
.contents {
font-size: 1rem;
padding: 0.5em 0.5rem;/* 위아래는 font-size에 맞게 조정. 양쪽은 font-size와 상관없이 고정된 값 */
}
@media screen and (max-width: 780px) {
.component {
font-size: 1.5rem;
}
}
em, rem 둘 중, 꼭 1가지만 사용하기 보다는 컴포넌트의 디자인에 따라서 적절히 필요에 맞게 사용하는 것이 좋다.
5/ Final Project
이 사이트는 반응형이지만, font-size는 변경이 되지 않는다.
<!DOCTYPE html>
<html lang="en">
<!-- head 생략 -->
<body>
<h1>Dream Coding</h1>
<div class="container">
<section class="component">
<header class="title">Master Front-end ✨</header>
<p class="contents">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sapiente
veniam, nulla porro distinctio aliquid, quos quidem odio consectetur
aperiam, delectus cum. Deserunt facilis excepturi similique natus
minus deleniti rem sit?
</p>
</section>
<section class="component">
<header class="title">Career Growth 🚀</header>
<p class="contents">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sapiente
veniam, nulla porro distinctio aliquid, quos quidem odio consectetur
aperiam, delectus cum. Deserunt facilis excepturi similique natus
minus deleniti rem sit?
</p>
</section>
</div>
</body>
</html>
h1 {
font-size: 28px;
color: burlywood;
margin: auto;
text-align: center;
}
.container {
display: flex;
padding: 32px;
}
.component {
border: 1px solid burlywood;
margin: 16px;
}
.title {
font-size: 24px;
padding: 16px;
background-color: burlywood;
}
.contents {
font-size: 18px;
padding: 16px;
}
@media screen and (max-width: 768px) {
.container {
flex-direction: column;
}
}
font-size가 px로 고정되어 있으므로 브라우저 자체 font-size를 늘려도 변경되지 않는다.
.title에서 font-size를 rem을 사용하는 이유
- title이나 header 등의 글자들이 어떤 컴포넌트에 쓰이냐에 상관없이 동일한 사이즈를 유지하면 좋을 것 같아서 rem을 사용하는 것.
- padding같은 건 font-size에 따라서 padding도 바뀌면 좋을 것 같아서 em을 사용하고 있다.
h1 {
/* font-size: 28px; */
font-size: 1.75rem;
color: burlywood;
margin: auto;
text-align: center;
}
.container {
display: flex;
/* padding: 32px; */
padding: 2em;
}
.component {
border: 1px solid burlywood;
/* margin: 16px; */
margin: 1em;
}
.title {
/* font-size: 24px; */
font-size: 1.5rem;
/* padding: 16px; */
padding: 1em;
background-color: burlywood;
}
.contents {
/* font-size: 18px; */
font-size: 1.125em;
/* padding: 16px; */
padding: 1em;
}
@media screen and (max-width: 768px) {
.container {
flex-direction: column;
}
}
이제 사이트가 글꼴 크기를 변경하면(즉, root의 font-size를 변경하면) font-size와 padding이 변경된다.
하지만 여전히 브라우저 크기가 768px보다 작으면 flex-direction이 column이 된다.
정말 반응형으로 만들고 싶다면, mediaquery에서 max-width도 고정적인 pixel보다는 rem을 사용하면
글자크기가 큰 경우에는 768px보다 브라우저 크기가 더 커도 font-size에 맞게 flex-direction이 column으로 바뀐다.
@media screen and (max-width: 48rem) {
.container {
flex-direction: column;
}
}
글자크기를 크게 한 경우, width가 960px임에도 flex-direction이 column으로 변경된다.
글자크기를 작게 한 경우, width가 576px에서 flex-direction이 column으로 변경된다.
이렇게, 꼭 한 가지 unit만 사용해야 한다는 건 없다.
내가 어떤 걸 원하느냐에 따라서 적절히 사용하면 된다.
# 정리
- box자체의 사이즈를 결정할 때는 : %, v* 또는 flexbox를 이용하면 좋다.
- 요소의 font-size를 결정할 때 :
root를 상대로 변경되어야 할 때는 rem
부모 요소에 따라서 변동이 되어야 할 때는 em
참고 자료: 드림코딩
https://www.youtube.com/watch?v=xWMKz9NCD0k&list=PLv2d7VI9OotQ1F92Jp9Ce7ovHEsuRQB3Y&index=24
'CSS' 카테고리의 다른 글
[CSS] display에 대하여 (0) | 2023.12.17 |
---|---|
CSS Flexbox 완전 정리. 포트폴리오 만드는 날까지! | 프론트엔드 개발자 입문편: HTML, CSS, Javascript (1) | 2023.12.12 |
가상 클래스 셀렉터(Pseudo-Class Selector) (0) | 2023.10.17 |
[CSS] transition (트랜지션) (0) | 2023.10.10 |
HTML파일에 CSS 적용하는 방법 3가지 (0) | 2023.07.10 |