├── README.md ├── session-1 ├── css │ ├── normalize.css │ ├── reset.css │ └── styles.css ├── index.html └── js │ └── main.js ├── session-2 ├── css │ ├── normalize.css │ ├── reset.css │ └── styles.css ├── index.html └── js │ └── main.js └── session-3 ├── css ├── normalize.css ├── reset.css └── styles.css ├── index.html └── js └── main.js /README.md: -------------------------------------------------------------------------------- 1 | # calculator 2 | A calculator built with HTML, CSS & JS - Created by Kevin & Zell during live streams on YT. 3 | 4 | ## Watch the replays 5 | 6 | - [HTML & CSS](https://youtu.be/EuwzyB_FQNs) 7 | - [JS (Happy Path)](https://youtu.be/f0SG2j6d-Kg) 8 | - [Testing with Vanilla JS](https://youtu.be/G_z39jRHu2M) 9 | 10 | ## Source code 11 | 12 | You can grab the source code from each session. They're filed under [session-1](session-1), [session-2](session-2) and [session-3](session-3) respectively. 13 | 14 | ## Follow Kevin and Zell! 15 | 16 | You're welcome to follow us for more web development resources :) 17 | 18 | - [Kevin's website](https://www.kevinpowell.co) 19 | - [Zell's website](https://zellwk.com) 20 | -------------------------------------------------------------------------------- /session-1/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in 9 | * IE on Windows Phone and in iOS. 10 | */ 11 | 12 | html { 13 | line-height: 1.15; /* 1 */ 14 | -ms-text-size-adjust: 100%; /* 2 */ 15 | -webkit-text-size-adjust: 100%; /* 2 */ 16 | } 17 | 18 | /* Sections 19 | ========================================================================== */ 20 | 21 | /** 22 | * Remove the margin in all browsers (opinionated). 23 | */ 24 | 25 | body { 26 | margin: 0; 27 | } 28 | 29 | /** 30 | * Add the correct display in IE 9-. 31 | */ 32 | 33 | article, 34 | aside, 35 | footer, 36 | header, 37 | nav, 38 | section { 39 | display: block; 40 | } 41 | 42 | /** 43 | * Correct the font size and margin on `h1` elements within `section` and 44 | * `article` contexts in Chrome, Firefox, and Safari. 45 | */ 46 | 47 | h1 { 48 | font-size: 2em; 49 | margin: 0.67em 0; 50 | } 51 | 52 | /* Grouping content 53 | ========================================================================== */ 54 | 55 | /** 56 | * Add the correct display in IE 9-. 57 | * 1. Add the correct display in IE. 58 | */ 59 | 60 | figcaption, 61 | figure, 62 | main { /* 1 */ 63 | display: block; 64 | } 65 | 66 | /** 67 | * Add the correct margin in IE 8. 68 | */ 69 | 70 | figure { 71 | margin: 1em 40px; 72 | } 73 | 74 | /** 75 | * 1. Add the correct box sizing in Firefox. 76 | * 2. Show the overflow in Edge and IE. 77 | */ 78 | 79 | hr { 80 | box-sizing: content-box; /* 1 */ 81 | height: 0; /* 1 */ 82 | overflow: visible; /* 2 */ 83 | } 84 | 85 | /** 86 | * 1. Correct the inheritance and scaling of font size in all browsers. 87 | * 2. Correct the odd `em` font sizing in all browsers. 88 | */ 89 | 90 | pre { 91 | font-family: monospace, monospace; /* 1 */ 92 | font-size: 1em; /* 2 */ 93 | } 94 | 95 | /* Text-level semantics 96 | ========================================================================== */ 97 | 98 | /** 99 | * 1. Remove the gray background on active links in IE 10. 100 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 101 | */ 102 | 103 | a { 104 | background-color: transparent; /* 1 */ 105 | -webkit-text-decoration-skip: objects; /* 2 */ 106 | } 107 | 108 | /** 109 | * 1. Remove the bottom border in Chrome 57- and Firefox 39-. 110 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 111 | */ 112 | 113 | abbr[title] { 114 | border-bottom: none; /* 1 */ 115 | text-decoration: underline; /* 2 */ 116 | text-decoration: underline dotted; /* 2 */ 117 | } 118 | 119 | /** 120 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 121 | */ 122 | 123 | b, 124 | strong { 125 | font-weight: inherit; 126 | } 127 | 128 | /** 129 | * Add the correct font weight in Chrome, Edge, and Safari. 130 | */ 131 | 132 | b, 133 | strong { 134 | font-weight: bolder; 135 | } 136 | 137 | /** 138 | * 1. Correct the inheritance and scaling of font size in all browsers. 139 | * 2. Correct the odd `em` font sizing in all browsers. 140 | */ 141 | 142 | code, 143 | kbd, 144 | samp { 145 | font-family: monospace, monospace; /* 1 */ 146 | font-size: 1em; /* 2 */ 147 | } 148 | 149 | /** 150 | * Add the correct font style in Android 4.3-. 151 | */ 152 | 153 | dfn { 154 | font-style: italic; 155 | } 156 | 157 | /** 158 | * Add the correct background and color in IE 9-. 159 | */ 160 | 161 | mark { 162 | background-color: #ff0; 163 | color: #000; 164 | } 165 | 166 | /** 167 | * Add the correct font size in all browsers. 168 | */ 169 | 170 | small { 171 | font-size: 80%; 172 | } 173 | 174 | /** 175 | * Prevent `sub` and `sup` elements from affecting the line height in 176 | * all browsers. 177 | */ 178 | 179 | sub, 180 | sup { 181 | font-size: 75%; 182 | line-height: 0; 183 | position: relative; 184 | vertical-align: baseline; 185 | } 186 | 187 | sub { 188 | bottom: -0.25em; 189 | } 190 | 191 | sup { 192 | top: -0.5em; 193 | } 194 | 195 | /* Embedded content 196 | ========================================================================== */ 197 | 198 | /** 199 | * Add the correct display in IE 9-. 200 | */ 201 | 202 | audio, 203 | video { 204 | display: inline-block; 205 | } 206 | 207 | /** 208 | * Add the correct display in iOS 4-7. 209 | */ 210 | 211 | audio:not([controls]) { 212 | display: none; 213 | height: 0; 214 | } 215 | 216 | /** 217 | * Remove the border on images inside links in IE 10-. 218 | */ 219 | 220 | img { 221 | border-style: none; 222 | } 223 | 224 | /** 225 | * Hide the overflow in IE. 226 | */ 227 | 228 | svg:not(:root) { 229 | overflow: hidden; 230 | } 231 | 232 | /* Forms 233 | ========================================================================== */ 234 | 235 | /** 236 | * 1. Change the font styles in all browsers (opinionated). 237 | * 2. Remove the margin in Firefox and Safari. 238 | */ 239 | 240 | button, 241 | input, 242 | optgroup, 243 | select, 244 | textarea { 245 | font-family: sans-serif; /* 1 */ 246 | font-size: 100%; /* 1 */ 247 | line-height: 1.15; /* 1 */ 248 | margin: 0; /* 2 */ 249 | } 250 | 251 | /** 252 | * Show the overflow in IE. 253 | * 1. Show the overflow in Edge. 254 | */ 255 | 256 | button, 257 | input { /* 1 */ 258 | overflow: visible; 259 | } 260 | 261 | /** 262 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 263 | * 1. Remove the inheritance of text transform in Firefox. 264 | */ 265 | 266 | button, 267 | select { /* 1 */ 268 | text-transform: none; 269 | } 270 | 271 | /** 272 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 273 | * controls in Android 4. 274 | * 2. Correct the inability to style clickable types in iOS and Safari. 275 | */ 276 | 277 | button, 278 | html [type="button"], /* 1 */ 279 | [type="reset"], 280 | [type="submit"] { 281 | -webkit-appearance: button; /* 2 */ 282 | } 283 | 284 | /** 285 | * Remove the inner border and padding in Firefox. 286 | */ 287 | 288 | button::-moz-focus-inner, 289 | [type="button"]::-moz-focus-inner, 290 | [type="reset"]::-moz-focus-inner, 291 | [type="submit"]::-moz-focus-inner { 292 | border-style: none; 293 | padding: 0; 294 | } 295 | 296 | /** 297 | * Restore the focus styles unset by the previous rule. 298 | */ 299 | 300 | button:-moz-focusring, 301 | [type="button"]:-moz-focusring, 302 | [type="reset"]:-moz-focusring, 303 | [type="submit"]:-moz-focusring { 304 | outline: 1px dotted ButtonText; 305 | } 306 | 307 | /** 308 | * Correct the padding in Firefox. 309 | */ 310 | 311 | fieldset { 312 | padding: 0.35em 0.75em 0.625em; 313 | } 314 | 315 | /** 316 | * 1. Correct the text wrapping in Edge and IE. 317 | * 2. Correct the color inheritance from `fieldset` elements in IE. 318 | * 3. Remove the padding so developers are not caught out when they zero out 319 | * `fieldset` elements in all browsers. 320 | */ 321 | 322 | legend { 323 | box-sizing: border-box; /* 1 */ 324 | color: inherit; /* 2 */ 325 | display: table; /* 1 */ 326 | max-width: 100%; /* 1 */ 327 | padding: 0; /* 3 */ 328 | white-space: normal; /* 1 */ 329 | } 330 | 331 | /** 332 | * 1. Add the correct display in IE 9-. 333 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. 334 | */ 335 | 336 | progress { 337 | display: inline-block; /* 1 */ 338 | vertical-align: baseline; /* 2 */ 339 | } 340 | 341 | /** 342 | * Remove the default vertical scrollbar in IE. 343 | */ 344 | 345 | textarea { 346 | overflow: auto; 347 | } 348 | 349 | /** 350 | * 1. Add the correct box sizing in IE 10-. 351 | * 2. Remove the padding in IE 10-. 352 | */ 353 | 354 | [type="checkbox"], 355 | [type="radio"] { 356 | box-sizing: border-box; /* 1 */ 357 | padding: 0; /* 2 */ 358 | } 359 | 360 | /** 361 | * Correct the cursor style of increment and decrement buttons in Chrome. 362 | */ 363 | 364 | [type="number"]::-webkit-inner-spin-button, 365 | [type="number"]::-webkit-outer-spin-button { 366 | height: auto; 367 | } 368 | 369 | /** 370 | * 1. Correct the odd appearance in Chrome and Safari. 371 | * 2. Correct the outline style in Safari. 372 | */ 373 | 374 | [type="search"] { 375 | -webkit-appearance: textfield; /* 1 */ 376 | outline-offset: -2px; /* 2 */ 377 | } 378 | 379 | /** 380 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. 381 | */ 382 | 383 | [type="search"]::-webkit-search-cancel-button, 384 | [type="search"]::-webkit-search-decoration { 385 | -webkit-appearance: none; 386 | } 387 | 388 | /** 389 | * 1. Correct the inability to style clickable types in iOS and Safari. 390 | * 2. Change font properties to `inherit` in Safari. 391 | */ 392 | 393 | ::-webkit-file-upload-button { 394 | -webkit-appearance: button; /* 1 */ 395 | font: inherit; /* 2 */ 396 | } 397 | 398 | /* Interactive 399 | ========================================================================== */ 400 | 401 | /* 402 | * Add the correct display in IE 9-. 403 | * 1. Add the correct display in Edge, IE, and Firefox. 404 | */ 405 | 406 | details, /* 1 */ 407 | menu { 408 | display: block; 409 | } 410 | 411 | /* 412 | * Add the correct display in all browsers. 413 | */ 414 | 415 | summary { 416 | display: list-item; 417 | } 418 | 419 | /* Scripting 420 | ========================================================================== */ 421 | 422 | /** 423 | * Add the correct display in IE 9-. 424 | */ 425 | 426 | canvas { 427 | display: inline-block; 428 | } 429 | 430 | /** 431 | * Add the correct display in IE. 432 | */ 433 | 434 | template { 435 | display: none; 436 | } 437 | 438 | /* Hidden 439 | ========================================================================== */ 440 | 441 | /** 442 | * Add the correct display in IE 10-. 443 | */ 444 | 445 | [hidden] { 446 | display: none; 447 | } -------------------------------------------------------------------------------- /session-1/css/reset.css: -------------------------------------------------------------------------------- 1 | /******************* 2 | Box Sizing 3 | *******************/ 4 | html { 5 | box-sizing: border-box; 6 | } 7 | 8 | *, 9 | *::before, 10 | *::after { 11 | box-sizing: inherit; 12 | } 13 | 14 | /**************************** 15 | Generic Margins and Paddings 16 | ****************************/ 17 | body, 18 | h1, 19 | h2, 20 | h3, 21 | h4, 22 | h5, 23 | h6, 24 | ul, 25 | ol, 26 | li, 27 | p, 28 | pre, 29 | blockquote, 30 | figure, 31 | hr { 32 | margin: 0; 33 | padding: 0; 34 | } 35 | 36 | /******************* 37 | Lists 38 | *******************/ 39 | ul { 40 | list-style: none; 41 | } 42 | 43 | /******************* 44 | Forms and buttons 45 | *******************/ 46 | input, 47 | textarea, 48 | select, 49 | button { 50 | color: inherit; 51 | font: inherit; 52 | letter-spacing: inherit; 53 | } 54 | 55 | /* I usually expand input and textarea to full-width */ 56 | input[type="text"], 57 | textarea { 58 | width: 100%; 59 | } 60 | 61 | /* More friendly border */ 62 | input, 63 | textarea, 64 | button { 65 | border: 1px solid gray; 66 | } 67 | 68 | /* Some defaults for one-liner buttons */ 69 | button { 70 | padding: 0.75em 1em; 71 | border-radius: 0; 72 | line-height: 1; 73 | background-color: transparent; 74 | } 75 | 76 | button * { 77 | pointer-events: none; 78 | } 79 | 80 | /*********************************** 81 | Easy responsive for media elements 82 | ***********************************/ 83 | img, 84 | svg, 85 | iframe, 86 | video, 87 | object, 88 | embed { 89 | display: block; 90 | max-width: 100%; 91 | } 92 | 93 | /******************* 94 | Useful table styles 95 | *******************/ 96 | table { 97 | table-layout: fixed; 98 | width: 100%; 99 | } 100 | 101 | /******************* 102 | The hidden attribute 103 | *******************/ 104 | [hidden] { 105 | display: none !important; 106 | } 107 | 108 | /******************* 109 | Noscript 110 | *******************/ 111 | noscript { 112 | display: block; 113 | margin-bottom: 1em; 114 | margin-top: 1em; 115 | } 116 | 117 | /******************* 118 | Focus 119 | *******************/ 120 | [tabindex="-1"] { 121 | outline: none !important; 122 | } 123 | -------------------------------------------------------------------------------- /session-1/css/styles.css: -------------------------------------------------------------------------------- 1 | /** 2 | * base styles and typography 3 | * --------------- 4 | */ 5 | :root { 6 | --orange-050: #ffe8d9; 7 | --orange-100: #ffd0b5; 8 | --orange-200: #ffb088; 9 | --orange-300: #ff9466; 10 | --orange-400: #f9703e; 11 | --orange-500: #f35627; 12 | --orange-600: #de3a11; 13 | --orange-700: #c52707; 14 | --orange-800: #ad1d07; 15 | --orange-900: #841003; 16 | 17 | --grey-050: #f5f7fa; 18 | --grey-100: #e4e7eb; 19 | --grey-200: #cbd2d9; 20 | --grey-300: #9aa5b1; 21 | --grey-400: #7b8794; 22 | --grey-500: #616e7c; 23 | --grey-600: #52606d; 24 | --grey-700: #3e4c59; 25 | --grey-800: #323f4b; 26 | --grey-900: #1f2933; 27 | } 28 | 29 | /******************* 30 | Base styles 31 | *******************/ 32 | html { 33 | font-size: 150%; 34 | font-weight: 300; 35 | font-family: "Roboto", Helvetica, Arial, sans-serif; 36 | line-height: 1.4; 37 | } 38 | 39 | body { 40 | display: flex; 41 | background-image: linear-gradient(236deg, #74ebd5, #acb6e5); 42 | justify-content: center; 43 | align-items: center; 44 | height: 100vh; 45 | } 46 | 47 | /******************* 48 | Calculator 49 | *******************/ 50 | .calculator { 51 | box-shadow: 0 0 25px 0 rgba(0, 0, 0, 0.3); 52 | border-radius: 0.5em; 53 | overflow: hidden; 54 | } 55 | 56 | .calculator__display { 57 | background-color: var(--grey-900); 58 | color: var(--grey-050); 59 | width: 16.25rem; 60 | padding: 0.75rem 1rem; 61 | text-align: right; 62 | font-size: calc(1rem * 1.2 * 1.2); 63 | } 64 | 65 | .calculator__keys { 66 | background: var(--grey-200); 67 | display: grid; 68 | grid-gap: 2px; 69 | grid-template-columns: repeat(4, auto); 70 | grid-template-areas: 71 | ". . . ." 72 | "seven eight nine equal" 73 | "four five six equal" 74 | "one two three equal" 75 | "zero decimal clear equal"; 76 | } 77 | 78 | .calculator__keys > button { 79 | border: 0; 80 | } 81 | 82 | .one { 83 | grid-area: one; 84 | } 85 | .two { 86 | grid-area: two; 87 | } 88 | .three { 89 | grid-area: three; 90 | } 91 | .four { 92 | grid-area: four; 93 | } 94 | .five { 95 | grid-area: five; 96 | } 97 | .six { 98 | grid-area: six; 99 | } 100 | .seven { 101 | grid-area: seven; 102 | } 103 | .eight { 104 | grid-area: eight; 105 | } 106 | .nine { 107 | grid-area: nine; 108 | } 109 | .zero { 110 | grid-area: zero; 111 | } 112 | .decimal { 113 | grid-area: decimal; 114 | } 115 | .clear { 116 | grid-area: clear; 117 | } 118 | .equal { 119 | grid-area: equal; 120 | background-color: var(--orange-400); 121 | } 122 | 123 | .equal:active { 124 | background-color: var(--orange-500); 125 | } 126 | 127 | .operator { 128 | background: var(--grey-100); 129 | } 130 | 131 | .number { 132 | background: #fff; 133 | } 134 | 135 | .operator:active, 136 | .number:active { 137 | background: var(--grey-200); 138 | } 139 | -------------------------------------------------------------------------------- /session-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Calculator 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
0
21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 |
41 |
42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /session-1/js/main.js: -------------------------------------------------------------------------------- 1 | // Start writing JavaScript here! 2 | -------------------------------------------------------------------------------- /session-2/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in 9 | * IE on Windows Phone and in iOS. 10 | */ 11 | 12 | html { 13 | line-height: 1.15; /* 1 */ 14 | -ms-text-size-adjust: 100%; /* 2 */ 15 | -webkit-text-size-adjust: 100%; /* 2 */ 16 | } 17 | 18 | /* Sections 19 | ========================================================================== */ 20 | 21 | /** 22 | * Remove the margin in all browsers (opinionated). 23 | */ 24 | 25 | body { 26 | margin: 0; 27 | } 28 | 29 | /** 30 | * Add the correct display in IE 9-. 31 | */ 32 | 33 | article, 34 | aside, 35 | footer, 36 | header, 37 | nav, 38 | section { 39 | display: block; 40 | } 41 | 42 | /** 43 | * Correct the font size and margin on `h1` elements within `section` and 44 | * `article` contexts in Chrome, Firefox, and Safari. 45 | */ 46 | 47 | h1 { 48 | font-size: 2em; 49 | margin: 0.67em 0; 50 | } 51 | 52 | /* Grouping content 53 | ========================================================================== */ 54 | 55 | /** 56 | * Add the correct display in IE 9-. 57 | * 1. Add the correct display in IE. 58 | */ 59 | 60 | figcaption, 61 | figure, 62 | main { /* 1 */ 63 | display: block; 64 | } 65 | 66 | /** 67 | * Add the correct margin in IE 8. 68 | */ 69 | 70 | figure { 71 | margin: 1em 40px; 72 | } 73 | 74 | /** 75 | * 1. Add the correct box sizing in Firefox. 76 | * 2. Show the overflow in Edge and IE. 77 | */ 78 | 79 | hr { 80 | box-sizing: content-box; /* 1 */ 81 | height: 0; /* 1 */ 82 | overflow: visible; /* 2 */ 83 | } 84 | 85 | /** 86 | * 1. Correct the inheritance and scaling of font size in all browsers. 87 | * 2. Correct the odd `em` font sizing in all browsers. 88 | */ 89 | 90 | pre { 91 | font-family: monospace, monospace; /* 1 */ 92 | font-size: 1em; /* 2 */ 93 | } 94 | 95 | /* Text-level semantics 96 | ========================================================================== */ 97 | 98 | /** 99 | * 1. Remove the gray background on active links in IE 10. 100 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 101 | */ 102 | 103 | a { 104 | background-color: transparent; /* 1 */ 105 | -webkit-text-decoration-skip: objects; /* 2 */ 106 | } 107 | 108 | /** 109 | * 1. Remove the bottom border in Chrome 57- and Firefox 39-. 110 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 111 | */ 112 | 113 | abbr[title] { 114 | border-bottom: none; /* 1 */ 115 | text-decoration: underline; /* 2 */ 116 | text-decoration: underline dotted; /* 2 */ 117 | } 118 | 119 | /** 120 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 121 | */ 122 | 123 | b, 124 | strong { 125 | font-weight: inherit; 126 | } 127 | 128 | /** 129 | * Add the correct font weight in Chrome, Edge, and Safari. 130 | */ 131 | 132 | b, 133 | strong { 134 | font-weight: bolder; 135 | } 136 | 137 | /** 138 | * 1. Correct the inheritance and scaling of font size in all browsers. 139 | * 2. Correct the odd `em` font sizing in all browsers. 140 | */ 141 | 142 | code, 143 | kbd, 144 | samp { 145 | font-family: monospace, monospace; /* 1 */ 146 | font-size: 1em; /* 2 */ 147 | } 148 | 149 | /** 150 | * Add the correct font style in Android 4.3-. 151 | */ 152 | 153 | dfn { 154 | font-style: italic; 155 | } 156 | 157 | /** 158 | * Add the correct background and color in IE 9-. 159 | */ 160 | 161 | mark { 162 | background-color: #ff0; 163 | color: #000; 164 | } 165 | 166 | /** 167 | * Add the correct font size in all browsers. 168 | */ 169 | 170 | small { 171 | font-size: 80%; 172 | } 173 | 174 | /** 175 | * Prevent `sub` and `sup` elements from affecting the line height in 176 | * all browsers. 177 | */ 178 | 179 | sub, 180 | sup { 181 | font-size: 75%; 182 | line-height: 0; 183 | position: relative; 184 | vertical-align: baseline; 185 | } 186 | 187 | sub { 188 | bottom: -0.25em; 189 | } 190 | 191 | sup { 192 | top: -0.5em; 193 | } 194 | 195 | /* Embedded content 196 | ========================================================================== */ 197 | 198 | /** 199 | * Add the correct display in IE 9-. 200 | */ 201 | 202 | audio, 203 | video { 204 | display: inline-block; 205 | } 206 | 207 | /** 208 | * Add the correct display in iOS 4-7. 209 | */ 210 | 211 | audio:not([controls]) { 212 | display: none; 213 | height: 0; 214 | } 215 | 216 | /** 217 | * Remove the border on images inside links in IE 10-. 218 | */ 219 | 220 | img { 221 | border-style: none; 222 | } 223 | 224 | /** 225 | * Hide the overflow in IE. 226 | */ 227 | 228 | svg:not(:root) { 229 | overflow: hidden; 230 | } 231 | 232 | /* Forms 233 | ========================================================================== */ 234 | 235 | /** 236 | * 1. Change the font styles in all browsers (opinionated). 237 | * 2. Remove the margin in Firefox and Safari. 238 | */ 239 | 240 | button, 241 | input, 242 | optgroup, 243 | select, 244 | textarea { 245 | font-family: sans-serif; /* 1 */ 246 | font-size: 100%; /* 1 */ 247 | line-height: 1.15; /* 1 */ 248 | margin: 0; /* 2 */ 249 | } 250 | 251 | /** 252 | * Show the overflow in IE. 253 | * 1. Show the overflow in Edge. 254 | */ 255 | 256 | button, 257 | input { /* 1 */ 258 | overflow: visible; 259 | } 260 | 261 | /** 262 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 263 | * 1. Remove the inheritance of text transform in Firefox. 264 | */ 265 | 266 | button, 267 | select { /* 1 */ 268 | text-transform: none; 269 | } 270 | 271 | /** 272 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 273 | * controls in Android 4. 274 | * 2. Correct the inability to style clickable types in iOS and Safari. 275 | */ 276 | 277 | button, 278 | html [type="button"], /* 1 */ 279 | [type="reset"], 280 | [type="submit"] { 281 | -webkit-appearance: button; /* 2 */ 282 | } 283 | 284 | /** 285 | * Remove the inner border and padding in Firefox. 286 | */ 287 | 288 | button::-moz-focus-inner, 289 | [type="button"]::-moz-focus-inner, 290 | [type="reset"]::-moz-focus-inner, 291 | [type="submit"]::-moz-focus-inner { 292 | border-style: none; 293 | padding: 0; 294 | } 295 | 296 | /** 297 | * Restore the focus styles unset by the previous rule. 298 | */ 299 | 300 | button:-moz-focusring, 301 | [type="button"]:-moz-focusring, 302 | [type="reset"]:-moz-focusring, 303 | [type="submit"]:-moz-focusring { 304 | outline: 1px dotted ButtonText; 305 | } 306 | 307 | /** 308 | * Correct the padding in Firefox. 309 | */ 310 | 311 | fieldset { 312 | padding: 0.35em 0.75em 0.625em; 313 | } 314 | 315 | /** 316 | * 1. Correct the text wrapping in Edge and IE. 317 | * 2. Correct the color inheritance from `fieldset` elements in IE. 318 | * 3. Remove the padding so developers are not caught out when they zero out 319 | * `fieldset` elements in all browsers. 320 | */ 321 | 322 | legend { 323 | box-sizing: border-box; /* 1 */ 324 | color: inherit; /* 2 */ 325 | display: table; /* 1 */ 326 | max-width: 100%; /* 1 */ 327 | padding: 0; /* 3 */ 328 | white-space: normal; /* 1 */ 329 | } 330 | 331 | /** 332 | * 1. Add the correct display in IE 9-. 333 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. 334 | */ 335 | 336 | progress { 337 | display: inline-block; /* 1 */ 338 | vertical-align: baseline; /* 2 */ 339 | } 340 | 341 | /** 342 | * Remove the default vertical scrollbar in IE. 343 | */ 344 | 345 | textarea { 346 | overflow: auto; 347 | } 348 | 349 | /** 350 | * 1. Add the correct box sizing in IE 10-. 351 | * 2. Remove the padding in IE 10-. 352 | */ 353 | 354 | [type="checkbox"], 355 | [type="radio"] { 356 | box-sizing: border-box; /* 1 */ 357 | padding: 0; /* 2 */ 358 | } 359 | 360 | /** 361 | * Correct the cursor style of increment and decrement buttons in Chrome. 362 | */ 363 | 364 | [type="number"]::-webkit-inner-spin-button, 365 | [type="number"]::-webkit-outer-spin-button { 366 | height: auto; 367 | } 368 | 369 | /** 370 | * 1. Correct the odd appearance in Chrome and Safari. 371 | * 2. Correct the outline style in Safari. 372 | */ 373 | 374 | [type="search"] { 375 | -webkit-appearance: textfield; /* 1 */ 376 | outline-offset: -2px; /* 2 */ 377 | } 378 | 379 | /** 380 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. 381 | */ 382 | 383 | [type="search"]::-webkit-search-cancel-button, 384 | [type="search"]::-webkit-search-decoration { 385 | -webkit-appearance: none; 386 | } 387 | 388 | /** 389 | * 1. Correct the inability to style clickable types in iOS and Safari. 390 | * 2. Change font properties to `inherit` in Safari. 391 | */ 392 | 393 | ::-webkit-file-upload-button { 394 | -webkit-appearance: button; /* 1 */ 395 | font: inherit; /* 2 */ 396 | } 397 | 398 | /* Interactive 399 | ========================================================================== */ 400 | 401 | /* 402 | * Add the correct display in IE 9-. 403 | * 1. Add the correct display in Edge, IE, and Firefox. 404 | */ 405 | 406 | details, /* 1 */ 407 | menu { 408 | display: block; 409 | } 410 | 411 | /* 412 | * Add the correct display in all browsers. 413 | */ 414 | 415 | summary { 416 | display: list-item; 417 | } 418 | 419 | /* Scripting 420 | ========================================================================== */ 421 | 422 | /** 423 | * Add the correct display in IE 9-. 424 | */ 425 | 426 | canvas { 427 | display: inline-block; 428 | } 429 | 430 | /** 431 | * Add the correct display in IE. 432 | */ 433 | 434 | template { 435 | display: none; 436 | } 437 | 438 | /* Hidden 439 | ========================================================================== */ 440 | 441 | /** 442 | * Add the correct display in IE 10-. 443 | */ 444 | 445 | [hidden] { 446 | display: none; 447 | } -------------------------------------------------------------------------------- /session-2/css/reset.css: -------------------------------------------------------------------------------- 1 | /******************* 2 | Box Sizing 3 | *******************/ 4 | html { 5 | box-sizing: border-box; 6 | } 7 | 8 | *, 9 | *::before, 10 | *::after { 11 | box-sizing: inherit; 12 | } 13 | 14 | /**************************** 15 | Generic Margins and Paddings 16 | ****************************/ 17 | body, 18 | h1, 19 | h2, 20 | h3, 21 | h4, 22 | h5, 23 | h6, 24 | ul, 25 | ol, 26 | li, 27 | p, 28 | pre, 29 | blockquote, 30 | figure, 31 | hr { 32 | margin: 0; 33 | padding: 0; 34 | } 35 | 36 | /******************* 37 | Lists 38 | *******************/ 39 | ul { 40 | list-style: none; 41 | } 42 | 43 | /******************* 44 | Forms and buttons 45 | *******************/ 46 | input, 47 | textarea, 48 | select, 49 | button { 50 | color: inherit; 51 | font: inherit; 52 | letter-spacing: inherit; 53 | } 54 | 55 | /* I usually expand input and textarea to full-width */ 56 | input[type="text"], 57 | textarea { 58 | width: 100%; 59 | } 60 | 61 | /* More friendly border */ 62 | input, 63 | textarea, 64 | button { 65 | border: 1px solid gray; 66 | } 67 | 68 | /* Some defaults for one-liner buttons */ 69 | button { 70 | padding: 0.75em 1em; 71 | border-radius: 0; 72 | line-height: 1; 73 | background-color: transparent; 74 | } 75 | 76 | button * { 77 | pointer-events: none; 78 | } 79 | 80 | /*********************************** 81 | Easy responsive for media elements 82 | ***********************************/ 83 | img, 84 | svg, 85 | iframe, 86 | video, 87 | object, 88 | embed { 89 | display: block; 90 | max-width: 100%; 91 | } 92 | 93 | /******************* 94 | Useful table styles 95 | *******************/ 96 | table { 97 | table-layout: fixed; 98 | width: 100%; 99 | } 100 | 101 | /******************* 102 | The hidden attribute 103 | *******************/ 104 | [hidden] { 105 | display: none !important; 106 | } 107 | 108 | /******************* 109 | Noscript 110 | *******************/ 111 | noscript { 112 | display: block; 113 | margin-bottom: 1em; 114 | margin-top: 1em; 115 | } 116 | 117 | /******************* 118 | Focus 119 | *******************/ 120 | [tabindex="-1"] { 121 | outline: none !important; 122 | } 123 | -------------------------------------------------------------------------------- /session-2/css/styles.css: -------------------------------------------------------------------------------- 1 | /** 2 | * base styles and typography 3 | * --------------- 4 | */ 5 | :root { 6 | --orange-050: #ffe8d9; 7 | --orange-100: #ffd0b5; 8 | --orange-200: #ffb088; 9 | --orange-300: #ff9466; 10 | --orange-400: #f9703e; 11 | --orange-500: #f35627; 12 | --orange-600: #de3a11; 13 | --orange-700: #c52707; 14 | --orange-800: #ad1d07; 15 | --orange-900: #841003; 16 | 17 | --grey-050: #f5f7fa; 18 | --grey-100: #e4e7eb; 19 | --grey-200: #cbd2d9; 20 | --grey-300: #9aa5b1; 21 | --grey-400: #7b8794; 22 | --grey-500: #616e7c; 23 | --grey-600: #52606d; 24 | --grey-700: #3e4c59; 25 | --grey-800: #323f4b; 26 | --grey-900: #1f2933; 27 | } 28 | 29 | /******************* 30 | Base styles 31 | *******************/ 32 | html { 33 | font-size: 150%; 34 | font-weight: 300; 35 | font-family: "Roboto", Helvetica, Arial, sans-serif; 36 | line-height: 1.4; 37 | } 38 | 39 | body { 40 | display: flex; 41 | background-image: linear-gradient(236deg, #74ebd5, #acb6e5); 42 | justify-content: center; 43 | align-items: center; 44 | height: 100vh; 45 | } 46 | 47 | /******************* 48 | Calculator 49 | *******************/ 50 | .calculator { 51 | box-shadow: 0 0 25px 0 rgba(0, 0, 0, 0.3); 52 | border-radius: 0.5em; 53 | overflow: hidden; 54 | } 55 | 56 | .calculator__display { 57 | background-color: var(--grey-900); 58 | color: var(--grey-050); 59 | width: 16.25rem; 60 | padding: 0.75rem 1rem; 61 | text-align: right; 62 | font-size: calc(1rem * 1.2 * 1.2); 63 | } 64 | 65 | .calculator__keys { 66 | background: var(--grey-200); 67 | display: grid; 68 | grid-gap: 2px; 69 | grid-template-columns: repeat(4, auto); 70 | grid-template-areas: 71 | ". . . ." 72 | "seven eight nine equal" 73 | "four five six equal" 74 | "one two three equal" 75 | "zero decimal clear equal"; 76 | } 77 | 78 | .calculator__keys > button { 79 | border: 0; 80 | } 81 | 82 | .one { 83 | grid-area: one; 84 | } 85 | .two { 86 | grid-area: two; 87 | } 88 | .three { 89 | grid-area: three; 90 | } 91 | .four { 92 | grid-area: four; 93 | } 94 | .five { 95 | grid-area: five; 96 | } 97 | .six { 98 | grid-area: six; 99 | } 100 | .seven { 101 | grid-area: seven; 102 | } 103 | .eight { 104 | grid-area: eight; 105 | } 106 | .nine { 107 | grid-area: nine; 108 | } 109 | .zero { 110 | grid-area: zero; 111 | } 112 | .decimal { 113 | grid-area: decimal; 114 | } 115 | .clear { 116 | grid-area: clear; 117 | } 118 | .equal { 119 | grid-area: equal; 120 | background-color: var(--orange-400); 121 | } 122 | 123 | .equal:active { 124 | background-color: var(--orange-500); 125 | } 126 | 127 | [data-type="operator"] { 128 | background: var(--grey-100); 129 | } 130 | 131 | [data-type="number"] { 132 | background: #fff; 133 | } 134 | 135 | [data-type="operator"]:active, 136 | [data-type="number"]:active { 137 | background: var(--grey-200); 138 | } 139 | 140 | [data-state="selected"] { 141 | background: var(--grey-200); 142 | } 143 | -------------------------------------------------------------------------------- /session-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Calculator 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |
0
23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 |
44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /session-2/js/main.js: -------------------------------------------------------------------------------- 1 | // Start writing JavaScript here! 2 | const calculator = document.querySelector('.calculator') 3 | const keys = calculator.querySelector('.calculator__keys') 4 | const display = calculator.querySelector('.calculator__display') 5 | 6 | keys.addEventListener('click', event => { 7 | if (!event.target.closest('button')) return 8 | 9 | const key = event.target 10 | const keyValue = key.textContent 11 | const displayValue = display.textContent 12 | const { type } = key.dataset 13 | const { previousKeyType } = calculator.dataset 14 | 15 | if (type === 'number') { 16 | if ( 17 | displayValue === '0' || 18 | previousKeyType === 'operator' 19 | ) { 20 | display.textContent = keyValue 21 | } else { 22 | display.textContent = displayValue + keyValue 23 | } 24 | } 25 | 26 | if (type === 'operator') { 27 | const operatorKeys = keys.querySelectorAll('[data-type="operator"]') 28 | operatorKeys.forEach(el => { el.dataset.state = '' }) 29 | key.dataset.state = 'selected' 30 | 31 | calculator.dataset.firstNumber = displayValue 32 | calculator.dataset.operator = key.dataset.key 33 | } 34 | 35 | if (type === 'equal') { 36 | // Perform a calculation 37 | const firstNumber = calculator.dataset.firstNumber 38 | const operator = calculator.dataset.operator 39 | const secondNumber = displayValue 40 | display.textContent = calculate(firstNumber, operator, secondNumber) 41 | } 42 | 43 | calculator.dataset.previousKeyType = type 44 | }) 45 | 46 | function calculate (firstNumber, operator, secondNumber) { 47 | firstNumber = parseInt(firstNumber) 48 | secondNumber = parseInt(secondNumber) 49 | 50 | if (operator === 'plus') return firstNumber + secondNumber 51 | if (operator === 'minus') return firstNumber - secondNumber 52 | if (operator === 'times') return firstNumber * secondNumber 53 | if (operator === 'divide') return firstNumber / secondNumber 54 | } 55 | -------------------------------------------------------------------------------- /session-3/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in 9 | * IE on Windows Phone and in iOS. 10 | */ 11 | 12 | html { 13 | line-height: 1.15; /* 1 */ 14 | -ms-text-size-adjust: 100%; /* 2 */ 15 | -webkit-text-size-adjust: 100%; /* 2 */ 16 | } 17 | 18 | /* Sections 19 | ========================================================================== */ 20 | 21 | /** 22 | * Remove the margin in all browsers (opinionated). 23 | */ 24 | 25 | body { 26 | margin: 0; 27 | } 28 | 29 | /** 30 | * Add the correct display in IE 9-. 31 | */ 32 | 33 | article, 34 | aside, 35 | footer, 36 | header, 37 | nav, 38 | section { 39 | display: block; 40 | } 41 | 42 | /** 43 | * Correct the font size and margin on `h1` elements within `section` and 44 | * `article` contexts in Chrome, Firefox, and Safari. 45 | */ 46 | 47 | h1 { 48 | font-size: 2em; 49 | margin: 0.67em 0; 50 | } 51 | 52 | /* Grouping content 53 | ========================================================================== */ 54 | 55 | /** 56 | * Add the correct display in IE 9-. 57 | * 1. Add the correct display in IE. 58 | */ 59 | 60 | figcaption, 61 | figure, 62 | main { /* 1 */ 63 | display: block; 64 | } 65 | 66 | /** 67 | * Add the correct margin in IE 8. 68 | */ 69 | 70 | figure { 71 | margin: 1em 40px; 72 | } 73 | 74 | /** 75 | * 1. Add the correct box sizing in Firefox. 76 | * 2. Show the overflow in Edge and IE. 77 | */ 78 | 79 | hr { 80 | box-sizing: content-box; /* 1 */ 81 | height: 0; /* 1 */ 82 | overflow: visible; /* 2 */ 83 | } 84 | 85 | /** 86 | * 1. Correct the inheritance and scaling of font size in all browsers. 87 | * 2. Correct the odd `em` font sizing in all browsers. 88 | */ 89 | 90 | pre { 91 | font-family: monospace, monospace; /* 1 */ 92 | font-size: 1em; /* 2 */ 93 | } 94 | 95 | /* Text-level semantics 96 | ========================================================================== */ 97 | 98 | /** 99 | * 1. Remove the gray background on active links in IE 10. 100 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 101 | */ 102 | 103 | a { 104 | background-color: transparent; /* 1 */ 105 | -webkit-text-decoration-skip: objects; /* 2 */ 106 | } 107 | 108 | /** 109 | * 1. Remove the bottom border in Chrome 57- and Firefox 39-. 110 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 111 | */ 112 | 113 | abbr[title] { 114 | border-bottom: none; /* 1 */ 115 | text-decoration: underline; /* 2 */ 116 | text-decoration: underline dotted; /* 2 */ 117 | } 118 | 119 | /** 120 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 121 | */ 122 | 123 | b, 124 | strong { 125 | font-weight: inherit; 126 | } 127 | 128 | /** 129 | * Add the correct font weight in Chrome, Edge, and Safari. 130 | */ 131 | 132 | b, 133 | strong { 134 | font-weight: bolder; 135 | } 136 | 137 | /** 138 | * 1. Correct the inheritance and scaling of font size in all browsers. 139 | * 2. Correct the odd `em` font sizing in all browsers. 140 | */ 141 | 142 | code, 143 | kbd, 144 | samp { 145 | font-family: monospace, monospace; /* 1 */ 146 | font-size: 1em; /* 2 */ 147 | } 148 | 149 | /** 150 | * Add the correct font style in Android 4.3-. 151 | */ 152 | 153 | dfn { 154 | font-style: italic; 155 | } 156 | 157 | /** 158 | * Add the correct background and color in IE 9-. 159 | */ 160 | 161 | mark { 162 | background-color: #ff0; 163 | color: #000; 164 | } 165 | 166 | /** 167 | * Add the correct font size in all browsers. 168 | */ 169 | 170 | small { 171 | font-size: 80%; 172 | } 173 | 174 | /** 175 | * Prevent `sub` and `sup` elements from affecting the line height in 176 | * all browsers. 177 | */ 178 | 179 | sub, 180 | sup { 181 | font-size: 75%; 182 | line-height: 0; 183 | position: relative; 184 | vertical-align: baseline; 185 | } 186 | 187 | sub { 188 | bottom: -0.25em; 189 | } 190 | 191 | sup { 192 | top: -0.5em; 193 | } 194 | 195 | /* Embedded content 196 | ========================================================================== */ 197 | 198 | /** 199 | * Add the correct display in IE 9-. 200 | */ 201 | 202 | audio, 203 | video { 204 | display: inline-block; 205 | } 206 | 207 | /** 208 | * Add the correct display in iOS 4-7. 209 | */ 210 | 211 | audio:not([controls]) { 212 | display: none; 213 | height: 0; 214 | } 215 | 216 | /** 217 | * Remove the border on images inside links in IE 10-. 218 | */ 219 | 220 | img { 221 | border-style: none; 222 | } 223 | 224 | /** 225 | * Hide the overflow in IE. 226 | */ 227 | 228 | svg:not(:root) { 229 | overflow: hidden; 230 | } 231 | 232 | /* Forms 233 | ========================================================================== */ 234 | 235 | /** 236 | * 1. Change the font styles in all browsers (opinionated). 237 | * 2. Remove the margin in Firefox and Safari. 238 | */ 239 | 240 | button, 241 | input, 242 | optgroup, 243 | select, 244 | textarea { 245 | font-family: sans-serif; /* 1 */ 246 | font-size: 100%; /* 1 */ 247 | line-height: 1.15; /* 1 */ 248 | margin: 0; /* 2 */ 249 | } 250 | 251 | /** 252 | * Show the overflow in IE. 253 | * 1. Show the overflow in Edge. 254 | */ 255 | 256 | button, 257 | input { /* 1 */ 258 | overflow: visible; 259 | } 260 | 261 | /** 262 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 263 | * 1. Remove the inheritance of text transform in Firefox. 264 | */ 265 | 266 | button, 267 | select { /* 1 */ 268 | text-transform: none; 269 | } 270 | 271 | /** 272 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 273 | * controls in Android 4. 274 | * 2. Correct the inability to style clickable types in iOS and Safari. 275 | */ 276 | 277 | button, 278 | html [type="button"], /* 1 */ 279 | [type="reset"], 280 | [type="submit"] { 281 | -webkit-appearance: button; /* 2 */ 282 | } 283 | 284 | /** 285 | * Remove the inner border and padding in Firefox. 286 | */ 287 | 288 | button::-moz-focus-inner, 289 | [type="button"]::-moz-focus-inner, 290 | [type="reset"]::-moz-focus-inner, 291 | [type="submit"]::-moz-focus-inner { 292 | border-style: none; 293 | padding: 0; 294 | } 295 | 296 | /** 297 | * Restore the focus styles unset by the previous rule. 298 | */ 299 | 300 | button:-moz-focusring, 301 | [type="button"]:-moz-focusring, 302 | [type="reset"]:-moz-focusring, 303 | [type="submit"]:-moz-focusring { 304 | outline: 1px dotted ButtonText; 305 | } 306 | 307 | /** 308 | * Correct the padding in Firefox. 309 | */ 310 | 311 | fieldset { 312 | padding: 0.35em 0.75em 0.625em; 313 | } 314 | 315 | /** 316 | * 1. Correct the text wrapping in Edge and IE. 317 | * 2. Correct the color inheritance from `fieldset` elements in IE. 318 | * 3. Remove the padding so developers are not caught out when they zero out 319 | * `fieldset` elements in all browsers. 320 | */ 321 | 322 | legend { 323 | box-sizing: border-box; /* 1 */ 324 | color: inherit; /* 2 */ 325 | display: table; /* 1 */ 326 | max-width: 100%; /* 1 */ 327 | padding: 0; /* 3 */ 328 | white-space: normal; /* 1 */ 329 | } 330 | 331 | /** 332 | * 1. Add the correct display in IE 9-. 333 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. 334 | */ 335 | 336 | progress { 337 | display: inline-block; /* 1 */ 338 | vertical-align: baseline; /* 2 */ 339 | } 340 | 341 | /** 342 | * Remove the default vertical scrollbar in IE. 343 | */ 344 | 345 | textarea { 346 | overflow: auto; 347 | } 348 | 349 | /** 350 | * 1. Add the correct box sizing in IE 10-. 351 | * 2. Remove the padding in IE 10-. 352 | */ 353 | 354 | [type="checkbox"], 355 | [type="radio"] { 356 | box-sizing: border-box; /* 1 */ 357 | padding: 0; /* 2 */ 358 | } 359 | 360 | /** 361 | * Correct the cursor style of increment and decrement buttons in Chrome. 362 | */ 363 | 364 | [type="number"]::-webkit-inner-spin-button, 365 | [type="number"]::-webkit-outer-spin-button { 366 | height: auto; 367 | } 368 | 369 | /** 370 | * 1. Correct the odd appearance in Chrome and Safari. 371 | * 2. Correct the outline style in Safari. 372 | */ 373 | 374 | [type="search"] { 375 | -webkit-appearance: textfield; /* 1 */ 376 | outline-offset: -2px; /* 2 */ 377 | } 378 | 379 | /** 380 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. 381 | */ 382 | 383 | [type="search"]::-webkit-search-cancel-button, 384 | [type="search"]::-webkit-search-decoration { 385 | -webkit-appearance: none; 386 | } 387 | 388 | /** 389 | * 1. Correct the inability to style clickable types in iOS and Safari. 390 | * 2. Change font properties to `inherit` in Safari. 391 | */ 392 | 393 | ::-webkit-file-upload-button { 394 | -webkit-appearance: button; /* 1 */ 395 | font: inherit; /* 2 */ 396 | } 397 | 398 | /* Interactive 399 | ========================================================================== */ 400 | 401 | /* 402 | * Add the correct display in IE 9-. 403 | * 1. Add the correct display in Edge, IE, and Firefox. 404 | */ 405 | 406 | details, /* 1 */ 407 | menu { 408 | display: block; 409 | } 410 | 411 | /* 412 | * Add the correct display in all browsers. 413 | */ 414 | 415 | summary { 416 | display: list-item; 417 | } 418 | 419 | /* Scripting 420 | ========================================================================== */ 421 | 422 | /** 423 | * Add the correct display in IE 9-. 424 | */ 425 | 426 | canvas { 427 | display: inline-block; 428 | } 429 | 430 | /** 431 | * Add the correct display in IE. 432 | */ 433 | 434 | template { 435 | display: none; 436 | } 437 | 438 | /* Hidden 439 | ========================================================================== */ 440 | 441 | /** 442 | * Add the correct display in IE 10-. 443 | */ 444 | 445 | [hidden] { 446 | display: none; 447 | } -------------------------------------------------------------------------------- /session-3/css/reset.css: -------------------------------------------------------------------------------- 1 | /******************* 2 | Box Sizing 3 | *******************/ 4 | html { 5 | box-sizing: border-box; 6 | } 7 | 8 | *, 9 | *::before, 10 | *::after { 11 | box-sizing: inherit; 12 | } 13 | 14 | /**************************** 15 | Generic Margins and Paddings 16 | ****************************/ 17 | body, 18 | h1, 19 | h2, 20 | h3, 21 | h4, 22 | h5, 23 | h6, 24 | ul, 25 | ol, 26 | li, 27 | p, 28 | pre, 29 | blockquote, 30 | figure, 31 | hr { 32 | margin: 0; 33 | padding: 0; 34 | } 35 | 36 | /******************* 37 | Lists 38 | *******************/ 39 | ul { 40 | list-style: none; 41 | } 42 | 43 | /******************* 44 | Forms and buttons 45 | *******************/ 46 | input, 47 | textarea, 48 | select, 49 | button { 50 | color: inherit; 51 | font: inherit; 52 | letter-spacing: inherit; 53 | } 54 | 55 | /* I usually expand input and textarea to full-width */ 56 | input[type="text"], 57 | textarea { 58 | width: 100%; 59 | } 60 | 61 | /* More friendly border */ 62 | input, 63 | textarea, 64 | button { 65 | border: 1px solid gray; 66 | } 67 | 68 | /* Some defaults for one-liner buttons */ 69 | button { 70 | padding: 0.75em 1em; 71 | border-radius: 0; 72 | line-height: 1; 73 | background-color: transparent; 74 | } 75 | 76 | button * { 77 | pointer-events: none; 78 | } 79 | 80 | /*********************************** 81 | Easy responsive for media elements 82 | ***********************************/ 83 | img, 84 | svg, 85 | iframe, 86 | video, 87 | object, 88 | embed { 89 | display: block; 90 | max-width: 100%; 91 | } 92 | 93 | /******************* 94 | Useful table styles 95 | *******************/ 96 | table { 97 | table-layout: fixed; 98 | width: 100%; 99 | } 100 | 101 | /******************* 102 | The hidden attribute 103 | *******************/ 104 | [hidden] { 105 | display: none !important; 106 | } 107 | 108 | /******************* 109 | Noscript 110 | *******************/ 111 | noscript { 112 | display: block; 113 | margin-bottom: 1em; 114 | margin-top: 1em; 115 | } 116 | 117 | /******************* 118 | Focus 119 | *******************/ 120 | [tabindex="-1"] { 121 | outline: none !important; 122 | } 123 | -------------------------------------------------------------------------------- /session-3/css/styles.css: -------------------------------------------------------------------------------- 1 | /** 2 | * base styles and typography 3 | * --------------- 4 | */ 5 | :root { 6 | --orange-050: #ffe8d9; 7 | --orange-100: #ffd0b5; 8 | --orange-200: #ffb088; 9 | --orange-300: #ff9466; 10 | --orange-400: #f9703e; 11 | --orange-500: #f35627; 12 | --orange-600: #de3a11; 13 | --orange-700: #c52707; 14 | --orange-800: #ad1d07; 15 | --orange-900: #841003; 16 | 17 | --grey-050: #f5f7fa; 18 | --grey-100: #e4e7eb; 19 | --grey-200: #cbd2d9; 20 | --grey-300: #9aa5b1; 21 | --grey-400: #7b8794; 22 | --grey-500: #616e7c; 23 | --grey-600: #52606d; 24 | --grey-700: #3e4c59; 25 | --grey-800: #323f4b; 26 | --grey-900: #1f2933; 27 | } 28 | 29 | /******************* 30 | Base styles 31 | *******************/ 32 | html { 33 | font-size: 150%; 34 | font-weight: 300; 35 | font-family: "Roboto", Helvetica, Arial, sans-serif; 36 | line-height: 1.4; 37 | } 38 | 39 | body { 40 | display: flex; 41 | background-image: linear-gradient(236deg, #74ebd5, #acb6e5); 42 | justify-content: center; 43 | align-items: center; 44 | height: 100vh; 45 | } 46 | 47 | /******************* 48 | Calculator 49 | *******************/ 50 | .calculator { 51 | box-shadow: 0 0 25px 0 rgba(0, 0, 0, 0.3); 52 | border-radius: 0.5em; 53 | overflow: hidden; 54 | } 55 | 56 | .calculator__display { 57 | background-color: var(--grey-900); 58 | color: var(--grey-050); 59 | width: 16.25rem; 60 | padding: 0.75rem 1rem; 61 | text-align: right; 62 | font-size: calc(1rem * 1.2 * 1.2); 63 | } 64 | 65 | .calculator__keys { 66 | background: var(--grey-200); 67 | display: grid; 68 | grid-gap: 2px; 69 | grid-template-columns: repeat(4, auto); 70 | grid-template-areas: 71 | ". . . ." 72 | "seven eight nine equal" 73 | "four five six equal" 74 | "one two three equal" 75 | "zero decimal clear equal"; 76 | } 77 | 78 | .calculator__keys > button { 79 | border: 0; 80 | } 81 | 82 | [data-key="1"] { 83 | grid-area: one; 84 | } 85 | 86 | [data-key="2"] { 87 | grid-area: two; 88 | } 89 | 90 | [data-key="3"] { 91 | grid-area: three; 92 | } 93 | 94 | [data-key="4"] { 95 | grid-area: four; 96 | } 97 | 98 | [data-key="5"] { 99 | grid-area: five; 100 | } 101 | 102 | [data-key="6"] { 103 | grid-area: six; 104 | } 105 | 106 | [data-key="7"] { 107 | grid-area: seven; 108 | } 109 | 110 | [data-key="8"] { 111 | grid-area: eight; 112 | } 113 | 114 | [data-key="9"] { 115 | grid-area: nine; 116 | } 117 | 118 | [data-key="0"] { 119 | grid-area: zero; 120 | } 121 | .decimal { 122 | grid-area: decimal; 123 | } 124 | .clear { 125 | grid-area: clear; 126 | } 127 | 128 | [data-key="equal"] { 129 | grid-area: equal; 130 | background-color: var(--orange-400); 131 | } 132 | 133 | [data-key="equal"]:active { 134 | background-color: var(--orange-500); 135 | } 136 | 137 | [data-type="operator"] { 138 | background: var(--grey-100); 139 | } 140 | 141 | [data-type="number"], 142 | [data-type="clear"] { 143 | background: #fff; 144 | } 145 | 146 | [data-type="operator"]:active, 147 | [data-type="number"]:active, 148 | [data-type="clear"]:active { 149 | background: var(--grey-200); 150 | } 151 | 152 | [data-state="selected"] { 153 | background: var(--grey-200); 154 | } 155 | -------------------------------------------------------------------------------- /session-3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Calculator 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |
0
23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 |
44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /session-3/js/main.js: -------------------------------------------------------------------------------- 1 | // Start writing JavaScript here! 2 | const calculator = document.querySelector('.calculator') 3 | const keys = calculator.querySelector('.calculator__keys') 4 | const display = calculator.querySelector('.calculator__display') 5 | const operatorKeys = keys.querySelectorAll('[data-type="operator"]') 6 | 7 | keys.addEventListener('click', event => { 8 | if (!event.target.closest('button')) return 9 | 10 | const key = event.target 11 | const keyValue = key.textContent 12 | const displayValue = display.textContent 13 | const { type } = key.dataset 14 | const { previousKeyType } = calculator.dataset 15 | 16 | if (type === 'number') { 17 | if ( 18 | displayValue === '0' || 19 | previousKeyType === 'operator' 20 | ) { 21 | display.textContent = keyValue 22 | } else { 23 | display.textContent = displayValue + keyValue 24 | } 25 | } 26 | 27 | if (type === 'operator') { 28 | operatorKeys.forEach(el => { el.dataset.state = '' }) 29 | key.dataset.state = 'selected' 30 | 31 | calculator.dataset.firstNumber = displayValue 32 | calculator.dataset.operator = key.dataset.key 33 | } 34 | 35 | if (type === 'equal') { 36 | // Perform a calculation 37 | const firstNumber = calculator.dataset.firstNumber 38 | const operator = calculator.dataset.operator 39 | const secondNumber = displayValue 40 | display.textContent = calculate(firstNumber, operator, secondNumber) 41 | } 42 | 43 | if (type === 'clear') { 44 | display.textContent = '0' 45 | delete calculator.dataset.firstNumber 46 | delete calculator.dataset.operator 47 | } 48 | 49 | calculator.dataset.previousKeyType = type 50 | }) 51 | 52 | function calculate (firstNumber, operator, secondNumber) { 53 | firstNumber = parseInt(firstNumber) 54 | secondNumber = parseInt(secondNumber) 55 | 56 | if (operator === 'plus') return firstNumber + secondNumber 57 | if (operator === 'minus') return firstNumber - secondNumber 58 | if (operator === 'times') return firstNumber * secondNumber 59 | if (operator === 'divide') return firstNumber / secondNumber 60 | } 61 | 62 | // ======================== 63 | // TESTING 64 | // ======================== 65 | function clearCalculator () { 66 | // Press the clear key 67 | const clearKey = document.querySelector('[data-type="clear"]') 68 | clearKey.click() 69 | 70 | // Clear operator states 71 | operatorKeys.forEach(key => { key.dataset.state = '' }) 72 | } 73 | 74 | function testClearKey () { 75 | clearCalculator() 76 | console.assert(display.textContent === '0', 'Clear key. Display should be 0') 77 | console.assert(!calculator.dataset.firstNumber, 'Clear key. No first number remains') 78 | console.assert(!calculator.dataset.operator, 'Clear key. No operator remains') 79 | } 80 | 81 | function testKeySequence (test) { 82 | // Press keys 83 | test.keys.forEach(key => { 84 | document.querySelector(`[data-key="${key}"]`).click() 85 | }) 86 | 87 | // Assertion 88 | console.assert(display.textContent === test.value, test.message) 89 | 90 | // Clear calculator 91 | clearCalculator() 92 | testClearKey() 93 | } 94 | 95 | const tests = [{ 96 | keys: ['1'], 97 | value: '1', 98 | message: 'Click 1' 99 | }, { 100 | keys: ['1', '5'], 101 | value: '15', 102 | message: 'Click 15' 103 | }, { 104 | keys: ['1', '5', '9'], 105 | value: '159', 106 | message: 'Click 159' 107 | }, { 108 | keys: ['2', '4', 'plus', '7', 'equal'], 109 | value: '31', 110 | message: 'Calculation with plus' 111 | }, { 112 | keys: ['3', 'minus', '7', '0', 'equal'], 113 | value: '-67', 114 | message: 'Calculation with minus' 115 | }, { 116 | keys: ['1', '5', 'times', '9', 'equal'], 117 | value: '135', 118 | message: 'Calculation with times' 119 | }, { 120 | keys: ['9', 'divide', '3', 'equal'], 121 | value: '3', 122 | message: 'Calculation with divide' 123 | }, { 124 | keys: ['9', 'divide', '0', 'equal'], 125 | value: 'Infinity', 126 | message: 'Calculation. Divide by 0' 127 | }] 128 | 129 | tests.forEach(testKeySequence) 130 | --------------------------------------------------------------------------------