End - CSS

프론트엔드 CSS 기본기 정리

2021.07.19 ~ 2021.07.26

CSS 서론, 링크

CSS는 HTML을 꾸며주는 역할

앞서서, 웹페이지의 문서를 HTML을 이용하여 작성하였다면 마치 앙상한 뼈대처럼 볼품없는 파일만 남아있을 것이다. CSS를 이용하여 이 뼈대에 살을 붙혀줘서 보기 좋게 만들 것이다.

그리고 하면서 느낀건데 너무 기초적인 것을 해서 그런 것일 수도 있는데 직관적이어서 백엔드보다 훨씬 재밌는 것 같다 ^^

아래는 도움을 받은 문서와 강의이다.


기본적인 CSS의 사용법 - http://tcpschool.com/css/intro
CSS 참고 문서 MDN - https://developer.mozilla.org/en-US/docs/Web/CSS
CSS 적용 인터넷 참고 - https://caniuse.com/
CSS 색깔 코드값 참고 - https://material.io/resources/color
CSS Flexbox 내용 - https://css-tricks.com/snippets/css/a-guide-to-flexbox/

드림코딩 엘리님의 CSS 기본 1강 - https://www.youtube.com/watch?v=gGebK7lWnCk
드림코딩 엘리님의 CSS 기본 2강 - https://www.youtube.com/watch?v=jWh3IbgMUPI
드림코딩 엘리님의 CSS 기본 3강 - https://www.youtube.com/watch?v=7neASrWEFEM
드림코딩 엘리님의 CSS 기본 4강 - https://www.youtube.com/watch?v=8-uJ_4136uI
드림코딩 엘리님의 CSS 기본 5강 - https://www.youtube.com/watch?v=7Z3t1OWOpHo
드림코딩 엘리님의 CSS 기본 6강 - https://www.youtube.com/watch?v=xWMKz9NCD0k


CSS Cascading

Cascading의 의미를 깊게 살펴보자

CSS는 Cascading Style Sheets의 약자이다. cascading은 폭포, 연속 같은 의미인데 스타일 시트들 간에 정해진 세부적인 정의가 있다면 그것을 사용하고 없으면 다른 곳에 가서 또 찾아보고 이런식으로 진행되는 것이다.

폭포가 흐르듯 위에서 아래의 순서로 떨어진다고 생각한다. Author style(개발자가 정의한 스타일), User Style(사용자가 정의한 스타일), Browser(브라우저가 정의한 스타일)이 있을때 Author -> User -> Browser 순서로 우선순위가 정해지는 느낌이다.

이때 이 cascading을 끊어내는 역할을 하는 명령어가 바로 important라고 한다. important가 보이면 일단 무서워하고 본다. 가능한 안쓰는게 좋긴 하다.

CSS(1) - Selector

CSS(1) : 셀렉터

CSS의 문법은 딱히 공부할 게 없이 너무 간단하다. selecter(선택자) + property(속성) + value(속성값)

selector { property: value; }

선택자와 선언부로 작성만 해주면 된다. 여기서 선택자가 중요한데, 선택자는 CSS를 적용하고자 하는 HTML 요소를 가르킨다.

선택자는 크게 Universal, type, id, class, state, attribute를 사용할 수 있다. 순서대로 * , tag , #id , .class , : , []를 이용하면 된다. CSS의 selectors를 사용하는 방법을 터득할 수 있는 게임을 해보면 좋다. https://flukeout.github.io/ 강추 !!

CSS(2) - Layout

CSS(2) : 레이아웃 Display, Position

display는 말 그대로 보여지는 화면을 변경하는 것이다. HTML에서 배웠던 사용자에게 보여지는 요소 Block vs Inline을 기억해보자.

<!-- Block-level -->
<div></div>
<div></div>
<div></div>

<!-- Inline-level -->
<span></span>
<span></span>
<span></span>

여기서 div는 대표적인 Block 요소이고 span은 대표적인 Inline 요소이다. 하지만, CSS에서 이를 바꿀 수 있다.

div { display: inline; }
span { display: block; }

자유자재로 바꾸면서, CSS를 이용한 박스 배치를 새로운 줄에서 시작할 것인지 같은 줄에서 바로 배치할 것인지 정할 수 있다. 추가로, span 태그의 내용이 없으면 출력되는 화면에 아무 것도 안나올 수 있으니 당황하지 말자.

