Daily Front_Minhhk

[CSS ] css(Cascading Style Sheets), UI,UX,Selector 본문

Code개발일지

[CSS ] css(Cascading Style Sheets), UI,UX,Selector

Minhhk 2022. 10. 27. 15:00

CSS (Cascading Style Sheets)

CSS는 웹 페이지 스타일 및 레이아웃을 정의하는 스타일시트 언어입니다. 지금까지 학습한 HTML로 웹 페이지의 구조를 잘 세우고 나서, 더 나은 사용자 경험(UX, user experience)을 제공하기 위해 CSS로 UI 및 레이아웃을 적절히 구성하면 멋진 웹 페이지를 완성할 수 있습니다. CSS가 개발자인 여러분에게 어떤 의미가 있을까요? 미래의 프론트앤드 개발자로써 앞으로 CSS에 대해 가져야 할 마음가짐을 공유하고자 합니다.

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

사용자 인터페이스(UI; user interface)에 대해서 설명하기 전, 인터페이스(interface)에 대해서 알아보겠습니다. 쉽게 설명하자면 인터페이스는 컴퓨터와 교류하기 위한 연결고리입니다. 버튼도 없고, 마우스도 없던 시대의 개발자는 자신이 만든 애플리케이션과 소통하기 위해서 CLI를 사용했습니다. 키보드로 작성한 비밀 암호같은 코드를 적어서 엔터를 눌러야만 애플리케이션을 작동시킬 수 있었습니다.

사용자 경험(UX; user experience)은 직관적이고 쉬운 UI에서 나옵니다.

이번에는 UX를 고려해 보겠습니다. 복잡한 내용을 단순하게 구분 짓고, 페이지를 나누어 사용자가 한 페이지에서 볼 수 있는 내용을 제한했습니다. 화면크기는 같지만, 사용자가 하나의 내용에 집중할 수 있도록 UX를 고려하여 리디자인 했습니다.

CSS 따라하기

body { // 선언 블록
셀렉터
	color : red;    <- 선언

  font-size : 30px; // ; <- 속성 구분자
      속성명    속성값
}
<link rel="stylesheet" href="index.css" />
<link rel="stylesheet" href="layout.css" />

css파일을 자바스크립트와 연동시킬때 헤더부분에 위 코드를 작성해준다.

id와 class의 차이점을 반드시 기억하세요.

class로 묶기

여려요소를 묶을 때는 class ⇒ <li class=”menu-item”> 이렇게 묶고 .menuitem { } 로 적용


id로 묶기

가장 포괄적인 하나를 묶고 싶을 땐 id 선택자를 써서 묶는다!

⇒ <h4 id=navigation-title> </h4> 로 묶고 #navigation-title { } 로 적용

⇒ 한 문서에 단 하나의 요소에만 적용!

여러개의 class로 묶기 → 띄어쓰기!

여러개의 클래스를 묶을때는

<li class="menu-item **selected**">Home</li> 이렇게 띄어쓰기로 쓰고 .selected { } 로 적용하면 된다!

당연히 .menu-item도 가능하다!

색상 적용

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

글꼴말고도 다양하게 적용 가능!

글꼴 적용

.emphasize {
  font-family: "SF Pro KR", "MalgunGothic", "Verdana";
}

디바이스에 따라 지원하지 않는 글꼴인 경우 fallback 글꼴 입력된 순서로대로 추가!

글자의 크기 적용

.title {
  font-size: 24px;
}

font-size 로 적용시킨다!

이때 단위가 중요하다!

  • 절대단위 : px, pt 등
  • 상대단위 : %, em ,rem, ch, vw, vh 등

⇒ 일반적인 경우 rem 추천! px는 사용자 접근성이 불리함.

⇒ 하지만 px는 반응형 웹을 만들 때 쓰임!

⇒ vw,vh는 화면 너비나 높이에 따른 상대적인 크기가 중요한 경우 쓰임!

그외

  • 굵기: font-weight
  • 밑줄, 가로줄: text-decoration =underline 이런식
  • 자간: letter-spacing
  • 행간: line-height

mdn에서 사용법 쳐보자!

정렬

가로로 정렬할 경우 text-align 유효한 값으로는

, left , right , center , justify(양쪽 정렬)

