사용자 인터페이스(UI; user interface)
- 웹프론트엔드 개발자는 웹 개발 기술을 기반으로 사용자와 소통할 수 있는 웹페이지 제작을 담당한다.
⇒ 애플리케이션과 소통에 필요한 UI 제작은 프론트엔드 개발자의 기본 소양!
좋은 사용자경험(UX;user experience)은 직관적이고 쉬운 UI에서 나온다.
UX디자인을 위한 로고/이미지는 검색을 통해 무료로 사용가능한 아이콘을 찾을 수 있다.
(검색어 : `free app icon`)
프론트엔드 개발가가 갖춰야할 역량
- (필수)컴포넌트 기능별로 묶어서 제작
- (필수)화면의 구성이나 배치(레이아웃 디자인)
- (필수)굵은 글씨와 같은 타이포그래피와 색상을 적용하는 일 등
- (추가)정렬이나 배색에 대한 감각
- (추가)UX에 대해 고민해보고, UX가 잘 적용된 웹이나 앱을 분석해 본 경험
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Modern CSS</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<header>This is the header.</header>
<div class="container">
<nav>
<h4>This is the navigation section.</h4>
<ul>
<li>Home</li>
<li>Mac</li>
<li>iPhone</li>
<li>iPad</li>
</ul>
</nav>
<main>
<h1>This is the main content.</h1>
<p>...</p>
</main>
<aside>
<h4>This is an aside section.</h4>
<p>...</p>
</aside>
</div>
<footer>
<ul>
<li>개인정보 처리방침</li>
<li>이용 약관</li>
<li>법적 고지</li>
</ul>
</footer>
</body>
</html>![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7ca28f69-c8cb-477c-9c99-83063f442317/Untitled.png)
body {
margin: 0;
padding: 0;
background: #fff;
color: #4a4a4a;
}
header, footer {
font-size: large;
text-align: center;
padding: 0.3em 0;
background-color: #4a4a4a;
color: #f9f9f9;
}
nav {
background: #eee;
}
main {
background: #f9f9f9;
}
aside {
background: #eee;
}
❓속성 Question셀렉터(Selector) : 요소 이름, id, class
- 셀렉터로 특정 요소 선택 → 중괄호 안에 이 요소에 적용할 내용(속성)을 작성
속성(property) : 요소에 적용할 내용으로 색상, 글자 크기 등
- 속성과 값의 끝에는 세미콜론(;)을 붙여 속성을 구분
가운데 정렬을 위한 속성 :
text-align: center ;
글자 색 바꾸는 속성 :
color : #f9f9f9;
배경색을 바꾸는 속성 :
background-color: #eee ;
background : #eee ;
**background
속성과background-color
속성 차이** :
- background-color : 오직 단일 색만 지정 가능
- background : 단축속성으로 → 색상, 이미지, 원점, 크기, 반복 등 여러 배경 스타일을 한 번에 지정 가능
상대단위인
em
과rem
의 차이 :
- 공통점 : 둘 다 CSS의
font-size
속성 값에 비례해서 결정되는 상대단위- em : 해당 단위가 사용되고 있는 요소의
font-size
속성 값이 기준- rem : r(root), 즉 최상위 요소의
font-size
속성 값이 기준 → 최상위 요소 : HTML
- rem 사용이 권장된다 → em으로 스타일된 요소의 경우 재사용과 유지보수가 어려움.
html { font-size: 16px;}
div { font-size : 20px; whdth 10em; } /* 200px(200*10) */
div { font-size : 20px; whdth 10em; } /* 160px(16*10) */
//즉 em은 CSS에 부여된 값을, rem은 최상위요소인 HTML에 부여된 값을 상대단위로 잡는다.
상대단위와 절대 단위 :
- 절대 단위:
px
,pt
등- 상대 단위:
%
,em
,rem
,ch
,vw
,vh
등
HTML - CSS 파일 연결
<link>
태그 안에href
속성을 통해 파일을 연결
<link rel="stylesheet" href="index.css" />
rel
: 연결하고자 하는 파일의 역할이나 특징을 나타냄rel
속성에 stylesheet
를 추가한다.href
: 파일의 위치를 추가body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex: 1;
}
main {
flex: 1;
padding: 0 20px;
}
nav {
flex: 0 0 180px;
padding: 0 10px;
}
aside {
flex: 0 0 130px;
padding: 0 10px;
}
<link rel="stylesheet" href="layout.css" />
<nav style="background: #eee; color: blue">...</nav>. //인라인 스타일
❌ 인라인 스타일 : 같은 줄에 스타일 적용
❌ 내부 스타일 시트 : CSS 파일 내에 작성하는 내용을 별도 파일로 구분하지 않고,
⇒ 관심사 분리 측면에서 권장 X
⭕️ 외부스타일 시트 : 위의 내용
- id로 이름 붙여서 스타일링 적용하기
- (#)기호를 사용, 하나의 문서에 = 하나의 요소에만 사용
<!--h4요소를 red로 색상 변경하고 싶다면,-->
<!--1)본래 코드-->
<h4>This is the navigation section.</h4>
<!--2)h4요소에 id를 붙임-->
<h4 id="navigation-title">This is the navigation section.</h4>
<!--3)id로 요소를 선택해 스타일링-->
**#**navigation-title {color: red;}
- class로 스타일 분류하여 적용하기
- (.)기호를 사용, 동일한 기능을 하는 CSS 여러 요소에 적용
<!--네비게이션 섹션의 li요소에 밑줄 치고 싶다면-->
<!--1)본래 코드-->
section.</h4>
<ul>
<li>Home</li>
<li>Mac</li>
<li>iPhone</li>
<li>iPad</li>
</ul>
<!--2)요소에 class를 붙임-->
<ul>
<li class="menu-item">Home</li>
<li class="menu-item">Mac</li>
<li class="menu-item">iPhone</li>
<li class="menu-item">iPad</li>
</ul>
<!--3)class로 요소를 선택해 스타일링-->
**.**menu-item {text-decoration: underline;}
3. 여러 개의 class를 하나의 엘리먼트에 적용
<!--하나의 요소에 여러 class 적용하는 방법-->
<li class="menu-item selected">Home</li>
<!--여러 class에 하나의 요소를 적용 = 특정 class를 통해 요소를 스타일링-->
**.**selected {
font-weight: bold;
color: #009999; }
최종 정리
id | class |
---|---|
#으로 선택 | .으로 선택 |
한 문서에 단 하나의 요소에만 적용 | 동일한 값을 갖는 요소 많음 |
특정 요소에 이름을 붙이는 데 사용 | 스타일의 분류(classification)에 사용 |
색상
color
.box {
color: #155724; /* 글자 색상 */
background-color: #d4edda; /* 배경 색상 */
border-color: #c3e6cb; /* 테두리 색상 */
}
글꼴
font-family
.emphasize {
font-family: "SF Pro KR", "MalgunGothic", "Verdana";
}
크기
font-size
.title {
font-size: 24px;
}
기타 스타일링
- 굵기:
font-weight
- 밑줄, 가로줄:
text-decoration
- 자간:
letter-spacing
- 행간:
line-height
정렬
- 가로 정렬
text-align
- 유효값 :
left
,right
,center
,justify
(양쪽 정렬)- 세로 정렬 :
vertical-align
- But, 세로정렬은 부모요소의
display
속성이 반드시table-cell
이어야 한다.
💡 **절대단위와 상대단위**글꼴 사이즈를 정할 때
px
, pt
등%
, em
, rem
, ch
, vw
, vh
등→ px
(픽셀)을 사용. 하지만 픽셀은 크기가 고정된 절대 단위이기 때문에 사용자 접근성이 불리하다.
→ 또한 픽셀은 모바일 기기처럼 작은 화면이면서, 동시에 고해상도인 경우에도 적합하지 않다.
⇒ 픽셀은 인쇄와 같이 화면의 사이즈가 정해진 경우에 유리
→ 상대 단위인 rem
을 추천
→ 사용자가 설정한 기본 글꼴 크기를 따르므로, 접근성에 유리
화면 사이즈를 정할 때
- 반응형 웹(responsive web)에서 기준점을 만들 때
- 반응형 웹 : 디바이스의 너비(width)에 따라 유동적인 레이아웃이 적용되는 웹사이트 → 데스크탑, 스마트폰, 가로모드, 세로모드, 태블릿 등
- 디바이스 크기를 나누는 기준 : 보통
px
로 정한다.
ex. iPhone 12 Pro Max의 너비는 414px → 보통 450px 미만의 너비를 갖는 디바이스는 스마트폰 세로 모드
vw(viewport width)
, vh(viewport height)
를 사용
→ Viewport(웹사이트의 보이는 영역)인 화면을 가득 채우며 딱 떨어지게 스크롤되는 사이트 구현 가능
<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>
<link rel="stylesheet" href="box.css" />
h1 {
background: gray;
width: 60%;
}
p {
background: rgba(255,84,104,0.3);
width: 80%;
height: 200px;
}
span {
background: yellow;
width: 100px;
height: 100px;
}
❓ Question
줄바꿈 요소, 줄바꿈이 적용안되는 요소?
⇒ h1
p
: 줄바꿈이 적용되는 요소 → 한줄에 한 문장
⇒ span
: 줄바꿈이 적용되지 않는 요소 → 한줄에 여러 문장 작성 가능
파일 연결 어떻게?
⇒
줄 바꿈이 되는 박스(block) vs 옆으로 붙는 박스(inline) vs 두 가지 박스의 종류가 섞인(inline-block)
종류 | 줄바꿈 여부 | 기본 너비(Width) | width, height 사용 가능 여부 | 대표적 요소 | 특징 |
---|---|---|---|---|---|
block | 줄바꿈 가능 | 100% | 가능 | div p h1 | |
inline | 불가능 | 글자가 차지하는 만큼 (크기 지정 불가능) | 불가능 | span | width, height 속성이 적용❌ → 따라서 display: inline-block; 를 부여하면 적용 가능 |
inline-block (blcok + inline) | 불가능 | 글자가 차지하는 만큼 (크기 지정 불가능) | 가능 |
박스를 구성하는 요소
- CSS 박스모델
[border : 테두리](https://www.notion.so/2022-10-27-6-CSS-9c6dbeb775e44bd3bfdfc127d649d67c)
[margin : 바깥여백](https://www.notion.so/2022-10-27-6-CSS-9c6dbeb775e44bd3bfdfc127d649d67c)
[padding : 안쪽여백](https://www.notion.so/2022-10-27-6-CSS-9c6dbeb775e44bd3bfdfc127d649d67c)
border : 테두리
<!--p요소에 1px의 빨간 실선을 추가-->
p { border: 1px solid red;}
border-width
: 테두리 두께
border-style
: 테두리 스타일 (테두리 점선, 실선 등)
border-color
: 테두리 색상※ border-style mdn
margin : 바깥여백
※padding에도 동일하게 적용
1) 값을 4개 넣을 경우
⇒ top, right, bottom, left
<!--p요소 상하좌우에 여백 추가-->
p {margin: 10px 20px 30px 40px;}
1) 값을 2개 넣을 경우
⇒ 첫번째 값 :top/bottom
⇒ 두번째 값 :left/right
p { margin: 10px 20px;}
3) 값을 하나만 넣을 경우
⇒ 모든 방향
p { margin: 10px;}
4) 특정 값 부여도 가능
p {
margin-top: 10px;
margin-right: 20px;
margin-bottom: 30px;
margin-left: 40px; }
5) 음수 값도 가능
⇒ 다른 엘리먼트와의 간격 줄어듬
⇒ 다른 엘리먼트와 겹치게 할 수도 있다.
p {
margin-top: -2rem;
}
padding : 안쪽여백
p {
padding: 10px 20px 30px 40px;
border: 1px solid red;
background-color: lightyellow;
}
박스 < 컨텐츠 길이라면?
⇒ overflow
속성의 auto
값
: 박스크기보다 콘텐츠 크기가 더 커서 넘치는 경우 → overflow
속성의 auto
를 이용해 스크롤을 생성
p {
height: 40px;
overflow: auto;
}
overflow
속성의 hidden
값overflow-x
속성과 overflow-y
속성을 이용하면 두 방향을 모두 지정할 수 있다.박스 크기 측정 기준
❓여백과 테두리 두께를 포함해 박스크기를 계산할 순 없을까 ?
❗️ box-sizing
속성을 추가하고, border-box
라는 값을 추가하면 된다 !
* {
box-sizing: border-box;
}
⇒ 그럼 모든 박스에서 여백과 테두리를 포함한 크기로 계산된다!
box-sizing
은 HTML 문서 전체에 적용(일부 요소만 적용 → 혼란을 가중시킬 수 있다)[ 셀렉터의 구조 ]
전체 셀렉터 :
*
로 문서의 모든 요소를 선택* { }
태그 셀렉터 :
태그이름
같은 태그명을 가진 모든 요소를 선택하며, 복수로도 선택 가능하다.h1 { } div { } section, h1 { } /*복수선택도 가능 */
ID 셀렉터 :
#id
로 입력하여 선택#only { }
**class 셀렉터 :**
.class
로 입력하며 같은 class를 가진 모든 요소를 선택.widget { } .center { }
태그, id, class 복합셀렉터 :
태그#id이름
태그.class이름
#id이름.class이름
- 요소를 구체적으로 언급해야할 때 사용, 띄여쓰기가 없는 것에 주의
/* 복합 셀렉터는 띄여쓰기가 없다 -> id가 container면서 class가 mx-auto인 엘리먼트 */ #container.mx-auto {} /* 띄여쓰기가 있는 경우 -> id가 container인 엘리먼트의 후손 중 class가 mx-auto인 엘리먼트 */ #container .mx-auto {}
**attribute 셀렉터 :** 같은 속성을 가진 요소를 선택(모두 암기할 필요는 없다)
a[href] { } p[id="only"] { } p[class~="out"] { } p[class|="out"] { } section[id^="sect"] { } div[class$="2"] { } div[class*="w"] { }
자식셀렉터 :
header > p { }
첫번째로 입력한 요소의 바로 아래 자식인 요소를 선택
❗️ 할아버지(head)의 자식들(p)만 선택된다.
<header> <p> <!-- 선택 --> <span> <p></p> </span> </p> <p> <!-- 선택 --> <span> <p></p> </span> </p> </header>
후손셀렉터 :
header p {}
첫번째로 입력한 요소의 후손까지 선택
❗️할아버지(head)의 자식들(p)과 손녀,손자들(span 아래 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 { }
- 같은 부모를 공유 && 첫번째 요소 바로 뒤에 오는 두번째 입력한 요소를 선택
❗️엄마(section)의 자식인 나와 동생 중 장녀인 나(p)만 선택
<header> <section></section> <p></p> <!-- 선택 --> <p></p> <p></p> </header>
가상 클래스 셀렉터 :
a
. 요소의 상태 정보에 기반해 요소를 선택a:link { } /*사용자가 방문하지 않은 <a>요소를 선택합니다.*/ a:visited { } /*사용자가 방문한 <a>요소를 선택합니다. */ a:hover { } /* 마우스를 요소 위에 올렸을 때 선택합니다. */ a:active { } /* 활성화 된(클릭된) 상태일 때 선택합니다. */ a:focus { } /* 포커스가 들어와 있을 때 선택합니다. */
UI 요소 상태 셀렉터 :
+span
input:checked + span { } /*체크 상태일 때 선택합니다. */ input:enabled + span { } /*사용 가능한 상태일 때 선택합니다. */ input:disabled + span { } /*사용 불가능한 상태일 때 선택합니다. */
구조 가상 클래스 셀렉터 :
※ 요소 = 엘리먼트
:root /* 문서 최상위의 요소 */ :nth-child(n) /* 상위 요소의 n번째 자식 요소 */ :nth-last-child(n) /* 상위 요소의 역순으로 n번째 자식 요소 */ :nth-of-type(n) /* 동일한 타입의 형제 요소 중 n번째 요소(not 자식) */ :nth-last-of-type(n) /* 동일한 타입의 형제 요소 중 역순으로 n번째 요소 */ :first-child /* 첫 번째 자식 요소 */ :last-child /* 마지막 자식 요소 */ :first-of-type(n) /* 상위 요소의 첫 번째 자식의 타입이 매치될 때 선택됨 */ :last-of-type(n) /* 상위 요소의 마지막 자식의 타입이 매치될 떄 선택됨 */ :only-child /* 상위 요소에 대해 유일한 자식 요소일 때 선택됨 */ :only-of-type /* 상위 요소에 대해 유일한 자식 요소이며 타입이 매치될 때 선택됨 */ :empty /* 텍스트를 포함하여 아무런 자식 요소를 가지고 있지 않을 떄 선택됨 */ :nth-last-child(2n + 1) /* 상위 요소의 자식 중 홀수번째 자식 요소 */ :nth-child(4) /* 상위요소의 4번째 자식 요소 */ P:fist-of-type /* 상위요소의 형제 요소 중 첫번째 p요소 선택 (first-chile랑 다르게 첫번째 자식이 아닌, 처음 등장하는 p를 선택 */
부정셀렉터 :
not
input:not([type="password"]) { } div:not(:nth-of-type(2)) { }
정합성 확인 셀렉터 :
:valid
:invalid
input[type="text"]:valid { } input[type="text"]:invalid { }
실시간세션 꿀팁
html 만들기 : ! + tab
div 만들기 : div + tab
div 여러개 만들기 : div*10 + tab
div에 id 만들기 : div#
div에 class 만들기 : div.
commend + d :
commend + shift + l : 똑같은 요소 모두 선택
option + alt : 커서를 여러개 둘 수 있음
option + 방향키 : 코드 옮기기