position은 웹 페이지 상에서 박스 배치를 하기 위해서 아주 중요하다. 이해를 돕기 위해 컨테이너 안에 작은 박스 1, 2, 3, 4가 있다고 생각하자.

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
  </head>
  <body>
    <article class= "container">
      <div>작은 박스 1</div>
      <div class= "box">작은 박스 2</div>
      <div>작은 박스 3</div>
      <div>작은 박스 4</div>
div {
	width: 50px;
    height: 50px;
    margin-bottom: 20px;
    background: red;
}

.container {
	background: yello;
    left: 20px;
    top: 20px;
    position: relative;
}

.box {
	background: blue;
    left: 20px;
    top: 20px;
    position: relative;
 }

위 코드에서 포지션 값을 설정해주지 않으면 작은 박스를 어떻게 옮기더라도 위치는 바뀌지 않고 박스는 가만히 있을 것이다.

왜냐하면, CSS에서 position의 기본값으로 static을 가지고 있기 때문이다. position이 가질 수 있는 값은 static, relative, absolute, fixed, sticky 이렇게 5가지이다.

static은 가만히 있는 상태이다.
relative는 상대적인 위치를 나타낸다.
absolute는 절대적인 위치를 나타낸다.
fixed는 페이지 상의 위치를 나타낸다.
sticky는 스크롤링 되어도 없어지지 않고 원래 있던 자리에 그대로 있는 것을 나타낸다.

relative, absoulte, fixed를 조금 더 구체적으로 살펴보면, 위 코드에서 큰 박스 자체를 왼쪽에서 20px, 오른쪽에서 20px 떨어뜨렸다. 큰 박스를 옮김에 따라 안에 있는 작은 박스들 역시 위치가 바뀌는 것이다.

이때, 작은 박스의 position을 relative로 하면 바뀐 위치에서 상대적으로 왼쪽에서 20px, 오른쪽에서 20px 떨어뜨릴 것이고 absolute로 하면 속해있는 큰 박스의 시작에서 왼쪽에서 20px, 오른쪽에서 20px 떨어뜨릴 것이고 fixed로 하면 최초에 페이지 상 시작의 왼쪽에서 20px, 오른쪽에서 20px 떨어뜨릴 것이다.

position의 상태에 따라 변화가 어떻게 되는지 그림으로 그려서 확인하는 것이 좋다.

CSS(3) - Flexbox

CSS(3) : Flexbox!! 박스와 아이템들을 행, 열 자유자재로 배치 !!

웹 페이지의 레이아웃을 주무르기 위하여 필요한 것이 바로 CSS3의 Flexbox 이다. 에전에는 position, float, table을 이용하여 레이아웃을 하곤 했는데, 예를 들어 float의 원래 목적은 이미지와 텍스트를 어떻게 배치할 것인지에 대한 도구였는데 원래의 목적과 다르게 레이아웃을 위하여 사용했었다.

그 후에 레이아웃을 위하여 나온 것이 바로 CSS3의 Flexbox이다.

Flex box는 딱 2가지만 이해하면 된다.


1. Flexbox는 container에 지정하는 속성값이 있고 item에 지정하는 속성값이 있다.

2. Flexbox에는 중심축과 반대축이 있다. 예를 들어 x(수평), y(수직)축이 있을 때
수평 축을 중심축이라고 하면 수직 축이 반대축이 되는 것이다.
물론 수직 축을 중심 축으로 잡아도 된다.


Flexbox를 사용하기 위해선 CSS의 container display 값을 flex로 설정해야 한다. display: flex; 는 block 형식이지만 Inline 형식으로 하고 싶다면, inline-flex로 설정하면 된다. 기본적으로 하나의 플렉스 컨테이너는 하나의 플렉스 라인 만을 가진다.

먼저, container에 지정하는 속성값은 display, flex-direction, flex-wrap, flex-flow, justify-content, align-items, align-content가 있고 item에 지정하는 속성값은 order, flex-grow, flex-shrink, flex, align-self가 있다.

각각의 기능은 큰 틀에서 이해하고 있고 외우지는 말고 위의 링크 https://css-tricks.com/snippets/css/a-guide-to-flexbox/ 를 참조한다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
  </head>
  <body>
    <div class="container">
      <div class="item item1">1</div>
      <div class="item item2">2</div>
      <div class="item item3">3</div>
      <div class="item item4">4</div>
      <div class="item item5">5</div>
      <div class="item item6">6</div>
      <div class="item item7">7</div>
      <div class="item item8">8</div>
      <div class="item item9">9</div>
      <div class="item item10">10</div>
    </div>
  </body>