글꼴 크기, 화면 크기 등 크기를 다룰 때는 크기의 단위가 무엇보다 중요합니다. 크기의 단위는 절대 단위와 상대 단위, 두 가지로 구분할 수 있습니다.

  • 절대 단위: px, pt 등
  • 상대 단위: %, em, rem, ch, vw, vh 등

글꼴 사이즈를 정할 때 >> rem 추천

  1. 기기나 브라우저 사이즈 등의 환경에 영향을 받지 않는 절대적인 크기로 정하는 경우 px(픽셀)을 사용합니다. 픽셀은 크기가 고정된 절대 단위이기 때문에 사용자 접근성이 불리합니다. 글꼴의 크기를 픽셀로 설정하면, 작은 글씨를 보기 힘든 사용자가 브라우저의 기본 글꼴 크기를 더 크게 설정하더라도 글꼴의 크기는 항상 설정된 픽셀로 고정됩니다. 개발자가 제목(heading)을 강조하기 위해 픽셀을 이용해 글꼴의 크기를 지정했으나 사용자의 환경에 따라 일반 텍스트보다 작게 보이는 결과를 초래할 수 있습니다. 그리고 픽셀은 모바일 기기처럼 작은 화면이면서, 동시에 고해상도인 경우에도 적합하지 않습니다. 기본적으로 고해상도에서는 1px이 모니터의 한 점보다 크게 업스케일(upscale) 되기 때문에, 뚜렷하지 못한 형태로 출력되는 경우도 있습니다. 픽셀은 인쇄와 같이 화면의 사이즈가 정해진 경우에 유리합니다.
  2. 일반적인 경우 상대 단위인 rem을 추천합니다. root의 글자 크기, 즉 브라우저의 기본 글자 크기가 1rem이며, 두 배로 크게 하고 싶다면 2rem, 작게 하려면 0.8rem 등으로 조절해서 사용할 수 있습니다. 이는 사용자가 설정한 기본 글꼴 크기를 따르므로, 접근성에 유리합니다. (em은 부모 엘리먼트에 따라 상대적으로 크기가 변경되므로 계산이 어렵습니다. 이에 비해 rem은 root의 글자 크기에 따라서만 상대적으로 변합니다.)

박스 모델 (boxmedol.css, boxmodel.html 참조)

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="boxmodel.css" />
</head>
<body>
<h1>Basic document flow</h1>
<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
<p>By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>
<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not</p>
</body>
</html>
h1 {
    background: red;
    width: 60%;
  }
  
  p {
    background: rgba(255,84,104,0.3);
    width: 80%;
    height: 200px;
  }
  
  span {
    background: yellow;
    display:inline-block;   // display를 사용해서 incline-block지정해야 변한다!
    width: 100px;
    height: 100px;
  }
  • 줄바꿈이 되는 태그(block) : <h1>, <p>, <div>
  • 줄바꿈이 되지 않는 태그(inline) : <span>
  • ⇒ span은 inline이라서 width, height 사용 불가능 , inline-block으로 보이게 display를 써줘야함!
  • display: inline-block;

박스 구성 요소

border ( 테두리 )

p {
  border: 1px solid red;
}

//각각의 값은 width , style, color

테두리를 둥글게 >> border-radius : 30px // 25%

그림자 >> box-shadow: 10px 5px 5px red;

box-shadow: none | x-position y-position blur spread color | inset | initial | inherit
  • none : 그림자 효과를 없앱니다.
  • x-position : 가로 위치입니다. 양수면 오른쪽에, 음수면 왼쪽에 그림자가 만들어집니다. (필수)
  • y-position : 세로 위치입니다. 양수면 아래쪽에, 음수면 위쪽에 그림자가 만들어집니다. (필수)
  • blur : 그림자를 흐릿하게 만듭니다. 값이 클 수록 더욱 흐려집니다.
  • spread : 양수면 그림자를 확장하고, 음수면 축소합니다.
  • color : 그림자 색을 정합니다.
  • inset : 그림자를 요소의 안쪽에 만듭니다.
  • initial : 기본값으로 설정합니다.
  • inherit : 부모 요소의 속성값을 상속받습니다.

margin (바깥 여백)

p {
  margin: 10px 20px 30px 40px;
}
// 각각의 값은 top , right, bottom , left 
  • margin: 20px >> 모든 방향
  • margin-top , margin-right 이렇게 하나하나 적용
