CSS

왕지호·2022년 10월 27일
0

오늘은 마크업의 꽃, HTML 문서에 스타일을 부여할 수 있는 CSS에 대해 알아보자!

CSS

  • 웹페이지 스타일 및 레이아웃을 정의하는 스타일시트 언어
  • HTML구조의 UX를 제공하기 위해 UI 및 레이아웃을 적절히 구성하여 멋진 웹페이지 완성이 가능하다.
  • 웹 사이트 사용자가 HTML 문서에 작성된 콘텐츠를 잘 이해할 수 있도록 돕는 역할을 한다.

주의!: CSS는 UI(사용자 인터페이스)를 고려해야한다!
...

그렇다면 UI는 무엇일까?

사용자 인터페이스(UI; user interface)

인터페이스는 컴퓨터와 교류하기 위한 연결고리!
메세지를 키보드 인터페이스로 입력하고, 마우스 모양 인터페이스를 사용할 수 있는 것처럼 사용자가 쉽게 사용할 수 있는 인터페이스는 앞에 ‘사용자’를 붙여 사용자인터페이스, 즉 UI라고 부름

직관적이고 쉬운 UI 제작은 프론트엔드 개발자의 기본 소양

FE는 웹 개발 기술을 기반으로 사용자와 소통할 수 있는 웹 페이지 제작을 담당한다. 그렇기 때문에 애플리케이션과 소통이 필요한 UI 제작은 FE 개발자의 기본 소양이다.

CSS를 잘 이용해 본텐츠가 더욱 잘 보이게 레이아웃을 적절히 디자인하는 것이 필요

  • 아무리 훌륭한 내부 기능을 갖고 있더라도, UI가 없으면 소용 X
  • 사용자가 애플리케이션을 사용하게 하려면 UI가 꼭 필요!

이처럼 중요한 UI를 만드는 것이 프론트엔드 개발자의 역할이다!

그럼 이제 UI의 중요성을 알았으니, CSS 내용에 대해 알아보자!

CSS 내용

  • 하나에 집중하기 위해 파일이나 구간을 구분하는 관심사 분리 측면에서 인라인 스타일과 내부 스타일 시트는 권장하지 않는다.
  • 다만, 파일로 굳이 구분하지 않아도 될 만큼 적은 css는 예외로 한다.

CSS에는 id와 class가 있는데, 그 둘의 차이점을 표로 보자.

id와 class의 차이점

idclass
#으로 선택.으로 선택
한 문서에 단 하나의 요소에만 적용동일한 값을 갖는 요소 많음
특정 요소에 이름을 붙이는 데 사용스타일의 분류(classification)에 사용

흠... id랑 class로 구분하는건 알겠어! 그럼 다른 요소를 바꿀 때는 어떻게 할까?

만약...글자 색이나 글꼴을 바꾸고 싶을때 어떻게 하지? 정렬은...?

색상

.red {
  color: #ff0000;
}

.box {
  color: #155724; /* 글자 색상 */
  background-color: #d4edda; /* 배경 색상 */
  border-color: #c3e6cb; /* 테두리 색상 */
}

글꼴 font-family , font-size

.emphasize {
  font-family: "SF Pro KR", "MalgunGothic", "Verdana";
}
h1{
	font: 12px/1em "SF Pro KR" #ff0;
}
.title {
  font-size: 24px;
}
  • google font 이용해 다양한 글꼴 사용 가능
  • 굵기: font-weight
  • 밑줄, 가로줄: text-decoration
  • 자간: letter-spacing
  • 행간: line-height

정렬

  • 가로로 정렬할 경우 text-align, 유효한 값으로는 left, right, center, justify(양쪽 정렬)
  • 세로로 정렬할 경우에는 문제가 조금 복잡하다.
    vertical-align 속성을 쉽게 떠올릴 수 있지만, 이 속성은 부모 요소의 display 속성이 반드시 table-cell이어야 하기 때문이다.

어라...? 그럼 글꼴 사이즈는 px 하나만 쓰나? 그거 말고 다른 단위가 있나?

