Chapter3. CSS Selector
이전 유닛에서 id와 class를 사용하여 HTML 태그에 CSS 속성을 적용할 수 있다는 것을 학습하였습니다. 이처럼 CSS 속성을 적용할 대상을 선택하는 방법을 CSS selector라고 합니다. 지금까지는 id와 class를 사용해 적용하는 방법을 주로 사용했지만, 이번 챕터에서는 보다 다양한 CSS selector를 학습합니다. 학습 후에는 CSS selector의 실제 사용 예시를 익히는 퀴즈를 풀어보겠습니다.
Chapter3-1. 다양한 CSS selector
- 개념학습: 다양한 CSS Selector에 대하여 학습합니다.
개념학습
앞서 학습한 선택자는 class 선택자(.)와 id 선택자(#)였습니다. 실제 환경에서는 선택자를 더욱 다양한 방법으로 사용할 수 있습니다.
기본 선택자
전체 선택자
전체 선택자는 문서의 모든 요소를 선택합니다.
* { }
태그 선택자
태그 선택자는 같은 태그명을 가진 모든 요소를 선택합니다. 복수로도 선택할 수 있습니다.
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> 요소 바로 아래에 있는 두 개의 <div> 요소는 선택되지만, <p> 요소의 자식인 <div> 요소는 선택되지 않습니다. (마찬가지로 후손 선택자와의 차이를 반드시 알고 있어야 합니다.)
header > div { }
예시)
<header>
<div> <!-- 선택 -->
<p>
<div></div>
</p>
</div>
<div> <!-- 선택 -->
<p>
<div></div>
</p>
</div>
</header>
후손 선택자
후손 선택자는 첫 번째로 입력한 요소의 후손을 선택합니다. 아래 예시의 경우 <header> 요소의 자식인 <div> 요소뿐 아니라, <p> 요소의 자식인 <div> 요소까지 모두 선택됩니다. (자식 선택자와의 차이점을 반드시 알고 있어야 합니다.)
header div {}
예시)
<header>
<div><!-- 선택 -->
<p>
<div><!-- !!선택!! -->
</div>
</p>
</div>
<div><!-- 선택 -->
<p>
<div><!-- !!선택!! -->
</div>
</p>
</div>
</header>
형제 선택자
형제 선택자는 같은 부모 요소를 공유하면서, 첫 번째 입력한 요소 뒤에 오는 두 번째 입력한 요소를 모두 선택합니다. 아래 예시의 경우 <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 { } /* 셀렉터는 부모 요소의 첫 번째 자식 요소가 <p>일 때 선택합니다. */
ul > li:last-child { } /* ul 요소의 마지막 자식인 li 요소를 선택합니다. */
<ul>
<li>첫 번째 항목</li>
<li>두 번째 항목</li>
<li>마지막 항목</li>
</ul>
ul > li:nth-child(2n) { } /* ul 요소의 짝수 번째 자식인 li 요소를 선택합니다. */
<ul>
<li>첫 번째 항목</li>
<li>두 번째 항목</li>
<li>세 번째 항목</li>
<li>네 번째 항목</li>
</ul>
section > p:nth-child(2n+1) { } /* section 요소의 홀수 번째 자식인 p 요소를 선택합니다. */
<section>
<p>첫 번째 단락</p>
<p>두 번째 단락</p>
<p>세 번째 단락</p>
<p>네 번째 단락</p>
</section>
ul > li:first-child { } /* ul 요소의 첫 번째 자식인 li 요소를 선택합니다.*/
<ul>
<li>첫 번째 항목</li>
<li>두 번째 항목</li>
<li>세 번째 항목</li>
</ul>
li:last-child { } /* 부모 요소의 마지막 자식인 li 요소를 선택합니다. */
<ul>
<li>첫 번째 항목</li>
<li>두 번째 항목</li>
<li>마지막 항목</li>
</ul>
div > div:nth-child(4) { } /* div 요소의 네 번째 자식인 div 요소를 선택합니다. */
<div>
<div>첫 번째 div</div>
<div>두 번째 div</div>
<div>세 번째 div</div>
<div>네 번째 div</div>
</div>
div:nth-last-child(2) { } /* 부모 요소의 뒤에서 두 번째 자식인 div 요소를 선택합니다. */
<div>
<div>첫 번째 div</div>
<div>두 번째 div</div>
<div>세 번째 div</div>
<div>네 번째 div</div>
</div>
section > p:nth-last-child(2n + 1) { } /* 부모 요소의 뒤에서 홀수 번째 자식인 p 요소를 선택합니다. */
p:first-of-type { } /* 형제 요소 중 첫 번째 <p> 요소를 선택합니다. */
<div>
<p>첫 번째 단락</p>
<span>텍스트</span>
<p>두 번째 단락</p>
</div>
div:last-of-type { } /* 형제 요소 중 마지막 <div> 요소를 선택합니다. */
<div>
<div>첫 번째 div</div>
<span>텍스트</span>
<div>마지막 div</div>
</div>
ul:nth-of-type(2) { } /* 형제 요소 중 두 번째 <ul> 요소를 선택합니다. */
<ul>
<li>첫 번째 목록</li>
</ul>
<ul>
<li>두 번째 목록</li>
</ul>
p:nth-last-of-type(1) { } /* 형제 요소 중 마지막 <p> 요소를 선택합니다. */
<div>
<p>첫 번째 단락</p>
<span>텍스트</span>
<p>마지막 단락</p>
</div>
부정 선택자
input:not([type="password"]) { } /* type 속성이 "password"가 아닌 모든 <input> 요소를 선택합니다. */
<form>
<input type="text" placeholder="Username">
<input type="password" placeholder="Password">
<input type="email" placeholder="Email">
<input type="submit" value="Submit">
</form>
div:not(:nth-of-type(2)) { } /* 형제 요소들 중 두 번째 div 요소를 제외한 모든 div 요소를 선택합니다.*/
<div>첫 번째 div</div>
<div>두 번째 div</div>
<div>세 번째 div</div>
<div>네 번째 div</div>
정합성 확인 선택자
input[type="text"]:valid { } /* 올바른 형식으로 입력된 텍스트 필드를 선택합니다. 즉, 유효한 값이 입력된 input 요소를 선택합니다.*/
<form>
<label for="username">Username (at least 3 characters):</label>
<input type="text" id="username" name="username" pattern=".{3,}" required>
<input type="submit" value="Submit">
</form>
input[type="text"]:invalid { } /* 올바르지 않은 형식으로 입력된 텍스트 필드를 선택합니다. 즉, 무효한 값이 입력된 input 요소를 선택합니다.*/
<form>
<label for="username">Username (at least 3 characters):</label>
<input type="text" id="username" name="username" pattern=".{3,}" required>
<input type="submit" value="Submit">
</form>
Chapter3-2. CSS selector 연습
- 퀴즈: 학습한 내용을 바탕으로 CSS Selector 연습 문제를 풉니다.
https://lucky-kor.github.io/css-selector/
[HTML/CSS] 활용
여러분은 지난 유닛들을 거쳐오며 HTML과 CSS에 대한 기본 지식을 쌓았습니다. 이번 유닛에서는 레이아웃에 대하여 본격적으로 학습합니다. 특히 웹 페이지의 레이아웃을 구성하기 위해 빼놓을 수 없는 Flexbox를 학습함으로써, 여러분이 구상한 레이아웃을 직접 구현할 수 있게 됩니다.
이미 충분히 경험하고 있겠지만, HTML과 CSS를 학습할 때는 다양한 속성을 적용해 보고 직접 눈으로 확인하는 것이 매우 중요합니다. 학습 중간중간에 결과를 여러분의 눈으로 확인할 수 있도록 구성되어 있으니, 꼭 확인하고 넘어가 주세요!
Before You Learn
- CSS selector
- CSS의 기본적인 선택자를 이해하고 있다.
- CSS의 기본적인 선택자 #와 .의 차이를 이해하고 있다.
- 박스 모델
- CSS 박스 모델에 대해 이해하고 있다.
- 절대 단위와 상대 단위: 절대 단위와 상대 단위를 구분할 수 있다.
- 박스 측정 기준(content-box, border-box) 두 가지의 차이를 이해하고 있다.
Chapter1. 레이아웃
우리가 잘 알고 있는 웹 사이트를 방문해 보면 각 요소의 위치가 웹 사이트의 목적에 맞게 배치된 것을 볼 수 있습니다. 그와 같이 각각의 요소를 목적에 맞게 배치하는 것을 레이아웃이라고 합니다. 웹 개발자에게 웹 사이트에 목적에 맞게 화면을 만드는 작업, 즉 레이아웃은 자바스크립트에 대해 배우는 만큼이나 중요합니다.
학습 목표
- 레이아웃을 위한 HTML을 만들 수 있다.
지난 유닛에서 HTML과 CSS를 통해 화면을 만드는 기초를 학습했습니다. 이번 유닛에서는 콘텐츠를 원하는 위치에 배치하는 것을 넘어 레이아웃이 무엇인지, 보다 구체적으로 학습합니다.
Chapter1-1. 와이어프레임
개념학습
와이어프레임(Wireframe)
웹 또는 애플리케이션을 개발할 때 레이아웃의 뼈대를 그리는 단계를 와이어프레임이라고 합니다. 와이어프레임은 말 그대로 "와이어로 설계된 모양"을 의미하며, 단순한 선이나, 도형으로 웹이나 앱의 인터페이스를 시각적으로 묘사한 것입니다. 와이어프레임은 아주 단순하게, 레이아웃과 제품의 구조를 보여주는 용도입니다. 전환 효과나, 애니메이션, 사용자 테스트 같은 스타일링 요소나 UX(사용자 경험, User Experience)를 판단하는 것이 아닙니다.
특히 이번에 우리가 그려볼 와이어프레임의 가장 큰 목적은, 화면의 영역을 구분하는 일입니다. 그래서 인터페이스를 그림으로 표현하는 와이어프레임이 아니라, 각 영역에서 사용할 주요 태그를 메모하는 형식으로 와이어프레임을 작성하세요.
예제를 하나 소개합니다. 다음은 특정 목적을 가진 프로그램의 와이어프레임입니다. 이 와이어프레임을 보고, 어떤 목적을 가진 프로그램인지 유추할 수 있나요? 그렇다고 답했다면, 이 와이어프레임은 그 목적을 성공적으로 달성했습니다. 다음 그림을 살펴보고, 이 와이어프레임이 나타내는 프로그램의 목적이 무엇인지 유추해 보세요.
[그림] 특정 목적을 가진 프로그램의 와이어프레임
목업(Mock-up)
대부분의 산업에서 목업은 실물 크기의 모형을 뜻합니다. 실물 제품이 없는 무형의 웹 또는 앱은 어떻게 목업을 만들까요? 웹 또는 앱을 제품이라고 할 때, 목업은 실제 제품이 작동하는 모습과 동일하게 HTML 문서를 작성합니다. 예를 들어, 트윗 작성자, 트윗 내용, 작성한 날짜 등을 HTML 문서 내에 하드코딩하는 방식입니다.
하드코딩이란?
만일 JavaScript에서 변수를 사용하지 않고, 구구단을 만든다고 가정하겠습니다. 변수를 사용하지 않고 구구단처럼 보이기 위해서는, 각 숫자의 단을 소스 코드에 모두 출력하는 방법뿐입니다.
// 하드코딩의 예
console.log('2 x 1 = 2')
console.log('2 x 2 = 4')
console.log('2 x 3 = 6')
console.log('2 x 4 = 8')
[코드] 하드코딩한 2단의 일부
우리가 역동적인 웹 애플리케이션을 만들기 위해서는, HTML 문서에 트윗 작성자, 내용을 변수로 관리하여 값을 동적으로 담아야 합니다.
// JavaScript 어딘가에는 tweet 내용이 담긴 객체가 존재합니다.
let tweet = { user: '김코딩', content: 'SNS는 인생의...' }
[코드] 변수를 이용한 데이터 관리
그러나 아직 우리는 <div> 요소 내에 변수의 값을 전달하는 방법을 배우지 않았습니다. 아직은 변수를 이용할 수 없기 때문에, HTML 문서에 아래와 같이 하나하나 입력해야 합니다. 이런 방식을 하드코딩이라고 합니다.
<!-- 실제로는 어떤 로직에 의해서 적절한 위치에 값이 들어가게 됩니다. -->
<div class="writer">김코딩</div><div class="content">SNS는 인생의...</div>
[코드] 하드코딩한 HTML 문서
와이어프레임과 목업을 작성하는 단계를 건너뛰고, JavaScript로 동작하는 애플리케이션을 만들고 싶을 수 있습니다. 그러나 와이어프레임과 목업을 작성하는 단계를 반드시 진행해 주세요. HTML 문서를 통해 화면을 다 그려보지 않으면, JavaScript를 적용한 완성본이 어떤 형태를 가질지 상상하기 어렵습니다. 마치 설계도 없이 건물을 짓는 것과 같습니다.
와이어프레임의 목적
*상단의 와이어프레임은 POS기(상품 주문 시스템)를 나타내고 있습니다. 메뉴와 카트, 그리고 총합계가 잘 나타나 있나요? 여러분들도 상세하게 와이어프레임을 작성해 보세요
퀴즈
Chapter1-2. 화면을 나누는 방법
개념학습
HTML 구성하기
대부분의 경우 콘텐츠의 흐름은 좌에서 우, 위에서 아래로 흐릅니다. CSS로 화면을 구분할 때는 수직 분할과 수평 분할을 차례대로 적용하여 콘텐츠의 흐름을 따라 작업을 진행합니다.
- [수직 분할] 화면을 수직으로 구분하여, 콘텐츠가 가로로 배치될 수 있도록 요소를 배치합니다.
- [수평 분할] 분할된 각각의 요소를 수평으로 구분하여, 내부 콘텐츠가 세로로 배치될 수 있도록 요소를 배치합니다.
- 수평으로 구분된 요소에 height 속성을 추가하면, 수평 분할을 보다 직관적으로 할 수 있습니다.
다음과 같이, VScode와 비슷한 레이아웃을 적용한다고 가정합니다.
[그림] 레이아웃을 적용하기 위해 VScode의 레이아웃을 참고합니다.
실제 VScode의 레이아웃을 분석해 큰 틀에서 추상화하면, 다음과 같이 영역을 나눌 수 있습니다.
[그림] VScode의 레이아웃을 추상화한 결과
CSS로 화면을 구분할 때는 수직 분할과 수평 분할을 차례로 적용합니다. HTML 문서를 통해 레이아웃을 작성하면, 다음과 같이 구성할 수 있습니다.
<div id="container">
<div class="col w10">
<div class="icon">아이콘 1</div>
<div class="icon">아이콘 2</div>
<div class="icon">아이콘 3</div>
</div>
<div class="col w20">
<div class="row h40">영역1</div>
<div class="row h40">영역2</div>
<div class="row h20">영역3</div>
</div>
<div class="col w70">
<div class="row h80">영역4</div>
<div class="row h20">영역5</div>
</div>
</div>
[코드] 레이아웃을 고려해 작성한 HTML 파일
- 참고: 클래스 이름으로 지정된 w10, w20, w70, 또는 h20, h40, h80을 CSS로 구현하면, 다음과 같습니다.
.w70 { width: 70%; }
.h40 { height: 40%; }
[코드] 클래스 이름에 맞는 CSS 구현
이렇게 클래스 이름과 구현을 1:1로 일치시켜 아주 작은 단위로 CSS를 작성 기법을 Atomic CSS 방법론이라고 합니다. 클래스 이름을 선언하는 방법에 대한 이야기는 CSS Architcture: Atomic CSS에서 확인할 수 있습니다. (지금 당장은 몰라도 됩니다!)
레이아웃 리셋
HTML 문서는 기본적인 스타일을 가지고 있습니다. 때때로 HTML 문서가 갖는 기본 스타일이, 레이아웃을 잡는 데 방해가 되기도 합니다. 어떤 사례가 있는지 찾아볼까요?
- 박스의 시작을 정확히 (0,0)의 위치에서 시작하고 싶은데, <body> 요소가 가진 기본 스타일에 약간의 여백이 있습니다.
- width, height 계산이 여백을 포함하지 않아 계산에 어려움이 있습니다. (이전 유닛을 통해 박스 크기 측정 기준(box-sizing)에 대해 학습한 내용입니다.)
- 브라우저(크롬, 사파리 등)마다 여백이나 글꼴과 같은 기본 스타일이 조금씩 다릅니다.
이러한 수요에 따라 초기화(리셋)를 위한 다양한 라이브러리(Normalize.css)가 등장했지만, 사실 굳이 라이브러리를 사용할 필요는 없으며, 위에 언급한 문제를 해결할 몇 줄의 코드를 적용시키면, 기본 스타일링을 제거하여 디자인한 대로 레이아웃을 구현할 수 있습니다.
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
[코드] 기본 스타일링을 제거하는 CSS 코드의 예시
퀴즈
Chapter2. Flexbox
Flexbox의 flex(flexible)는 "잘 구부러지는, 유연한"이라는 뜻입니다. Flexbox로 레이아웃을 구성한다는 것은, 박스를 유연하게 늘리거나 줄여 레이아웃을 잡는 방법입니다. 이번 챕터에서는 Flexbox 속성에는 무엇이 있는지, 어떻게 사용하는지 구체적으로 학습합니다.
학습 목표
- display: flex;를 자식 요소가 아닌 부모 요소에 적용해야 함을 이해한다.
- flex-direction을 이용하여 요소를 정렬할 방향을 결정할 수 있다.
- justify-content와 align-items를 이용하여 수평-수직 정렬을 결정할 수 있다.
- flex-grow를 이용하여 요소를 얼마나 늘릴 것인지 결정할 수 있다.
- flex-basis를 이용하여 요소의 기본 크기를 결정할 수 있다.
- VSCode의 레이아웃을 Flexbox를 이용하여 구현할 수 있다.
Chapter2-1. Flexbox 따라하기 - 1
Flexbox로 레이아웃 잡기
Flex(Flexible)는 "잘 구부러지는, 유연한"이라는 뜻입니다. Flexbox로 레이아웃을 구성한다는 것은, 박스를 유연하게 늘리거나 줄여 레이아웃을 잡는 방법입니다. 여러분은 학습하면서 display: flex라는 CSS 속성을 이미 본 적이 있습니다. 이 속성 역시 Flexbox 속성 중 하나입니다. 이번 챕터에서는 Flexbox 속성들에 대해서 구체적으로 학습합니다.
display: flex 분석하기
display: flex는 부모 박스 요소에 적용해, 자식 박스의 방향과 크기를 결정하는 레이아웃 구성 방법입니다. 이 속성이 어떤 역할을 하는지 눈으로 직접 확인해 봅시다.
우선 HTML로 3개의 <div> 요소를 자식으로 가진 <main> 요소를 작성해 보겠습니다.
<main>
<div>box1</div>
<div>box2</div>
<div>box3</div>
</main>
그리고 각 요소들이 눈에 잘 보이도록 CSS로 <main> 요소에는 빨간색 점선, <div> 요소들에는 초록색 실선으로 테두리를 설정해 주고, 전체적으로 margin과 padding 도 10픽셀씩 주겠습니다.
main {
border: 1px dotted red;
}
div {
border: 1px solid green;
}
* {
margin: 10px;
padding: 10px;
}
그럼 다음과 같은 화면이 나오는 것을 확인할 수 있습니다. 이처럼 <div> 요소들은 별다른 설정을 해주지 않으면 위쪽에서부터 세로로 정렬되며, 가로로 넓게 공간을 차지하는 것을 확인할 수 있습니다.
이번에는 이 상태에서 부모 요소인 <main> 요소에 display: flex 속성을 적용해 보겠습니다.
main {
display: flex;
border: 1px dotted red;
}
...
속성을 적용했더니 자식 요소인 <div> 요소들이 왼쪽부터 가로로 정렬된 것과 내용만큼의 공간을 차지하는 것을 확인할 수 있습니다.
이처럼 Flexbox 속성들을 활용하면 요소의 정렬, 요소가 차지하는 공간을 설정해 줄 수 있습니다. 그럼 Flexbox 속성들은 어떤 것이 있는지 알아봅시다.
부모 요소에 적용해야 하는 Flexbox 속성들
들어가기 전, Flexbox 속성을 사용할 때 유의해야 할 점이 있습니다. 바로 속성을 지정해 주는 위치입니다. Flexbox 속성 중에서는 부모 요소에 적용해야 하는 속성들, 자식 요소에 적용해야 하는 속성들이 있습니다. 적절한 위치에 속성을 지정해주지 않으면 요소들이 원하는 대로 정렬되지 않습니다. 우선은 부모 요소에 적용해야 하는 속성들부터 알아보도록 하겠습니다.
1. flex-direction : 정렬 축 정하기
flex-direction 속성은 부모 요소에 설정해 주는 속성으로, 자식 요소들을 정렬할 정렬 축을 정합니다. 아무 설정도 해주지 않으면 기본적으로 가로 정렬을 합니다.
main {
display: flex;
flex-direction : row;
}
/* 부모 요소인 main에 작성하여 자식 요소인 div들을 정렬할 축을 정합니다. */
주요 속성값은 다음과 같습니다. 눈으로 보고 각 속성값의 정렬 축 방향을 확인해 보세요.
2. flex-wrap : 줄 바꿈 설정하기
flex-wrap 속성은 하위 요소들의 크기가 상위 요소의 크기를 넘으면 자동 줄 바꿈을 할 것인지 정합니다. 설정해 주지 않으면 줄 바꿈을 하지 않습니다.
main {
display: flex;
flex-wrap : nowrap;
}
/* 부모 요소인 main에 작성하여 자식 요소인 div들의 줄 바꿈을 어떻게 할지 정합니다. */
주요 속성값은 다음과 같습니다. 눈으로 보고 각 속성값의 줄 바꿈 기준을 확인해 보세요.
3. justify-content : 축 수평 방향 정렬
justify-content 속성은 자식 요소들을 축의 수평 방향으로 어떻게 정렬할 것인지 정합니다. 요소들이 가로로 정렬되어 있다면 가로 방향으론 어떻게 정렬할 것인지, 세로로 정렬되어 있다면 세로 방향으론 어떻게 정렬할 것인지 정하는 속성입니다.
주요 속성값으로는 flex-start , flex-end, center, space-between, space-around 이 있습니다. 각 속성값의 특성이 잘 드러날 수 있도록 자식 요소의 크기를 동일하게 설정해 놓았습니다. 각 속성값이 축 방향에 따라 요소들을 어떻게 정렬시키는지 눈으로 확인해 보세요.
flex-direction : row 인 경우 ↔
flex-direction: column 인 경우 ↕️
4. align-items : 축 수직 방향 정렬
align-items 속성은 자식 요소들을 축의 수직 방향으로 어떻게 정렬할 것인지 정합니다. 요소들이 가로로 정렬되어 있다면 세로 방향으론 어떻게 정렬할 것인지, 세로로 정렬되어 있다면 가로 방향으론 어떻게 정렬할 것인지 정하는 속성입니다.
주요 속성값으로는 stretch , flex-start , flex-end , center , baseline 이 있습니다. 이번에는 각 속성값의 특징이 명확하게 드러날 수 있도록 자식 요소의 글씨 크기를 각각 다르게 설정해 놓았습니다. 각 속성값이 축 방향에 따라 요소들을 어떻게 정렬시키는지 눈으로 확인해 보세요.
flex-direction : row 인 경우 ↕️
flex-direction : column 인 경우 ↔
여기까지 Flexbox와 부모 요소에 적용해야 하는 Flexbox 속성들에 대해 알아보았습니다. 당장 모든 속성들과 사용법이 완벽하게 이해되지 않아도 괜찮습니다. 실습과 연습을 통해서 직접 여러 속성들을 다뤄보면 어떤 방식으로 정렬되는지 천천히 파악해 보세요. 직접 사용해 보는 것이 사용법을 익히는데 가장 좋습니다.
Chapter2-2. Flexbox 따라하기 - 2
자식 요소에 적용해야 하는 Flexbox 속성
이번에는 Flexbox 속성 중 자식 요소에 적용해야 하는 속성, flex에 대해서 알아봅시다. 앞서 Flexbox 속성들을 활용하면 요소의 정렬, 요소가 차지하는 공간을 설정해 줄 수 있다고 이야기했습니다. 부모 요소에 적용해야 하는 속성들이 자식 요소들의 정렬과 관련이 있었다면, 자식 요소에게 적용해야 하는 속성인 flex는 요소가 차지하는 공간과 관련이 있습니다.
flex 속성의 값
flex 속성에는 세 가지 값을 지정해 줄 수 있습니다. 각 값이 의미하는 것은 다음과 같습니다.
flex: <grow(팽창 지수)> <shrink(수축 지수)> <basis(기본 크기)>
grow(팽창 지수)는 요소의 크기가 늘어나야 할 때 얼마나 늘어날 것인지, shrink(수축 지수)는 요소의 크기가 줄어들어야 할 때 얼마나 줄어들 것인지, basis(기본 크기)는 늘어나고 줄어드는 것과 상관없이 요소의 기본 크기는 얼마인지를 의미합니다. 각 값이 어떻게 작용하는지는 잠시 후 살펴보겠습니다.
자식 요소에 flex 속성을 따로 설정해 주지 않으면 다음과 같은 기본값이 적용되며, 왼쪽에서부터 오른쪽으로 콘텐츠의 크기만큼 배치됩니다.
flex: 0 1 auto;
이 순서와 기본값은 반드시 기억해 주세요. flex: grow shrink basis, flex: 0 1 auto
꼭 flex 속성 안에 세 가지 값을 한 번에 설정해 줄 필요 없이, 다음과 같이 각 값을 따로 지정해 줄 수 있습니다.
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
1. grow : 자식 박스는 얼마나 늘어날 수 있을까요?
grow(팽창 지수)는 요소의 크기가 늘어나야 할 때 얼마나 늘어날 것인지를 의미한다고 했습니다. 어떤 의미인지 알아보기 위해서 챕터 2-1에서 사용했던 HTML에서 자식 <div> 요소들에 id를 추가해서 grow 값을 변경하며 화면 변화를 확인해 보겠습니다.
<main>
<div id="box1" class="box">box1</div>
<div id="box2" class="box">box2</div>
<div id="box3" class="box">box3</div>
</main>
flex 속성을 설정하기 전의 모습입니다. grow의 기본 값인 0은 빈 공간이 있어도 늘어나지 않음을 의미합니다. 따라서 빈 공간이 있음에도 박스들이 늘어나지 않습니다. 그럼 grow의 값을 변경하며 어떤 변화가 생기는지 확인해 봅시다.
우선 box1만 flex-grow : 1로 설정해 보겠습니다. flex-grow의 기본값은 0이므로 나머지 박스는 flex-grow : 0인 상태입니다.
이번에는 box2도 flex-grow : 1로 설정해 보겠습니다. box3만 flex-grow : 1인 상태입니다.
box3도 flex-grow : 1로 설정해 보겠습니다. 세 박스 모두 flex-grow : 1인 상태입니다.
어떤 느낌인지 감이 오시나요? grow(팽창 지수)는 정렬축 방향으로 빈 공간이 있을 때, 각 자식 요소들이 얼마나 늘어나서 남는 공간을 차지할 것인지 비율을 정하는 것이라고 생각하면 이해하기 쉽습니다.
즉, 첫 번째 예시에서 grow는 box1 : box2 : box3 = 1 : 0 : 0 이므로 box1이 모든 공간을 차지하고,
두 번째 예시에서 grow는 box1 : box2 : box3 = 1 : 1 : 0 이므로 box1과 box2가 1:1로 공간을 나눠 가지고,
세 번째 예시에서 grow는 box1 : box2 : box3 = 1 : 1 : 1 이므로 세 박스가 1:1:1로 공간을 나눠 가진 것입니다.
예시를 좀 더 살펴보겠습니다.
[예시 1] 팽창지수가 1 : 1 : 2 일 때
[예시 2] 팽창지수가 1 : 1 : 4 일 때
[예시 3] 팽창지수가 6 : 3 : 1 일 때
[예시 4] 팽창지수가 60 : 30 : 10 일 때
이처럼 팽창지수는 자식 요소의 grow값 / 자식 요소들의 grow값의 총합의 비율로 빈 공간을 가져갑니다.
[예시 3]의 box1은 box1의 팽창지수 6 / 팽창지수의 총합 6 + 3 + 1 = 3/5 만큼의 공간을 가져가고,
[예시 4]의 box1은 box1의 팽창지수 60 / 팽창지수의 총합 60 + 30 + 10 = 3/5 만큼의 공간을 가져갑니다.
팽창지수의 절대적 크기가 아닌 총합에서의 비율로 빈 공간을 차지하게 되는 것이죠.
2. shrink : 자식 박스는 얼마나 줄어들 수 있을까요?
shrink(수축 지수)는 grow와 반대로, 설정한 비율만큼 박스 크기가 작아집니다. 비율이 클수록 더 많이 줄어드는 것이죠. 그러나 flex-grow 속성과 flex-shrink 속성을 함께 사용하는 일은 추천하지 않습니다. 비율로 레이아웃을 지정할 경우 flex-grow 속성 또는 flex: <grow> 1 auto와 같이 grow 속성에 변화를 주는 방식을 권장합니다. flex-shrink 속성은 width나 이후 설명할 flex-basis속성에 따른 비율이므로 실제 크기를 예측하기가 어렵기 때문입니다. flex-grow 속성으로 비율을 변경하는 경우, flex-shrink 속성은 기본값인 1로 두어도 무방합니다.
3. basis : 이 박스의 기본 크기는 얼마일까요?
basis(기본 크기)는 자식 박스가 flex-grow나 flex-shrink에 의해 늘어나거나 줄어들기 전에 가지는 기본 크기입니다. flex-grow가 0일 때, basis 크기를 지정하면 그 크기는 유지됩니다.
grow는 0 : 1 : 1로 설정하고, box1에 flex-basis : 50px로 설정해 보겠습니다.
box1의 크기가 늘어나거나 줄어들지 않고 50px을 유지하는 것을 확인할 수 있습니다.
도전하기
이 챕터의 레이아웃: 화면을 나누는 방법에서 봤던 VS Code 레이아웃 클론을 직접 만들어 볼 수 있을까요? 이 챕터를 충분히 학습했다면, 여러분도 하실 수 있습니다. 스스로 도전해 보세요.
- Flexbox를 이용해 다음 레이아웃을 만들어보세요.
html 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="layout.css" />
</head>
<body>
<div id="container">
<div class="col w10">
<div class="icon">아이콘 1</div>
<div class="icon">아이콘 2</div>
<div class="icon">아이콘 3</div>
</div>
<div class="col w20">
<div class="row h40">영역1</div>
<div class="row h40">영역2</div>
<div class="row h20">영역3</div>
</div>
<div class="col w70">
<div class="row h80">영역4</div>
<div class="row h20">영역5</div>
</div>
</div>
</body>
</html>
css 코드
#container {
display: flex;
border: 2px solid red;
height: 70vh;
}
.col {
display: flex;
border: 2px solid blue;
flex-direction: column;
}
.w10 {
flex: 1;
}
.w20 {
flex: 2;
}
.w70 {
flex: 7;
}
.icon {
border: 1px dashed orange;
justify-content: flex-start;
}
.row {
border: 1px dashed skyblue;
justify-content: center;
}
.h20 {
flex: 2;
}
.h40 {
flex: 4;
}
.h80 {
flex: 8;
}
* {
margin: 10px;
padding: 11px;
}
과제 - 계산기 목업 만들기
[그림] Mac에서 제공하는 계산기
이번 과제에서는 Flexbox를 활용해서 계산기 목업을 만들어보겠습니다. 위 이미지의 계산기는 Mac에서 제공하는 기본 계산기입니다. 이 외에도 구글에서 이미지 검색을 통해 다양한 구성과 디자인의 계산기를 찾아볼 수 있습니다. 그중에서 마음에 드는 계산기를 하나 골라 따라 만들어보아도 좋고, 여러분만의 계산기 목업을 만들어보셔도 좋습니다.
html code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="rainbow">
<div class="circle red"></div>
<div class="circle orange"></div>
<div class="circle green"></div>
</div>
<div class="screen">0</div>
<div class="buttons">
<div class="button gray">AC</div>
<div class="button gray">+/-</div>
<div class="button gray">%</div>
<div class="button orange">/</div>
<div class="button">7</div>
<div class="button">8</div>
<div class="button">9</div>
<div class="button orange">*</div>
<div class="button">4</div>
<div class="button">5</div>
<div class="button">6</div>
<div class="button orange">-</div>
<div class="button">1</div>
<div class="button">2</div>
<div class="button">3</div>
<div class="button orange">+</div>
<div class="button">0</div>
<div class="button black"></div>
<div class="button">.</div>
<div class="button orange">=</div>
</div>
</div>
</body>
</html>
css code
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
font-size: 24px;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
width: 350px;
padding:30px;
border-radius: 17px;
background-color: black;
color: white;
border: 1px solid white;
box-shadow: 5px 17px 20px rgba(0, 0, 0, 0.3);
}
.rainbow {
margin-top: -20px;
}
.circle {
display: inline-flex;
flex-direction: row;
width: 10px;
height: 10px;
border-radius: 10px;
}
.screen {
height: 100px;
display: flex;
justify-content: flex-end;
align-items: flex-end;
font-size: 200%;
margin-bottom: 15px;
margin-right: 25px;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15px;
}
.button {
display: flex;
justify-content: center;
align-items: center;
background-color: darkgray;
width: 50px;
height: 50px;
border-radius: 50px;
}
.button:hover {
background-color: deeppink;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.gray {
background-color: gray;
}
.orange {
background-color: orange;
}
.black {
background-color: black;
}
학습 목표
- HTML과 CSS를 활용하여 만들고자 하는 웹 애플리케이션의 레이아웃을 구성할 수 있다.
- Flexbox속성을 이용하여 자식 요소를 정렬할 수 있다.
- 자식 요소에 flex 속성을 추가하여 부모 요소에서 각각의 자식 요소가 차지하는 비중을 조절할 수 있다.
과제 시작하기
Getting Started
코드 작성 환경 구성하기
첫 시작은 같이 해봅시다. 바탕 화면에 작업을 진행할 폴더를 하나 만든 다음 VScode로 해당 폴더를 열어줍니다. 그 후 폴더 안에 index.html, style.css 파일을 만드세요.
다음으로 html 기본 구조를 작성해 봅시다. 원래는 직접 작성해야 하지만, VScode에는 Emmet이라는 플러그인이 있어 쉽게 기본 구조를 작성할 수 있습니다. 빈 html 파일에 느낌표를 하나 입력 후 선택하면 됩니다.
이제 여기에 style.css 파일을 연결해 줍시다. <head> 요소 안에 다음 코드를 작성해 주세요.
<link rel="stylesheet" href="style.css">
그럼 본격적으로 코드를 작성할 준비는 완료되었습니다!
계산기 몸통 만들기
이번에는 계산기 화면과 버튼들을 담아줄 계산기의 몸통을 만들어봅시다. <body> 요소 사이에 <div> 요소를 하나 만들고, 클래스명으로 calculator라고 작성해 주겠습니다.
<div class="calculator"></div>
CSS 파일에서 calculator 클래스를 선택해 주고, 테두리, 높이, 너비를 적당히 설정해 줍시다. 적당히 너비 350px, 높이 500px, 테두리는 파란색으로 설정해 보겠습니다.
.calculator {
width: 350px;
height: 500px;
border: 1px solid blue;
}
여기까지 작성하고 저장한 후 index.html 파일을 열어보면 다음과 같은 화면을 볼 수 있습니다.
계산기가 화면 중앙에 위치하면 보기 좋을 것 같지 않나요? CSS 파일에서 부모 요소인 <body> 요소를 선택하고 Flexbox 속성을 다음과 같이 작성해 줍니다.
body {
display: flex;
justify-content: center;
align-items: center;
}
코드를 저장하고 새로고침하면 화면이 다음과 같이 변한 것을 확인할 수 있습니다.
어라? justify-content와 align-items 속성 모두 작성해 주었는데, 가로 방향으로만 가운데 정렬이 되었습니다. 왜 이런 현상이 나타나는 걸까요? 부모 요소인 <body> 의 상태를 확인하기 위해서 CSS 파일에서 body 에도 테두리를 설정해 주겠습니다.
body {
...
border: 1px solid red;
}
다시 저장 후 새로고침 해보니, <body> 요소의 높이가 딱 계산기에 몸통에 맞춰져 있는 것을 볼 수 있습니다. 이처럼 부모 요소는 높이를 따로 설정해주지 않으면 자식 요소의 크기에 맞춰서 높이가 설정됩니다.
그럼 <body> 요소의 높이를 설정한 다음 다시 확인해 봅시다. 높이를 100vh로 설정하겠습니다.
body {
...
height: 100vh;
}
이번에도 저장 후 새로고침합니다. 그랬더니 계산기 몸통이 <body> 요소의 높이에 맞춰서 세로로도 가운데 정렬이 잘 된 것을 확인할 수 있습니다.
100vh는 브라우저 화면의 높이만큼의 길이를 뜻합니다. 그런데 우측에 스크롤이 생긴 것으로 보아, body의 실제 높이는 브라우저 화면이 높이보다 길다는 것을 알 수 있습니다. 어떻게 하면 이런 현상을 해결할 수 있을까요? 박스모델과 레이아웃 리셋 내용을 바탕으로 해결해 보세요.
계산기 몸통 채우기
이제 계산기 몸통 안에 숫자를 띄울 화면과 버튼들을 넣어서 채워봅시다. 계산기 몸통을 채울 때, 아래의 Bare-minimun Requirements를 지켜서 진행해 주세요!
Bare-minimum Requirements
- 계산기의 내부에는 계산 과정과 결과가 출력되는 display와 입력을 위한 button container가 있어야 합니다.
- display에는 기본값으로 숫자 0이 출력되어야 합니다.
- 버튼은 <button> 요소로 작성하고, 내용은 텍스트로 작성합니다.
- 아래 이미지는 Unit6의 <계산기 구현하기> 과제에서 사용할 계산기 목업입니다. 계산기에 필요한 버튼을 참고하여 계산기를 구성하세요. 또는 구글에서 이미지 검색을 통해 찾은 계산기를 참고하여 자유롭게 구성해도 괜찮습니다.
- 부모 자식 관계에 유의해서 계산기의 와이어프레임부터 작성해 보세요.
- 프로토 타이핑 툴(파워포인트, figma 등)을 이용하면 좋습니다. 그림판도 괜찮아요.
- 버튼 요소를 정렬할 때 Flexbox 속성 사용을 권장합니다. 학습한 내용을 바탕으로 부모 요소에 적용해야 하는 속성과 자식 요소에 적용해야 하는 속성을 구분해서 사용해 주세요.
- Flexbox는 처음부터 잘 다루기는 매우 어렵습니다. 포기하지 말고 여러 가지 시도를 하면서 익혀보세요.
[그림] 다음 과제 개선에서 사용할 계산기 목업(Mock-up)
[JavaScript] 기초
HTML로 구조를 잡고, CSS로 디자인을 입혔다면, 이제 JavaScript로 웹 페이지에 생명력을 부여할 차례입니다. 천 리 길도 한 걸음부터! 이번 유닛에서는 JavaScript의 기본 문법을 학습하게 됩니다.
여러분은 이제 막 첫걸음을 내디뎠기 때문에, 처음 보는 개념들이 당연히 낯설게 느껴질 수 있습니다. 그러나 낯설 뿐이지, 어려운 내용은 아니니까 걱정하지 마세요! 여러분 자신을 믿고 학습 단계를 천천히 밟아 나가기만 하면 충분히 익힐 수 있는 수준의 내용입니다.
Chapter1. 코드 기초
JavaScript의 기본 개념들을 학습하기 위해서는 코드를 실행하는 방법부터 알아야 합니다. 또, JavaScript엔진이 어떻게 코드를 읽는지, 우리가 작성한 코드를 어떻게 출력할 수 있는지에 대해 알아야 합니다. 이번 챕터를 마치고 나면 여러분은 구구단 n단을 출력하는 코드를 작성할 수 있습니다.
학습 목표
- JavaScript 코드를 직접 실행할 수 있다.
- 원하는 데이터를 console.log()로 출력할 수 있다.
- JavaScript 엔진이 코드를 읽는 법에 대해 기억한다.
- 코드와 주석을 구분할 수 있다.
- 값과 연산자를 구분할 수 있다.
- console.log()로 구구단을 출력할 수 있다.
- 개념학습: 기초 개념을 학습합니다.
- 퀴즈: 학습한 개념의 이해도를 확인합니다.
Chapter 1-1. 코드 실행
- 개념학습: 코드 실행법에 대해서 학습하고 직접 코드를 실행해 본다.
- 퀴즈: 코드 실행법을 잘 기억했는지 퀴즈를 통해 점검합니다.
개념학습
JavaScript 코드 실행하기
JavaScript는 원래 브라우저에서 실행하기 위해 만들어진 프로그래밍 언어입니다. 그래서 HTML 파일과 JavaScript 파일을 함께 브라우저에서 실행해야 작동합니다. 혹은 따로 Node.js라는 JavaScript 런타임을 컴퓨터에 설치해야 합니다.
먼저 Node.js를 설치합니다.
설치 이후, node를 정상적으로 실행할 수 있는지 확인합니다.
[그림] 윈도우에서 명령 프롬포트의 위치
명령 프롬포트를 실행하면 아래와 같은 화면을 확인할 수 있습니다.
[그림] 명령 프롬포트가 실행된 화면
해당 화면에서 node -v 명령어를 입력하여, 정확한 버전이 출력되어야 합니다.
[그림] Node.js 버전 확인 명령어
Node.js로 코드를 실행하는 방법은 두 가지입니다.
- index.js 파일에 원하는 JavaScript 코드를 작성하고, Terminal 혹은 명령 프롬포트에 node index.js를 입력하고 엔터를 누르면 작성한 코드가 실행되고 출력 결과를 확인할 수 있습니다.
- Terminal에 node를 입력하면 REPL을 사용할 수 있습니다. REPL 사용을 종료하려면 .exit를 입력합니다.
직접 해보셨나요? 개발자가 되신 것을 축하드립니다. 여러분은 이미 간단한 프로그램을 개발하고 실행했기 때문입니다. 이렇게 컴퓨터를 특정 방식으로 작동시킬 수 있는 코드의 모음을 프로그램이라고 부르고, 프로그램을 실행하면 프로세스가 됩니다. 지금 보고 있는 브라우저도 하나의 프로세스입니다. 브라우저 개발자들이 모여 열심히 작성한 코드를 실행하여 화면에 구현되어 있기 때문입니다. 앞으로도 크고 작은 단위의 멋진 프로그램을 만드는 개발자로서 최선을 다해봅시다.
Glossary
- REPL(Read-Evaluate-Print loop): 읽고(read), 평가(evaluate)하고, 출력(print)을 반복(loop)하는 가장 간단한 개발 환경입니다. 내가 작성한 코드가 문법에 맞는지 틀린 지 간단하게 실행해 볼 수 있습니다.
- 프로그램(program): 작업(task) 수행을 위한 코드 모음
- 프로세스(process): 프로그램 실행의 결과물.
console.log()
‘hello world’라고 입력하고 엔터를 치는 순간 JavaScript 엔진은 이 코드를 읽고, 평가하고, 출력합니다. REPL 아니고 코드를 직접 실행하는 경우에는 console.log() 메서드로 출력을 할 수 있습니다. 괄호 안에 'hello world'를 입력하고 엔터를 눌러 출력합니다.
console.log('hello world'); // hello world
Glossary
- console.log(): 개발자 도구 콘솔이나 터미널에 원하는 값을 출력할 수 있게 돕는 메서드
퀴즈
Chapter 1-2. 코드 독해
- 개념학습: JavaScript 엔진이 코드를 읽는 법을 잘 이해하고, JavaScript 기본 문법에 대해 학습합니다.
- 퀴즈: 주어진 코드를 읽고 분석할 수 있는지 점검합니다.
개념학습
JavaScript 엔진이 코드 읽는 법
“컴퓨터는 0과 1로 이루어져 있다.”라고 많이 들어보셨을 겁니다. 실제로 그렇습니다. 우리가 사용하는 일반적인 컴퓨터는 0과 1의 조합으로 모든 정보를 표현하고 이해합니다. 이를 기계어라고 부릅니다.
그런데 자바스크립트(JavaScript)는 그렇지 않습니다. 영어도 있고, 기호도 있고, 숫자도 있습니다. 이렇게 사람이 다룰 수 있게 일정한 문법과 의미를 지닌 언어를 프로그래밍 언어라고 부릅니다. JavaScript도 프로그래밍 언어 중 하나입니다. JavaScript 엔진으로 실행할 수 있습니다.
let ourMission = 'Unlock Human Potential';
let JavaScriptWasInventedBy = 'Brendan Eich';
let JavaScriptWasInventedIn = 1995;
i++;
i--;
JavaScript 엔진은 코드를 위에서부터 아래로 코드를 읽고, 해석하고, 평가하다가 문제가 있으면 에러를 발생시키고, 해당 지점에서 코드 실행을 바로 중단합니다. 아래 코드는 실행하면 에러가 발생합니다.
= // SyntaxError: Unexpected token '='
SyntaxError(문법 에러)라는 문구가 에러로 출력되는 것을 확인할 수 있습니다.
영어도 ABC와 5형식부터 배우는 것처럼, JavaScript도 기초 문법부터 충실하게 학습해야 합니다. 다만, 너무 어려운 JavaScript의 특이한 동작이나 문법까지 자세히 배울 필요는 없습니다. 우리나라 말을 하기 위해서 훈민정음을 처음부터 배울 필요가 없는 것처럼, JavaScript도 가장 쉽고 기초적인 문법부터 학습하는 게 좋습니다.
Glossary
- 기계어: 컴퓨터가 이해할 수 있는 숫자로만 구성된 언어. 사람이 쉽게 이해할 수 없다.
- 프로그래밍 언어: 개발자가 프로그램을 작성하기 위한 언어. 기계어와 다르게 사람이 다룰 수 있는 수준의 문법과 의미를 지닌다.
- 자바스크립트(JavaScript): JavaScript는 브라우저, 서버, 모바일 개발이 가능한 멀티 패러다임 프로그래밍 언어입니다.
- JavaScript 엔진: JavaScript 코드를 실행할 수 있는 프로그램입니다. 크롬에 내장된 v8이 대표적입니다.
주석
초창기 많은 개발자는 개발을 하면서 메모를 할 필요성을 느끼기 시작했습니다. 아무리 직관적이고 간결하게 코드를 작성하려 해도, 내가 작성한 코드를 다른 개발자에게 쉽게 설명하기 어려웠습니다. 과거의 내가 열심히 작성했던 코드를 왜 그렇게 작성했는지도 기억하기 쉽지 않았죠.
그래서 코드에 간단히 메모를 하기 위해 주석(comment)를 추가했습니다. JavaScript에서 주석은 // 다음에 작성하거나, /*, */ 사이에 작성하면 됩니다. 주석 처리된 코드는 JavaScript 엔진이 인식하지 않기 때문에 자유롭게 사람의 언어, 자연어를 작성할 수 있습니다.
// 문자열 'hello world'를 설명하는 주석입니다. 주석은 가능하면 코드 위에 작성합니다.
'hello world';
/*
여러 줄의 코드를 주석 처리할 수 있습니다.
console.log('Hello');
*/
Glossary
- 주석: JavaScript 엔진이 따로 해석하지 않는 코드. 개발자가 쓰고 싶은 사람의 언어, 자연어를 자유롭게 작성할 수 있다.
- 자연어: 인간이 쓰는 언어. 컴퓨터공학에서 프로그래밍 언어와 구분하기 위해 사람의 언어를 자연어로 따로 구분한다.
값과 표현식
REPL에 a b c d를 입력해 봅시다. 아마 Uncaught SyntaxError: Unexpected identifier가 발생할 겁니다. 문법 에러가 발생했습니다.
a b c d // Uncaught SyntaxError: Unexpected identifier
123을 입력해 봅시다. 이제는 에러가 발생하지 않습니다. 문법을 잘 지켰네요.
123; // 123
이렇게 읽고, 평가가 완료되어 하나의 의미를 가지는 코드가 **값(value)**입니다. 값을 표현하기 위해서는 다양한 방식이 있습니다. 예를 들어, 숫자값 1995를 표현하기 위해서는 아래와 같은 다양한 코드로 쓸 수 있습니다. 이렇게 하나의 값으로 평가될 수 있는 코드를 표현식(expression)이라고 합니다. + 기호와 같이 값에 변화를 줄 수도 있습니다. 이렇게 산술 연산이나 논리 연산 등을 할 수 있는 기호를 연산자(operator)라고 합니다.
1995;
1000 + 900 + 90 + 5;
1900 + 95;
Glossary
- 값(value): 하나의 고유한 의미를 가지는 코드. JavaScript 엔진이 하나의 값으로 읽고 평가할 수 있어야 한다.
- 표현식(expression): 값으로 평가될 수 있는 코드.
- 연산자(operator): 특정 연산을 수행할 수 있는 코드.
퀴즈
Chapter 1-3. 코드 출력
- 개념학습: 코드 출력법에 대해 학습하고, console.log()로 구구단을 출력할 수 있다.
- 퀴즈: 코드 출력법을 잘 기억했는지 퀴즈를 통해 점검합니다.
개념학습
console.log()
‘hello world’라고 입력하고 엔터를 치는 순간 JavaScript 엔진은 이 코드를 읽고, 평가하고, 출력합니다. REPL이 아니고 코드를 직접 실행하는 경우에는 console.log() 메서드로 출력을 할 수 있습니다. 괄호 안에 'hello world'를 입력하고 파일을 실행하면 출력 결과를 아래와 같이 확인할 수 있습니다.
console.log('hello world'); // hello world
- console.log(): 개발자 도구 콘솔이나 터미널에 원하는 값을 출력할 수 있게 돕는 메서드
구구단 출력하기
지금까지 배운 내용을 기반으로 구구단을 출력해 봅니다. 예를 들어, 2단의 결과를 출력하기 위해서는 값을 직접 입력할 수도 있지만
console.log(2);
console.log(4);
console.log(6);
console.log(8);
console.log(10);
console.log(12);
console.log(14);
console.log(16);
console.log(18);
- * 연산자로 좀 더 직관적으로 2단이라는 것을 표현할 수도 있습니다.
퀴즈
Chapter2. 타입
학습 목표
- 데이터 타입이 무엇인지 이해한다.
- JavaScript의 데이터 타입 중 Number, String, Boolean이 있다는 것을 기억한다.
- Number 타입에 사용가능한 연산자를 사용하여 간단한 연산을 console에 출력할 수 있다.
- Math 내장 매서드 중 Math.floor(), Math.sqrt() 등에 대해 설명할 수 있다.
- + 연산자로 문자열과 문자열을 합칠 수 있다.
- 문자열의 길이를 조회할 수 있다.
- Boolean타입의 두 가지 값인 true와 false를 이해한다.
- 비교연산자(===)와 논리연산자(!, &&, ||)를 이해한다.
Chapter2-0. 타입 개요
Chapter2-1. Number 타입
- 개념학습: Number 타입을 다루는 방법에 대해 학습하고 실습한다.
- 퀴즈: Number 타입 대한 이해도를 퀴즈를 통해 점검합니다.
개념학습
Number 타입
JavaScript의 여러 데이터 타입 중 Number는 일상생활에서 흔히 접할 수 있는 숫자를 자바스크립트에서 표현하기 위한 데이터 타입입니다. 정수(integer)와 실수(float)를 모두 표현할 수 있습니다.
100; // 정수를 표현할 수 있습니다.
-100; // 음수를 표현할 수 있습니다.
100.123; // 실수를 표현할 수 있습니다.
typeof 연산자로 해당 값이 숫자 타입인지 확인할 수 있습니다.
typeof 100; // 'number'
typeof -100; // 'number'
typeof 100.123; // 'number'
같은 숫자 값 간에는 간단한 사칙연산을 할 수 있습니다. 아래 예시에서 사용한 수학 기호 (+ - * / )를 자바스크립트에서는 **산술 연산자(arithmetic operator)**라고 부릅니다.
console.log(1 + 2); // 3
console.log(1 - 2); // -1
console.log(1 * 2); // 2
console.log(1 / 2); // 0.5
console.log(9 % 2); // 1 (9를 2로 나눈 나머지 구하기)
Math 내장 객체
좀 더 복잡한 계산을 위해서는 Math 내장 객체를 사용합니다. Math 내장 객체의 대표적인 메서드에 대해서 알아보겠습니다.
- Math.floor(): 괄호 안의 숫자를 내림하여 반환합니다.
- Math.ceil(): 괄호 안의 숫자를 올림하여 반환합니다.
- Math.round(): 괄호 안의 숫자를 반올림하여 반환합니다.
- Math.abs(): 괄호 안의 숫자의 절대값을 반환합니다.
- Math.sqrt(): 괄호 안의 숫자의 루트값을 반환합니다.
- Math.pow() : 괄호 안의 첫 번째 숫자를 밑, 두 번째 숫자를 지수인 숫자를 반환합니다.
Math.floor(100.621); // 100
Math.ceil(100.621); // 101
Math.round(100.621); // 101
Math.round(100.421); // 100
Math.abs(-100); // 100
Math.abs(100); // 100
Math.sqrt(4); // 2
Math.sqrt(2); // 1.4142135623730951
Math.pow(2, 5); // 32
퀴즈
Chapter2-2. String 타입
- 개념학습: String 타입을 다루는 방법에 대해 학습하고 실습한다.
- 퀴즈: String 타입에 대한 이해도를 퀴즈를 통해 점검합니다.
개념학습
String 타입
JavaScript 데이터 타입 String(문자열)은 인간의 언어, 자연어를 JavaScript에서 표현하기 위한 데이터 타입입니다. 따옴표(’), 큰따옴표(”), 백틱(`)으로 감싸면 됩니다. 맥북의 경우 백틱은 영어로 전환하고 물결(~)을 누르면 입력할 수 있습니다.
한자나 이모지와 같은 특수문자도 문자열로 만들 수 있고, 숫자와 문자를 조합해서 문자열로 만들 수도 있습니다. 특히 백틱으로 만든 문자열은 줄 바꿈도 가능합니다.
'사과'
"JavaScript"
"欢迎你"
"😇"
"최초의 JavaScript는 Netscape의 Brendan Eich에 의해 만들었다."
`JavaScript (줄여서 JS)는 일급 함수를 사용하는 가벼운 객체 지향 인터프리터 언어이며
웹페이지의 스크립트 언어로 잘 알려져 있지만, 브라우저가 아닌 환경에서도 많이 사용된다.
프로토타입 기반, 다중 패러다임 스크립트 언어이며, 동적이고 명령어, 객체 지향, 함수 프로그래밍
스타일을 지원한다.`
+ 로 문자열을 이어 붙일 수 있습니다. 문자열과 문자열을 이어 붙일 때의 + 는 문자열 연결 연산자로써 쓰입니다. 다른 타입과 이어 붙이려고 하면 모두 문자열로 변합니다. 특히, 숫자와 이어 붙이기를 시도하다가 예상 못한 결과를 얻지 않도록 조심합니다. 위 이유로 가능하면 다른 타입 간의 연산을 하지 않도록 조심해야 합니다.
"안녕하세요" + "!!"; // 안녕하세요!!
"감사합니다." + " " + "🙏" // 감사합니다. 🙏
1 + "1" // 11
문자열의 length 속성
문자열의 length 속성을 이용하여 문자열의 길이를 확인할 수 있습니다. 문자열 값에 .length 를 붙이면 됩니다.
console.log('欢迎你'.length); // 3
console.log('최초의 JavaScript는 Netscape의 Brendan Eich에 의해 만들었다.'.length); // 48
인덱스(Index)
문자열의 각 문자는 순서를 가지고 있습니다. 각 문자가 몇 번째에 위치하는지 **인덱스(Index)**로 확인할 수 있습니다. 첫 번째 문자의 인덱스는 0입니다. JavaScript는 우리 일상생활에서 순서를 셀 때 1부터 1, 2, 3 … 세는 것이 아니고, 0부터 세는 점을 주의해 주세요. 이를 Zero-based numbering이라고 합니다.
let str = 'code';
console.log(str[0]); // 'c'
console.log(str[3]); // 'e'
문자열 주요 메서드
문자열의 유용한 메서드 일부를 소개합니다.
- toLowerCase() : 문자열을 소문자로 변경합니다.
- toUpperCase() : 문자열을 대문자로 변경합니다.
- concat() : 문자열 연결 연산자 +처럼 문자열을 이어 붙일 수 있습니다.
- slice() : 문자열의 일부를 자를 수 있습니다.
'HELLO WORLD'.toLowerCase(); // 'hello world'
'hello world'.toUpperCase(); // 'HELLO WORLD'
'hello '.concat('world'); // 'hello world'
'hello world'.slice(0, 5); // 'hello'
- indexOf() : 문자열 내에 특정 문자나 문자가 몇 번째 위치하는지 확인합니다.
- 만약 찾는 문자가 2개 이상일 경우, 가장 앞에 있는 문자의 인덱스를 조회합니다.
- 포함되어 있지 않으면 1을 반환합니다.
'🍎🍓🍉🍇'.indexOf('🍎'); // 0
'🍎🍓🍉🍇'.indexOf('🙏'); // -1
'최초의 JavaScript는 Netscape의 Brendan Eich에 의해 만들었다.'.indexOf('Eich'); // 34
'최초의 JavaScript는 Netscape의 Brendan Eich에 의해 만들었다.'.indexOf('Dahl'); // -1
- includes() : 문자열 내에 특정 문자나 문자가 포함되어 있는지 확인합니다.
퀴즈