├── README.md
├── common.css
├── day1-drum
├── img
│ ├── 1.jpg
│ ├── 2.jpg
│ ├── 3.jpg
│ └── 4.jpg
├── index.html
├── main.css
├── main.js
└── sound
│ ├── 1.mp3
│ ├── 2.mp3
│ ├── 3.mp3
│ ├── 4.mp3
│ └── 5.mp3
├── day2-clock
└── index.html
├── day3-css-variable
├── image.png
└── index.html
├── day4-flexbox
├── index.html
└── main.less
├── index.html
├── main.css
└── thumbnail
├── 1.png
├── 2.png
└── 3.png
/README.md:
--------------------------------------------------------------------------------
1 | # javascript-30
2 | 바닐라 자바스크립트로 30개의 프로젝트 만들기 (https://javascript30.com/)
3 |
--------------------------------------------------------------------------------
/common.css:
--------------------------------------------------------------------------------
1 | footer {
2 | color: white;
3 | margin: 3rem 0 5rem;
4 | }
5 | footer p {
6 | margin: 0;
7 | display: inline-block;
8 | }
9 | footer p:nth-of-type(1) {
10 | float: left;
11 | }
12 | footer p:nth-of-type(2) {
13 | float: right;
14 | }
15 | footer a {
16 | color: #0046a2;
17 | }
18 |
--------------------------------------------------------------------------------
/day1-drum/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/img/1.jpg
--------------------------------------------------------------------------------
/day1-drum/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/img/2.jpg
--------------------------------------------------------------------------------
/day1-drum/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/img/3.jpg
--------------------------------------------------------------------------------
/day1-drum/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/img/4.jpg
--------------------------------------------------------------------------------
/day1-drum/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 | CAT VOICE PIANO
12 |
13 |
14 | -
15 |
16 | A
17 |
18 | -
19 |
20 | S
21 |
22 | -
23 |
24 | D
25 |
26 | -
27 |
28 | F
29 |
30 |
31 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/day1-drum/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | text-align: center;
3 | background: #0c0c0c;
4 | }
5 | h1 {
6 | display: inline-block;
7 | padding: 1rem 2rem;
8 | background: #3cffc9;
9 | font-weight: 900;
10 | }
11 | ul {
12 | padding: 0;
13 | margin: 0;
14 | }
15 | li {
16 | display: inline-block;
17 | border: 1px solid #f3f3f3;
18 | border-radius: 15px;
19 | padding: 1rem;
20 | transition: all 0.3s;
21 | margin: 0.5rem 0.3rem;
22 | }
23 | li.playing {
24 | transform: scale(1.3);
25 | }
26 | li:nth-of-type(1) {
27 | background: #7183FB;
28 | }
29 | li:nth-of-type(2) {
30 | background: #FDB92C;
31 | }
32 | li:nth-of-type(3) {
33 | background: #FC52BC;
34 | }
35 | li:nth-of-type(4) {
36 | background: #fc5252;
37 | }
38 | li img {
39 | width: 110px;
40 | border-radius: 50%;
41 | }
42 | li p {
43 | color: white;
44 | margin: 7px 0 0px;
45 | font-weight: 900;
46 | font-size: 5rem;
47 | }
48 |
--------------------------------------------------------------------------------
/day1-drum/main.js:
--------------------------------------------------------------------------------
1 | window.addEventListener('keydown', e => {
2 | const keyCode = e.keyCode;
3 | const audioEl = document.querySelector(`audio[data-key="${keyCode}"`);
4 | const pianoEl = document.querySelector(`li[data-key="${keyCode}"`);
5 | if(!audioEl) return;
6 | audioEl.currentTime = 0;
7 | audioEl.play();
8 | pianoEl.classList.add('playing');
9 | });
10 |
11 | const pianoElList = document.querySelectorAll('li');
12 | pianoElList.forEach(el => {
13 | el.addEventListener('transitionend', function(e) {
14 | if (e.propertyName === 'transform') {
15 | this.classList.remove('playing');
16 | }
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/day1-drum/sound/1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/sound/1.mp3
--------------------------------------------------------------------------------
/day1-drum/sound/2.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/sound/2.mp3
--------------------------------------------------------------------------------
/day1-drum/sound/3.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/sound/3.mp3
--------------------------------------------------------------------------------
/day1-drum/sound/4.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/sound/4.mp3
--------------------------------------------------------------------------------
/day1-drum/sound/5.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day1-drum/sound/5.mp3
--------------------------------------------------------------------------------
/day2-clock/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | CSS&JS CLOCK
8 |
9 |
10 |
11 |
12 |
18 |
21 |
25 |
26 |
90 |
120 |
--------------------------------------------------------------------------------
/day3-css-variable/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/day3-css-variable/image.png
--------------------------------------------------------------------------------
/day3-css-variable/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 시력검사
8 |
9 |
10 |
11 | 저 멀리 집 쳐다보세요~
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |

23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
65 |
77 |
--------------------------------------------------------------------------------
/day4-flexbox/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 | CSS Flexbox
13 |
14 |
15 | flex-direction: 메인 축 정하기
16 |
17 | - flex-direction: row // 기본. 행으로 쌓임 (왼쪽 -> 오른쪽)
18 | - row-reverse // row가 반대로 쌓임 (오른쪽 -> 왼쪽)
19 | - column // 열로 쌓임(위 -> 아래)
20 |
21 |
22 |
1
23 |
2
24 |
3
25 |
26 |
27 |
28 | flex wrapping: 각 요소 부피, 순서 정하기
29 |
30 | - flex: 1 // 각각 1씩 부피 차지. 1/2/1 하면 그만큼씩 부피 차지.
31 | - order: 5 // 기본은 0. 클수록 main-axis의 뒤로 간다.
32 |
33 |
34 |
1
35 |
2
36 |
3
37 |
38 |
39 |
40 | justify-content: 메인 축 기준으로 정렬
41 |
42 | - justify-content: flex-start // 기본 정렬
43 | - flex-end // main-axis의 끝쪽으로 정렬
44 | - center // main-axis의 중앙으로 정렬
45 | - space-between // 중간에 스페이스 넣어서 정렬
46 | - space-around // 중간에 스페이스 넣어서 정렬하는데 처음이랑 끝도 스페이스 넣음
47 | - flex-direction을 column으로 했을 때는 height를 정해줘야 원하는 정렬이 나올것이다.
48 |
49 |
50 |
1
51 |
2
52 |
3
53 |
54 |
55 |
1
56 |
2
57 |
3
58 |
59 |
60 |
1
61 |
2
62 |
3
63 |
64 |
65 |
1
66 |
2
67 |
3
68 |
69 |
70 |
71 |
72 | align-items: 수직 정렬
73 |
74 | - align-items: center; // 수직 가운데 정렬
75 | - align-items: stretch; // 이게 기본. height에 맞게 쭉쭉 늘린다
76 | - flex-end; // 수직 하단 정렬
77 | - baseline; // 각각 크기 다른 div, 그들의 baseline에 맞게 수직 정렬
78 |
79 |
80 |
1
81 |
2
82 |
3
83 |
84 |
85 |
1
86 |
2
87 |
3
88 |
89 |
90 |
1
91 |
2
92 |
3
93 |
94 |
95 |
96 |
97 | align-content: 수직 정렬 (justify-content랑 같은 인자를 받지만, 얘는 cross-axis 기준)
98 |
99 |
1
100 |
2
101 |
3
102 |
103 |
104 |
1
105 |
2
106 |
3
107 |
108 |
109 |
110 |
111 | align-self: 자기 자신을 align함
112 |
113 | - 부모는 align-items: flex-end하고 자식은 align-self: flex-start 할 수 있다.
114 |
115 |
116 |
1
117 |
2
118 |
3
119 |
4
120 |
121 |
122 |
123 |
124 | flex basis, grow, shrink: 기본 크기, 여백이 있을때/없을때 비율 정하기
125 |
126 | - flex-basis:200px; // 기본 크기는 200px
127 | - flex-grow: 5; // box1이 box2보다 5배 길이를 가진 것이 아니고, 200px씩을 뺀 남은 여백에서 비율이 5:1로 간다. 기본은 0이다 - 지정 안하면 여백 있어도 아무 것도 안한다
128 | - flex-shrink: 3; // 400px아래로 내려갔을 때 뺀 값만큼 3배로 줄어듦
129 | - flex: 5 3 200px; // 위를 한번에 쓴 것. grow, shrink, basis
130 |
131 |
135 |
136 |
137 |
138 | flex-wrap: row를 감싸주기
139 |
140 | - flex-wrap: wrap; // 이거 없으면 그냥 한 줄에 다 나올텐데 넣으니 스르륵 내려옴(200px맞춰서)
141 | - flex-grow: 10; // flex-wrap으로 아래로 떨어져도, 여백의 10배 차지하는건 그 row만 기준이다. 전체 row기준 아님.
142 |
143 |
144 |
1
145 |
2
146 |
3
147 |
4
148 |
1
149 |
2
150 |
3
151 |
4
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/day4-flexbox/main.less:
--------------------------------------------------------------------------------
1 | @color-1: #ff4242;
2 | @color-2: #2196f3;
3 | @color-3: #cddc39;
4 | @color-4: #ffa52f;
5 |
6 | .outer {
7 | display: flex; // 상위 DOM을 플렉스로 감싼다
8 | border: 3px solid #e8e8e8;
9 | margin-bottom: 8px;
10 | // height: 50px;
11 | div {
12 | font-size: 2rem;
13 | color: white;
14 | font-weight: 900;
15 | text-align: center;
16 | padding: 1rem;
17 | &:nth-child(1), &.box1 {
18 | background: @color-1;
19 | }
20 | &:nth-child(2), &.box2 {
21 | background: @color-2;
22 | }
23 | &:nth-child(3), &.box3 {
24 | background: @color-3;
25 | }
26 | &:nth-child(4), &.box4 {
27 | background: @color-4;
28 | }
29 | }
30 | }
31 |
32 | h2 {
33 | margin-top: 4rem;
34 | }
35 |
36 | container.part1 {
37 | .outer { // 플렉스로 감싼 돔에 flex-direction 설정
38 | // flex-direction: row; // 이게 기본. 행으로 쌓임
39 | flex-direction: row-reverse; // row가 반대로 쌓임
40 | // flex-direction: column; // 열로 쌓임
41 | }
42 | }
43 |
44 | container.part2 {
45 | div {
46 | flex: 1; // 각각 1씩 부피 차지
47 | &.box2 {
48 | flex: 2;
49 | }
50 | &.box2 {
51 | order: 5; // 기본은 0. 이러면 2만 맨 뒤로 간다
52 | }
53 | }
54 | }
55 |
56 | container.part3 {
57 | .outer1 {
58 | // justify-content: flex-start; // 이게 기본.
59 | justify-content: flex-end; // main axis의 끝쪽으로 정렬
60 | }
61 | .outer2 {
62 | justify-content: center; // main axis의 중앙
63 | }
64 | .outer3 {
65 | // justify-content: space-between; // 중간에 스페이스 넣어서 정렬
66 | justify-content: space-around; // 중간에 스페이스 넣어서 정렬하는데 처음이랑 끝도 스페이스 넣음
67 | }
68 | .outer4 {
69 | flex-direction: column;
70 | justify-content: space-between;
71 | height: 30vh;
72 | }
73 | }
74 |
75 | container.part4 {
76 | .outer {
77 | height: 15vh;
78 | // align-items: stretch; // 이게 기본. height에 맞게 쭉쭉 늘린다
79 | }
80 | .outer1 {
81 | align-items: center; // 수직 가운데 정렬
82 | }
83 | .outer2 {
84 | align-items: flex-end; // 수직 하단 정렬
85 | }
86 | .outer3 {
87 | align-items: baseline; // 각각 크기 다른 div, 그들의 baseline에 맞게 수직 정렬
88 | div {
89 | &:nth-child(2) {
90 | font-size: 30px;
91 | }
92 | &:nth-child(3) {
93 | font-size: 50px
94 | }
95 | }
96 | }
97 | }
98 |
99 | container.part5 {
100 | .outer1 {
101 | align-content: space-between; // cross-axis에서 space-between 정렬
102 | flex-wrap: wrap;
103 | height: 30vh;
104 | div {
105 | width: 40%;
106 | }
107 | }
108 | .outer2 {
109 | align-content: flex-end;
110 | justify-content: center; // main-axis도 가운데 정렬해보자
111 | flex-wrap: wrap;
112 | height: 30vh;
113 | div {
114 | width: 40%;
115 | }
116 | }
117 | }
118 |
119 | container.part6 {
120 | .outer1 {
121 | align-items: flex-end;
122 | height: 20vh;
123 | .box2 {
124 | align-self: flex-start; // 본인을 align함
125 | }
126 | .box4 {
127 | align-self: stretch;
128 | }
129 | }
130 | }
131 |
132 | container.part7 {
133 | .outer1 {
134 | div {
135 | // flex: 1; // flex-grow: 1; flex-shrink:1; 을 줄인거임
136 | // flex-grow: 1; // 여분의 공간이 있을 때 어떡할거냐
137 | // flex-shrink: 1;
138 | // flex-basis:
139 | &.box1 {
140 | flex-basis: 200px;
141 | flex-grow: 5; // box1이 box2보다 5배 길이를 가진 것이 아니고, 200px씩을 뺀 남은 여백에서 비율이 5:1로 간다
142 | flex-shrink: 3; // 400px아래로 내려갔을 때 뺀 값만큼 3배로 줄어듦
143 | flex: 5 3 200px; // 위를 한번에 쓴 것. grow, shrink, basis
144 | }
145 | &.box2 {
146 | flex-basis: 200px;
147 | flex-grow: 1; // 기본은 0이다 - 지정 안하면 여백 있어도 아무 것도 안한다
148 | flex-shrink: 1;
149 | }
150 | }
151 | }
152 | }
153 |
154 | container.part8 {
155 | .outer{
156 | flex-wrap: wrap; // 이거 없으면 그냥 한 줄에 다 나올텐데 넣으니 스르륵 내려옴(200px맞춰서)
157 | flex-direction: column;
158 | height: 50vh;
159 | div {
160 | flex-basis: 120px;
161 | flex-grow: 1;
162 | &.box3 {
163 | flex-grow: 10; // flex-wrap으로 아래로 떨어져도, 여백의 10배 차지하는건 그 row만 기준이다. 전체 row기준 아님.
164 | }
165 | }
166 | }
167 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Javascript 30
8 |
9 |
10 |
11 | Jay Jin's Mini Projects
12 |
32 |
33 |
--------------------------------------------------------------------------------
/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | text-align: center;
3 | background: #F6F6F8;
4 | }
5 | ul {
6 | margin: 0;
7 | padding: 0;
8 | display: flex;
9 | flex-direction: row;
10 | flex-wrap: wrap;
11 | }
12 | li {
13 | display: inline-block;
14 | flex: auto;
15 | background: white;
16 | margin: 0.5rem;
17 | padding: 1.5rem 0 0.5rem;
18 | box-shadow: 0 20px 20px rgba(0, 0, 0, 0.08);
19 | border-radius: 3px;
20 | }
21 | li img {
22 | height: 100px;
23 | }
--------------------------------------------------------------------------------
/thumbnail/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/thumbnail/1.png
--------------------------------------------------------------------------------
/thumbnail/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/thumbnail/2.png
--------------------------------------------------------------------------------
/thumbnail/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milooy/javascript30/d61eb2ea60f0c9a612f197e169f93f41b10b2911/thumbnail/3.png
--------------------------------------------------------------------------------