...있다! 바로 글꼴에 따르냐 화면에 따르냐 정할때 말이다!

절대단위/상대단위

  • 절대 단위: px, pt
  • 상대 단위: %, em, rem, ch, vw, vhMDN , w3schools 참고

글꼴 사이즈를 정할 때

px

  • 기기나 브라우저 사이즈 등의 환경에 영향을 받지 않는 절대적인 크기로 정하는 경우 px사용한다.
  • 픽셀은 크기가 고정된 절대 단위이기 때문에 사용자 접근성이 불리하다.
  • 픽셀은 인쇄와 같이 화면의 사이즈가 정해진 경우에 유리
  • 그렇기 때문에 상대 단위인 rem을 추천(root의 글자 크기)

rem

  • 브라우저의 기본 글자 크기가 1rem이며, 두 배로 크게 하고 싶다면 2rem, 작게 하려면 0.8rem 등으로 조절해서 사용 가능하다.
  • 사용자가 설정한 기본 글꼴 크기를 따르므로, 접근성에 유리하다.
  • (em은 부모 엘리먼트에 따라 상대적으로 크기가 변경되므로 계산이 어려운데 rem은 root의 글자 크기에 따라서만 상대적으로 변한다)

화면 사이즈를 정할 때

반응형 웹(responsive web)에서 기준점을 만들 때

  • 반응형 웹은 디바이스의 너비(width)에 따라 유동적인 레이아웃이 적용되는 웹사이트
  • 디바이스 크기를 나누는 기준을 보통 px로 정함

화면 너비나 높이에 따른 상대적인 크기가 중요한 경우

  • 이때에는 vw, vh를 사용(웹사이트의 보이는 영역을 Viewport라고 함)
  • vw , vh는 각각 viewport width와 viewport height를 뜻하며, 1vw는 보이는 영역 너비의 1/100, 1vh는 보이는 영역 높이의 1/100
  • 화면을 가득 채우며 딱 떨어지게 스크롤 되는 사이트의 경우 100vw, 100vh를 사용해 구현한다.

우와 생각보다 고려해야 할게 많네...? CSS는 생각보다 복잡하네...

맞다. CSS는 깊게 파고들면 파고들수록 어렵다.
그 이유로 모든 콘텐츠는 고유한 영역이 있는데, 그것을 하나하나 지정하고 특성을 고려해서 스타일을 하려니 어려운 것이다...!

예를 들어 박스모델을 한 번 알아보자.

박스 모델은 두가지로 나눌 수 있다

줄 바꿈이 되는 박스(block) vs. 옆으로 붙는 박스(inline, inline-block)

  • 줄 바꿈이 되는 박스는 block 박스
  • 줄 바꿈이 일어나지 않고, 크기 지정을 할 수 없는 박스는 inline 박스
  • 줄 바꿈이 일어나지 않는 동시에 block 박스의 특징을 가지는 inline-block 박스
  • 줄 바꿈이 되는 요소: <h1>, <p>
  • 줄 바꿈이 되지 않는 요소: <span>

더 많은 block 요소의 목록은 MDN block 엘리먼트 목록, inline 요소의 목록은 inline 엘리먼트 목록을 찾아보자!

  • block 요소의 대표적인 예는 <div>, <p>
  • inline 요소의 대표적인 예는 <span>
  • inline-block 박스는 inline 박스처럼 다른 요소의 옆으로 붙으면서, 자체적으로 고유의 크기를 가진다.
span {
  background: yellow;
  display: inline-block;
  width: 100px;
  height: 100px;
}

표로 간단히 세가지를 비교해보자!

아! 박스요소는 3가지로 나뉠 수 있구나... 그렇다면...박스를 구성하는 요소로 무엇이 있을까?

박스를 구성하는 요소

border (테두리)

  • border 속성에 적용된 각각의 값은 테두리 두께(border-width), 테두리 스타일(border-style), 테두리 색상(border-color)
p {
  border: 1px solid red;
}

margin (바깥 여백) / padding (안쪽 여백)

  • 각각의 값은 top, right, bottom, left로 시계방향(상우하좌)