p {
  margin-top: 10px;
  margin-right: 20px;
  margin-bottom: 30px;
  margin-left: 40px;
}
  • padding 에도 똑같은 규칙이 적용됨
  • 음수를 적으면 겹치게도 할 수 있음!

padding(안쪽 여백)

p {
  padding: 10px 20px 30px 40px;
}

박스 내부의 여백을 지정! 값은 margin과 동일!

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

p {
  height: 40px;
  overflow: auto;
}

박스크기를 작게 줄이면 가끔씩 내용물이 너무 길면 밖으로 나가는 경우가 있다

이때 overflow: auto; 를 입력해주면 스크롤 생성

// ex) 이미지의 맨 아래 칸에 스크롤이 생성된걸 볼 수 있다

넘치는 내용을 보여주고 싶지 않으면 overflow:hidden;

x축 방향 y축방향 스크롤 지정 하고 싶으면 overflow-x , overflow-y 사용

박스 크기 측정 기준

* {
  box-sizing: border-box;
}

이렇게 모든 요소에 box-sizing: border-box 를 적용하면, 모든 박스에서 여백과 테두리를 포함한 크기로 계산됩니다.

일반적으로 box-sizing 은 HTML 문서 전체에 적용합니다. box-sizing 을 일부 요소에만 적용하는 경우, 혼란을 가중시킬 수 있습니다.

앞으로 레이아웃과 관련된 이야기를 할 때는 border-box 계산법을 기준으로 이야기합니다.

 

전체 셀렉터

전체 셀렉터는 문서의 모든 요소를 선택합니다.

* { }

태그 셀렉터

태그 셀렉터는 같은 태그명을 가진 모든 요소를 선택합니다. 복수로도 선택할 수 있습니다.

h1 { }
div { }

section, h1 { }

ID 셀렉터

ID 셀렉터는 #id로 입력하여 선택합니다.

#only { }

class 셀렉터

class 셀렉터는 .class로 입력하여 선택합니다. 같은 class를 가진 모든 요소를 선택합니다.

.widget { }
.center { }

attribute 셀렉터

attribute 셀렉터는 같은 속성을 가진 요소를 선택합니다. (모두 암기하실 필요는 없습니다.)

a[href] { }
p[id="only"] { }
p[class~="out"] { }
p[class|="out"] { }
section[id^="sect"] { }
div[class$="2"] { }
div[class*="w"] { }

자식 / 후손 / 형제 셀렉터

자식 셀렉터

자식 셀렉터는 첫 번째로 입력한 요소의 바로 아래 자식인 요소를 선택합니다. 아래 예시의 경우 <header> 요소 바로 아래에 있는 두 개의 <p> 요소는 선택되지만, <span> 요소의 자식인 <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 { }
<header>
<section>
</section>
	<p></p> <!-- 선택 -->
	<p></p> <!-- 선택 -->
	<p></p> <!-- 선택 -->
</header>

인접 형제 셀렉터

인접 형제 셀렉터는 같은 부모 요소를 공유하면서, 첫 번째 입력한 요소 바로 뒤에 오는 두 번째 입력한 요소를 선택합니다. 예시의 경우 <section> 요소 뒤에 있는 세 개의 <p> 요소 중 첫 번째 <p> 요소를 선택합니다.

section + p { }
<header>
	<section>
	  <p></p> <!-- 선택 -->
		<p></p>
	  <p></p>
	</section>
</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 { }

p[id='only'] {…}
p 엘리먼트 중에서, id가 only인 속성을 갖는 모든 엘리먼트를 선택합니다.

퀴즈

#label.center {…}

id가 label이면서 동시에 class가 center인 엘리먼트를 선택합니다.

section > p:nth-child(2n+1) {…}

section의 자식 엘리먼트 중에서, 홀수 번째 자식 엘리먼트가 p인 것을 선택합니다. 
// 짝수면 당연히 2n 이겠지?

p:first-of-type {…}

p 엘리먼트의 형제 엘리먼트 중 첫 번째 p 엘리먼트를 선택합니다. 
(first-child와는 다르게 첫 번째 자식 엘리먼트가 아닌, 처음 등장하는 p를 선택합니다)

p:not(#only) {…}

p 엘리먼트 중에서, id가 only인 엘리먼트를 제외하고 모두 선택합니다.