</html>
.container {
  padding-top: 100px;
  background: beige;
  height: 100vh;
  display: flex;
}

.item {
  width: 40px;
  height: 40px;
  border: 1px solid black;
}

.item1 {
  background: #ef9a9a;
  flex: 2 2 auto; 
  align-self: center;
}

.item2 {
  background: #f48fb1;
}

이와 같이 html과 CSS 문서를 작성하여 flexbox의 기능을 파악하면 큰 도움이 된다. 코드를 작성할 때 역시 Emmat을 사용하여 div.container>div.item.item{}* 10를 이용하자.

CSS 코드의 vh는 viewport height이다. 예를 들어, 100%라고 하면 컨테이너 박스에 해당하는 만큼만 백그라운드 색깔이 들어갈 것이다. 왜냐하면, 컨테이너 박스는 body 태그에 속해있고 body 태그는 또 html 태그에 속해있다. 따라서,
body, html 둘 다 100%로 설정해야 보이는 페이지 전체에 값이 적용된다.

따라서, 부모와 관계 없이 사용자의 눈에 보이는 높이를 맞추고 싶다면 100vh를 써서 맞추면 된다. 80vh라고 하면 보이는 높이의 80%에 해당하는 만큼 적용된다.

혹시, %와 vh에 관한 설명을 읽으면서 왜 굳이 vh를 사용하는 지에 대한 의문을 품지는 않았는가? 바로 나중에 설명할 반응형 웹 디자인 때문에 사용하는 것이다. vh와 vw는 %와 다르게 스크롤 바의 영역을 포함하기 때문에 반응형 웹에 아주 중요하다.

백그라운드 컬러를 적용할 때 위의 링크 color tools
https://material.io/resources/color/#!/?view.left=0&view.right=0
를 참조하면 된다.

마지막으로 CSS의 Flexbox를 이해하기 좋은 게임 링크이다. https://flexboxfroggy.com/#ko 강추!!

CSS(4) - Responsive Web

CSS(4) : 반응형 웹디자인 Responsive Web Design

예전과는 다르게, 현재의 시대에 오면서 데스크탑 뿐만이 아닌 태블릿, 모바일도 사용하는 시대가 왔다. 따라서, 고정적인 값을 사용한 레이아웃을 쓰면 태블릿이나 모바일에서는 화면이 잘리는 현상이 발생하기 때문에 유동적인 레이아웃 Fluid Layout을 사용해야 한다.

예전에는 유동적인 레이아웃을 구성하기 위해서 float과 % 값을 이용해서 많이 구현 했었는데 요즘에는 고정된 px 값을 사용하지 않고 Flex grid, Flex box, %, vw, vh를 이용하여 사이즈를 많이 구성하게 된다.

CSS의 속성 값들만 잘 사용해도 웹 페이지는 반응하여 레이아웃이 재배치 되는 놀라운 효과를 가지게 된다. 이를 구현하기 위해서는 CSS의 Media Queries를 사용하여 쉽게 구현할 수 있다.


사진 출처 : https://www.youtube.com/watch?v=8-uJ_4136uI 4분 38초

위와 같이 모바일, 태블릿, 데스크탑에 해당하는 섹션의 공간을 설정할 수 있다. 즉, 유동적으로 내용을 재배치해서 보이게 할 수 있는 것이다.

예전에는 어디서부터 어디까지가 데스크탑인지, 태블릿인지, 모바일인지 구분을 했었는데 최근에는 딱 맞다고 구분하기가 힘들다. 굳이 나누자면
모바일은 320px ~ 480px, 태블릿은 768px ~ 1024px, 데스크탑은 1024px ~와 같이 간주하면 무난하게 반응형으로 만들 수 있다.

Media Queries의 기본적인 문법은 어렵지 않다.

@media screen and (min:width: 800px) {
	.container {
    	   width: 50%;
        }
}

@media라는 프리 픽셀을 쓰고 screen의 최소의 너비가 800이면 이 컨테이너를 스타일링 해주세요! 라는 의미를 가지고 있다.

쓸 수 있는 type은 screen말고도 all, print, speech가 있고 and라는 문법은 not, only, ,(comma)를 사용해서 작성할 수 있다.

CSS(5) - units