p {
  margin: 10px 20px 30px 40px;
	padding: 10px 20px 30px 40px;
}

/* 값을 두 개만 넣으면 top과 bottom이 10px, left 및 right가 20px */

p {
  margin: 10px 20px;
}

/* 값을 하나만 넣으면 모든 방향의 바깥 여백에 적용 */

p {
  margin: 10px;
}

/* 음수도 사용 가능-> 화면 밖에서 사라지거나 겹치게 만들 수 있음 */
p {
  margin-top: -2rem;
}

박스를 벗어나는 콘텐츠 처리

  • 박스의 height 속성에 콘텐츠가 차지하는 공간보다 작은 값을 지정할 때, 콘텐츠가 박스를 뚫고 나가는 경우에는 박스 크기에 맞게 콘텐츠를 더 이상 표시하지 않거나, 혹은 박스 안에 스크롤을 추가하여 콘텐츠를 확인할 수 있게 만든다.
p {
  height: 40px;
  overflow: auto;
}

overflow: hidden; overflow-x, overflow-y 도 사용 가능하다

여백과 테두리 두께를 포함해서 박스 크기를 계산

  • 모든 요소에 box-sizing: border-box를 적용하면, 모든 박스에서 여백과 테두리를 포함한 크기로 계산한다.
  • 일반적으로 box-sizing은 HTML 문서 전체에 적용한다.
  • box-sizing을 일부 요소에만 적용하는 경우, 혼란을 가중시킬 수 있다.
  • content-box는 박스의 크기를 측정하는 기본값. 그러나 대부분의 레이아웃 디자인에서 여백과 테두리를 포함하는 박스 크기 계산법인 border-box를 권장한다.
* {
  box-sizing: border-box;
}

우와! 이렇게나 다양하다니... 신기하다! 아! 그럼 마지막으로 셀렉터를 한 번 알아볼까?

기본 셀렉터

/* 전체 셀렉터 */
* { }

/* 태그 셀렉터 -> 복수 선택 가능*/
h1 { }
div { }

section, h1 { }

/* ID 셀렉터 */
#only { }

/* class 셀렉터 */
.widget { }
.center { }

/* attribute 셀렉터 */
a[href] { } /*태그[속성명] 속성명이 있는 항목*/
p[id="only"] { } /*태그 [속성명="속성값"] 속성명에 속성값과 일치하는 항목*/
p[class~="out"] { } /*태그[속성명~="속성값"] 속성값에 공백이 있는 경우 그 중 하나라도 일치하는 항목 or 공백이 없으면 정확히 일치하는 속성값이 있는 항목*/
p[class|="out"] { } /* 태그[속성명|="속성값"] 속성값에 하이픈(-)이 있는 경우 속성값으로 시작하는 항목 or 하이픈(-)이 없으면 정확히 일치하는 값이 있는 항목 */
section[id^="sect"] { } /* 태그[속성명^="속성값"]  속성값으로 시작하는 항목 */
div[class$="2"] { } /*태그[속성명$="속성값"] 속성값으로 끝나는 항목*/
div[class*="w"] { } /* 태그[속성명*="속성값"] 속성값을 포함하는 항목*/

자식 / 후손 / 형제 셀렉터

/* 전체 셀렉터 */
* { }

/* 태그 셀렉터 -> 복수 선택 가능*/
h1 { }
div { }

section, h1 { }

/* ID 셀렉터 */
#only { }

/* class 셀렉터 */
.widget { }
.center { }

/* attribute 셀렉터 */
a[href] { } /*태그[속성명] 속성명이 있는 항목*/
p[id="only"] { } /*태그 [속성명="속성값"] 속성명에 속성값과 일치하는 항목*/
p[class~="out"] { } /*태그[속성명~="속성값"] 속성값에 공백이 있는 경우 그 중 하나라도 일치하는 항목 or 공백이 없으면 정확히 일치하는 속성값이 있는 항목*/
p[class|="out"] { } /* 태그[속성명|="속성값"] 속성값에 하이픈(-)이 있는 경우 속성값으로 시작하는 항목 or 하이픈(-)이 없으면 정확히 일치하는 값이 있는 항목 */
section[id^="sect"] { } /* 태그[속성명^="속성값"]  속성값으로 시작하는 항목 */
div[class$="2"] { } /*태그[속성명$="속성값"] 속성값으로 끝나는 항목*/
div[class*="w"] { } /* 태그[속성명*="속성값"] 속성값을 포함하는 항목*/

자식 셀렉터

  • 첫 번째로 입력한 요소의 바로 아래 자식인 요소를 선택한다.
  • 아래 예시의 경우 <header>요소 바로 아래에 있는 두 개의 <p>요소는 선택되지만, <span>``header p {}``header p {}요소의 자식인 <p> 요소는 선택되지 않는다.
header > p { }
<header>
	<p> <!-- 선택 -->
		<span>
			<p></p>
		</span>
	</p>
	<p> <!-- 선택 -->
		<span>
			<p></p>
		</span>
	</p>
</header>

후손 셀렉터

  • 첫 번째로 입력한 요소의 후손을 선택한다.
  • 아래 예시의 경우 <header>요소의 자식인 <p>요소 뿐 아니라, <header>요소의 자식인 <p> 요소까지 모두 선택한다.
header p {}
<header>
	<p><!-- 선택 -->
		<span>
			<p><!-- !!선택!! -->
			</p>
		</span>
	</p>
	<p><!-- 선택 -->
		<span>
			<p><!-- !!선택!! -->
			</p>
		</span>
	</p>
</header>

형제 셀렉터

  • 같은 부모 요소를 공유하면서, 첫 번째 입력한 요소 뒤에 오는 두 번째 입력한 요소를 모두 선택한다.
  • 아래 예시의 경우 <section>요소 뒤에 있는 세 개의 <p>``section ~ p { }요소를 모두 선택한다.
section ~ p { }
<header>
	<section></section>
	<p></p> <!-- 선택 -->
	<p></p> <!-- 선택 -->
	<p></p> <!-- 선택 -->
</header>

인접 형제 셀렉터

  • 같은 부모 요소를 공유하면서, 첫 번째 입력한 요소 바로 뒤에 오는 두 번째 입력한 요소를 선택한다
  • 예시의 경우 <section>요소 뒤에 있는 세 개의 <p>요소 중 첫 번째 <p>요소를 선택한다.
section + p { }
<header>
	<section></section>
	<p></p> <!-- 선택 -->
	<p></p>
	<p></p>
</header>

기타 셀렉터

가상 클래스 셀렉터

가상 클래스는 요소의 상태 정보에 기반해 요소를 선택한다

a:link { } /*사용자가 방문하지 않은 <a>요소를 선택합니다.*/
a:visited { } /*사용자가 방문한 <a>요소를 선택합니다. */
a:hover { } /* 마우스를 요소 위에 올렸을 때 선택합니다. */
a:active { } /* 활성화 된(클릭된) 상태일 때 선택합니다. */
a:focus { } /* 포커스가 들어와 있을 때 선택합니다. */

UI 요소 상태 셀렉터

input:checked + span { } /*체크 상태일 때 선택합니다. */
input:enabled + span { } /*사용 가능한 상태일 때 선택합니다. */
input:disabled + span { } /*사용 불가능한 상태일 때 선택합니다. */

구조 가상 클래스 셀렉터

p:first-child { }
ul > li:last-child { }
ul > li:nth-child(2n) { }
section > p:nth-child(2n+1) { }
ul > li:first-child { }
li:last-child { }
div > div:nth-child(4) { }
div:nth-last-child(2) { }
section > p:nth-last-child(2n + 1) { }
p:first-of-type { }
div:last-of-type { }
ul:nth-of-type(2) { }
p:nth-last-of-type(1) { }

부정 셀렉터

input:not([type="password"]) { }
div:not(:nth-of-type(2)) { }

정합성 확인 셀렉터

input[type="text"]:valid { }
input[type="text"]:invalid { }
profile
개발 공부하는 코린이!

0개의 댓글