CSS(5): 프론트엔드 필수 반응형 CSS Units(단위) 총정리

CSS(4)에서 말했듯이 반응형 웹을 만들기 위한 단위를 설명하려고 한다. 대표적으로 size를 결정하는 unit은 크게 Absolute/Relative 두 가지로 나눈다.

Absolute에서는 모니터 위에서 화면에 나타낼 수 있는 가장 작은 단위인 px(Pixels)를 주로 사용한다. 그런데, 큰 문제점이 있다. Container의 사이즈가 변경되어도 Contents가 그대로 고정된 사이즈 값을 유지하는 것이다. font-size를 px로 쓰게 되면 사용자가 브라우저에서 폰트 사이즈 설정을 변경해도 반응하지 않는다. 그래서 폰트 사이즈를 적을 때 % 를 이용해서 부모의 몇 퍼센트 인지를 표기하는 방식으로 많이 사용한다.

html {
	font-size: 100%;
}

이건 브라우저에서 지정한 폰트 사이즈를 따라간다는 의미이다. 다른 요소에서 em과 rem을 사용하고 브라우저 환경에서 폰트 사이즈를 변경하면 웹 사이트가 반응하여 폰트 사이즈가 변경 되는 것을 확인할 수 있지만, 만약 %가 아니라 고정된 px 값을 루트인 html에서 사요하면 더이상 반응형이 되지 않고 폰트 사이즈가 변경되지 않는 것을 확인할 수 있다.

Relative에서는 대표적으로 em / rem / vw / vh / %를 주로 사용한다.


em(relative to parent element) : 부모 요소에 의해 상대적으로 크기가 계산된다.
rem(relative to root element) : 루트 요소에 의해 상대적으로 크기가 계산된다.
vw(viewport width) : 브라우저의 너비의 몇 %를 사용하겠다.
vh(viewport height) : 브라우저의 높이의 몇 %를 사용하겠다.
% : 부모 요소에 의해 상대적으로 크기가 계산된다.


em과 rem에 관하여 세부적으로 설명을 하겠다.

em은 typography에서 현재 지정된 pt(pont size)를 나타내는 단위이다. 즉, 지금의 폰트 사이즈를 나타내는 단위라고 이해하면 된다. 같은 폰트 사이즈 이더라도 어떤 폰트를 사용하는 지에 따라 사용자에게 보여지는 텍스트의 크기는 달라질 수 있다. em은 선택된 폰트에 상관없이 고정된 폰트 사이즈를 가지는 것이다.

예를 들어, 현재 fontsize: 16px 이라면, 1em == 16px이다.

그렇다면 em은 왜 상대적이라는 것일까? em은 부모 요소에 의해 상대적으로 크기가 계산된다는 것이라고 위에서 설명했다. 기본적으로 브라우저에서 HTML에 할당하는 폰트 사이즈는 16px이다.

.parent {
	font-size: 8em;
}

.child {
	font-size: 0.5em;
}

Parent 8em = HTML (Parent의 부모 요소) 16px * 8 = 128px
Child 0.5em = Parent (Child의 부모 요소) 128px * 0.5 = 64px

em을 살펴보면 %와 굉장히 비슷하다는 것을 알 수 있다. 즉, 8em을 800%라고 쓰면 동일하게 작동한다는 것이다. 0.5em을 50%라고 써도 된다.

.parent {
	font-size: 8rem;
}

.child {
	font-size: 0.5rem;
}

Parent 8rem = root HTML의 16px * 8 = 128px
Child 0.5rem = root HTML의 16px * 0.5 = 8px

em과 rem의 차이가 어떤 것인지 파악할 수 있지 않는가?

다음으로 간단하게 viewport related를 말하겠다.

100vw = 브라우저의 너비에 있는 100%를 사용하겠다.
50vw = 브라우저의 너비에 있는 50%를 사용하겠다.

vmin과 vmax도 있는데, vmin은 브라우저의 너비와 높이 중에서 작은 값을 채택하여 사용한다는 것이고 vmax는 큰 값을 채택하여 사용한다는 것이다.

마지막으로, %와 v* (view port)의 차이를 설명하겠다. CSS(3)에서 설명한 것도 있지만, 아래의 코드를 봐보자.

.parent {
	font-size: 8em;
   	width: 500px;
}

.child {
	background-color: beige;
	font-size: 0.5em;
    width: 50%;

%는 부모 요소의 상대적인 크기라고 하였다. 현재 부모 요소의 너비가 500px이라는 값으로 고정되어있으니까 자식 요소의 너비가 250px로 고정이 되는 것이다. 따라서 웹의 크기를 조정할 때 자식 박스의 크기에는 변화가 없다.

근데 50%가 아닌 50vw로 작성하면, 브라우저(view port)의 50%에 해당하는 너비이기 때문에 크기를 조정할 때 반응하여 크기가 바뀌는 것이다.


CSS(6) - when em, rem?

CSS(6) : em과 rem 언제 어떻게 써야할까?

CSS의 반응형 units을 사용할 때 두 가지 기준으로 나누어서 생각한다.


(1) 부모 요소의 사이즈에 따라서 사이즈가 변경이 되어야 한다면 %, em 부모 요소의 사이즈와 상관없이 브라우저 사이즈에 대해서 반응해야 한다면 v*, rem

(2) box의 너비와 높이에 따라서 사이즈가 변경이 되어야 한다면 %, v* 폰트 사이즈에 따라서 사이즈가 변경이 되어야 한다면 em, rem


그리고 em과 rem을 사용할 때, 둘 중 어느 것이 더 낫다고 할 수는 없고 어떤 디자인인지에 따라서, 원하는 기능이 무엇인지에 따라서 적절한 것을 선택해서 사용해야한다.

나의 컴포넌트가 페이지 어디에서 사용되어도 크기가 고정되어야 한다면 rem을 사용 나의 컴포넌트가 어디에서 사용되는지 즉, 부모 요소에 따라서 크기가 유동적으로 변경되어야 한다면 em을 사용해서 스타일링 한다.

  1. em과 rem을 사용하는 예제
    다음으로, 폰트 사이즈를 결정할 때는 em보다 rem을 사용하는걸 선호한다.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
  </head>
  <body>
    <div class="level1">
      <h1>level 1</h1>
      <div class="level2">
        <h1>level 2</h1>
        <div class="level3">
          <h1>level 3</h1>
          <div class="level4">
            <h1>level 4</h1>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>
.level1 {
  font-size: 2em;
}

.level2 {
  font-size: 2em;
}

.level3 {
  font-size: 2em;
}

.level4 {
  font-size: 2em;
}

이렇게 복잡한 코드가 있을 때, em을 사용하면 폰트 사이즈가 어떻게 되는지 즉각적으로 파악하기가 힘들고 계산하는 과정을 거쳐야한다. 만약 2em이 아닌 2rem으로 적혀있다면 모두 32px의 크기를 가진다고 바로 생각해낼 수 있다.

  1. em과 rem을 사용하는 예제 padding 관련
<body>
	<h1>Hello, Worlds!</h1>
</body>
h1 {
	display: inline-block;
    font-size: 5em;
    background-color: beige;
    padding: 10px;
}

이렇게 padding이 10px로 고정되어 있으니 웹 사이트를 줄였다가 늘렸다가 할 때 font는 작은데 padding은 크거나 font는 큰데 padding은 작거나 이렇게 느껴지는 경우가 발생한다.

즉, padding도 font-size에 따라서 변경되어야 한다면 px보다는 1em과 같이 설정한다면, font-size가 변경됨에 따라 padding도 그에 맞게 변경된다.

이를 응용하면 CSS의 Media Queries를 이용하여 스크린마다 font-size가 변경이 되면 font-size에 맞게 padding이 변경되니까 조금 더 반응형으로 컴포넌트를 만들 수 있다.

  1. em과 rem 둘 중 하나만 사용하라는 말은 아니다.
.title {
	padding: 0.5em 0.5rem;
    background-color: burlywood;
}

.contents {
	font-size: 1rem;
    padding: 0.5em 0.5rem;
}

title, contents로 나누어진 박스가 있다고 상상하자. 안에 내용이 담겨져 있는데 웹 사이트 크기를 조절할 때 위아래 패딩은 em으로 반응하게 만들고 양옆 패딩은 rem으로 고정되게 만들면 수직적으로 글씨가 정렬되어 보이는 효과를
주게 된다.

어떤 컴포넌트를 어떻게 디자인 하는 지에 따라서 적절하게 사용하는 것이 가장 중요 !

픽셀에서 em이나 rem 계산이 바로 바로 안될 때 변환하기 좋은 사이트 http://pxtoem.com/ 도 이용하도록 하자.

좋은 웹페이지 즐겨찾기