├── 00-template ├── 00.css └── 00.html ├── 01-anchor ├── 01-scrolling.css ├── 01-scrolling.html ├── 02-carousel.css ├── 02-carousel.html └── 03-anchor.html ├── 02-target ├── 01-carousel.css ├── 01-carousel.html ├── 02-zoom.css └── 02-zoom.html ├── 03-map ├── 01-map.css └── 01-map.html ├── 04-mouse ├── 01-button.css ├── 01-button.html ├── 02-anchor.css ├── 02-anchor.html ├── 03-product.css ├── 03-product.html ├── 04-product-grid.css └── 04-product-grid.html ├── 05-attribute ├── 01-content.css ├── 01-content.html ├── 02-links.css ├── 02-links.html ├── 04-progress.css └── 04-progress.html ├── 06-input ├── 00-input-styling.css ├── 00-input-styling.html ├── 01-input.css └── 01-input.html ├── 07-calc ├── 00-clock-analogue.css ├── 00-clock-analogue.html ├── 00-clock-digital.css ├── 00-clock-digital.html ├── 01-grid-2.css ├── 01-grid-2.html ├── 01-grid.css └── 01-grid.html ├── 08-count ├── 01-list.css ├── 01-list.html ├── 02-calories.css ├── 02-calories.html ├── 03-basket.css └── 03-basket.html ├── 09-input-hack ├── 01-checkbox.css ├── 01-checkbox.html ├── 02-modal.css ├── 02-modal.html ├── 03-checkbox-accordion.css ├── 03-checkbox-accordion.html ├── 04-radio-accordion.css ├── 04-radio-accordion.html ├── 05-focus-accordion.css ├── 05-focus-accordion.html ├── 06-tabs.css ├── 06-tabs.html ├── 07-ratings.css └── 07-ratings.html ├── README.md ├── assets ├── camera.png ├── car1.jpg ├── car2.jpg ├── car3.jpg ├── car4.jpg ├── car5.jpg ├── desk.jpeg ├── download.png ├── fb.png ├── new-window.png ├── pdf.png ├── star-grey.svg └── star-yellow.svg ├── base.css └── style.css /00-template/00.css: -------------------------------------------------------------------------------- 1 | style { 2 | display: block; 3 | } 4 | -------------------------------------------------------------------------------- /00-template/00.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |

Hello

15 |

You can use me as a template

16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /01-anchor/01-scrolling.css: -------------------------------------------------------------------------------- 1 | html { 2 | scroll-behavior: smooth; 3 | } 4 | 5 | #to-top { 6 | position: fixed; 7 | bottom: 10px; 8 | left: 10px; 9 | padding: 10px 20px; 10 | background-color: var(--dark-blue); 11 | color: white; 12 | font-size: 14px; 13 | font-weight: normal; 14 | text-decoration: none; 15 | border-radius: 20px; 16 | } 17 | 18 | #to-top:hover { 19 | text-decoration: underline; 20 | } 21 | -------------------------------------------------------------------------------- /01-anchor/01-scrolling.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |

The power of anchors

15 | 16 | 20 | 21 |

22 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mattis 23 | justo ex, nec commodo metus pellentesque quis. Suspendisse lobortis eros 24 | elit, nec consequat sem posuere et. Aenean varius facilisis elit, a 25 | mattis ante bibendum a. Ut eu eleifend velit. Donec accumsan placerat 26 | massa quis egestas. Praesent vitae maximus nisl. Nulla ut dui quis purus 27 | tincidunt porta nec id eros. Vivamus in metus quis eros gravida finibus 28 | in sit amet elit. Maecenas eu sagittis augue. Nulla ut dolor et turpis 29 | vestibulum bibendum id at augue. Etiam eu faucibus sem. 30 |

31 | 32 |

33 | Mauris nec magna nisi. Maecenas nec leo ullamcorper tellus eleifend 34 | lobortis. Nulla risus orci, porta non diam vitae, posuere efficitur 35 | risus. Sed lorem dolor, imperdiet quis condimentum in, posuere quis 36 | arcu. Aliquam ex ligula, blandit non elementum non, molestie at metus. 37 | Duis vestibulum facilisis leo bibendum vestibulum. Integer ac justo 38 | augue. Integer mi turpis, porttitor sit amet orci nec, convallis egestas 39 | tortor. Duis convallis sapien ut lorem convallis, nec tristique eros 40 | sodales. Quisque placerat elit vel quam condimentum, quis fermentum 41 | risus elementum. Donec eget tincidunt nisl, nec laoreet massa. Class 42 | aptent taciti sociosqu ad litora torquent per conubia nostra, per 43 | inceptos himenaeos. Vivamus at faucibus ligula. Ut eu rhoncus tellus. 44 |

45 | 46 |

Introduction

47 | 48 |

49 | Aliquam pretium lacus a ex tincidunt, et aliquet magna feugiat. 50 | Suspendisse sagittis condimentum pretium. Aenean a scelerisque arcu, 51 | consequat aliquet felis. Cras dictum nulla nec odio tincidunt faucibus. 52 | Nullam nec fermentum elit. Duis in velit vitae felis euismod dignissim 53 | ullamcorper non nisl. Nullam malesuada faucibus malesuada. Duis sem 54 | velit, viverra et diam tempus, convallis sodales orci. Mauris gravida 55 | eros at lorem varius dignissim. Vivamus nec nibh lorem. 56 |

57 | 58 |

59 | Curabitur aliquet leo mi, non molestie orci mollis ut. Curabitur 60 | pretium, turpis rutrum tempus mattis, ex tellus lobortis sapien, vel 61 | vehicula urna purus ut ex. Sed at nisl sit amet nibh auctor hendrerit 62 | quis non est. Praesent hendrerit dui consectetur nisi lacinia, tincidunt 63 | scelerisque nunc condimentum. Etiam imperdiet nibh sed orci efficitur 64 | auctor. Pellentesque habitant morbi tristique senectus et netus et 65 | malesuada fames ac turpis egestas. Donec scelerisque neque quis lacus 66 | facilisis elementum. Sed nisl justo, vulputate non diam id, ornare 67 | luctus ligula. Praesent metus felis, feugiat non sapien eget, commodo 68 | aliquet risus. Integer congue lacinia nulla, ut vulputate augue. 69 | Suspendisse risus ex, eleifend at velit eget, ultricies hendrerit sem. 70 | Integer sit amet tincidunt erat, sed convallis sem. 71 |

72 | 73 |

Conclusion

74 | 75 |

76 | Nam tristique mi eu lectus rutrum, vel porta magna pharetra. Vestibulum 77 | dictum leo dolor, non sagittis arcu elementum nec. Cras commodo erat sit 78 | amet dolor efficitur, a eleifend libero ultrices. Vivamus facilisis 79 | bibendum posuere. Etiam ornare massa sit amet blandit pharetra. Ut vel 80 | egestas mi. Duis tempor massa elit. Nulla nec neque magna. Vestibulum 81 | posuere facilisis justo, egestas vulputate neque pellentesque sit amet. 82 |

83 | 84 | Back to top 85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /01-anchor/02-carousel.css: -------------------------------------------------------------------------------- 1 | #carousel-container { 2 | height: 350px; 3 | width: 600px; 4 | padding: 0; 5 | overflow-x: scroll; 6 | scroll-snap-type: x mandatory; 7 | scroll-behavior: smooth; 8 | 9 | --slide-count: 5; 10 | } 11 | 12 | #carousel { 13 | width: calc(100% * var(--slide-count)); 14 | display: flex; 15 | } 16 | 17 | #carousel, 18 | .slide { 19 | height: 100%; 20 | list-style: none; 21 | margin: 0; 22 | padding: 0; 23 | } 24 | 25 | .slide { 26 | scroll-snap-align: start; 27 | } 28 | 29 | .slide > img { 30 | width: 100%; 31 | height: 100%; 32 | object-fit: cover; 33 | } 34 | 35 | a { 36 | display: inline-block; 37 | margin: 20px; 38 | } 39 | 40 | nav { 41 | text-align: center; 42 | } 43 | -------------------------------------------------------------------------------- /01-anchor/02-carousel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 31 |
32 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /01-anchor/03-anchor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 |
14 | 49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /02-target/01-carousel.css: -------------------------------------------------------------------------------- 1 | #carousel-container { 2 | height: 350px; 3 | width: 600px; 4 | padding: 0; 5 | overflow: hidden; 6 | } 7 | 8 | #carousel { 9 | position: relative; 10 | } 11 | 12 | #carousel, 13 | .slide { 14 | height: 100%; 15 | list-style: none; 16 | margin: 0; 17 | padding: 0; 18 | } 19 | 20 | .slide { 21 | width: 100%; 22 | position: absolute; 23 | left: 0; 24 | top: 0; 25 | opacity: 0; 26 | transition: opacity 300ms; 27 | } 28 | 29 | .slide > img { 30 | width: 100%; 31 | height: 100%; 32 | object-fit: cover; 33 | } 34 | 35 | .slide:first-child, 36 | .slide:target { 37 | opacity: 1; 38 | } 39 | 40 | a { 41 | display: inline-block; 42 | margin: 20px; 43 | } 44 | 45 | nav { 46 | text-align: center; 47 | } 48 | -------------------------------------------------------------------------------- /02-target/01-carousel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 31 |
32 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /02-target/02-zoom.css: -------------------------------------------------------------------------------- 1 | #carousel-container { 2 | height: 350px; 3 | width: 600px; 4 | padding: 0; 5 | } 6 | 7 | #carousel { 8 | position: relative; 9 | } 10 | 11 | #carousel, 12 | .slide { 13 | height: 100%; 14 | list-style: none; 15 | margin: 0; 16 | padding: 0; 17 | } 18 | 19 | .slide { 20 | width: 100%; 21 | position: absolute; 22 | left: 0; 23 | top: 0; 24 | opacity: 0; 25 | transform: scale(0.5) rotate(-10deg); 26 | filter: blur(20px) brightness(0); 27 | transition: opacity 1s, transform 1s, filter 1s; 28 | pointer-events: none; 29 | } 30 | 31 | .slide > img { 32 | width: 100%; 33 | height: 100%; 34 | object-fit: cover; 35 | } 36 | 37 | .slide:target { 38 | opacity: 1; 39 | transform: scale(1) rotate(0); 40 | filter: blur(0) brightness(1); 41 | } 42 | 43 | .slide:target ~ .slide { 44 | opacity: 0; 45 | transform: scale(1.5) rotate(10deg); 46 | filter: blur(20px) brightness(2); 47 | } 48 | 49 | a { 50 | display: inline-block; 51 | margin: 20px; 52 | } 53 | 54 | nav { 55 | text-align: center; 56 | } 57 | -------------------------------------------------------------------------------- /02-target/02-zoom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 31 |
32 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /03-map/01-map.css: -------------------------------------------------------------------------------- 1 | main { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | } 6 | 7 | area { 8 | outline: 5px solid var(--red); 9 | } 10 | 11 | .popup { 12 | padding: 20px; 13 | background-color: rgba(100, 100, 100, 0.9); 14 | color: white; 15 | font-weight: 100; 16 | font-size: 14px; 17 | position: absolute; 18 | opacity: 0; 19 | transform: scale(0); 20 | transition: opacity 300ms, transform 300ms; 21 | } 22 | 23 | .popup:target { 24 | opacity: 1; 25 | transform: scale(1); 26 | } 27 | 28 | .popup > .close { 29 | position: absolute; 30 | right: -10px; 31 | top: -10px; 32 | background-color: black; 33 | padding: 4px 10px; 34 | } 35 | -------------------------------------------------------------------------------- /03-map/01-map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | headphones 23 | peripherals 30 | stationery 37 | 38 | 39 | 42 | 49 | 54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /04-mouse/01-button.css: -------------------------------------------------------------------------------- 1 | button { 2 | margin: 20px; 3 | color: white; 4 | border-radius: 40px; 5 | transition: background-color 300ms, transform 300ms; 6 | } 7 | 8 | button:hover { 9 | background-color: var(--dark-blue); 10 | transform: scale(1.1); 11 | } 12 | 13 | button:active { 14 | background-color: var(--red); 15 | transform: scale(0.8); 16 | } 17 | -------------------------------------------------------------------------------- /04-mouse/01-button.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /04-mouse/02-anchor.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 20px; 3 | } 4 | 5 | a:link { 6 | color: var(--blue); 7 | text-decoration: none; 8 | } 9 | 10 | a:visited { 11 | color: var(--grey); 12 | } 13 | 14 | a:hover { 15 | text-decoration: underline; 16 | } 17 | 18 | a:active { 19 | color: var(--dark-blue); 20 | } 21 | -------------------------------------------------------------------------------- /04-mouse/02-anchor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 |
15 | Check me out! 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /04-mouse/03-product.css: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | align-items: center; 4 | flex-wrap: wrap; 5 | } 6 | 7 | .product-card { 8 | width: 400px; 9 | height: 400px; 10 | margin: 0 auto; 11 | background-color: white; 12 | box-shadow: 0 0 30px rgba(0, 0, 0, 0.15); 13 | outline: none; 14 | cursor: pointer; 15 | overflow: hidden; 16 | } 17 | 18 | .product-image { 19 | width: 100%; 20 | height: 330px; 21 | background-color: var(--blue); 22 | display: block; 23 | object-fit: contain; 24 | transition: height 300ms, background-color 300ms; 25 | } 26 | 27 | .name { 28 | margin: 10px; 29 | font-size: 36px; 30 | } 31 | 32 | .cart-button { 33 | margin-left: 10px; 34 | } 35 | 36 | .product-card:focus > .product-image { 37 | height: 276px; 38 | background-color: var(--dark-blue); 39 | } 40 | -------------------------------------------------------------------------------- /04-mouse/03-product.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | camera 15 |

Film Camera

16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /04-mouse/04-product-grid.css: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | align-items: center; 4 | } 5 | 6 | .product-card { 7 | width: 400px; 8 | height: 400px; 9 | margin: 0 auto; 10 | background-color: white; 11 | box-shadow: 0 0 30px rgba(0, 0, 0, 0.15); 12 | outline: none; 13 | cursor: pointer; 14 | position: relative; 15 | overflow: hidden; 16 | margin: 20px; 17 | } 18 | 19 | .product-image { 20 | width: 100%; 21 | height: 330px; 22 | background-color: var(--blue); 23 | transition: height 300ms, background-color 300ms; 24 | display: block; 25 | object-fit: contain; 26 | } 27 | 28 | .name { 29 | margin: 10px; 30 | font-size: 36px; 31 | } 32 | 33 | .cart-button { 34 | margin-left: 10px; 35 | width: calc(100% - 20px); 36 | } 37 | 38 | .product-card:focus > .product-image { 39 | background-color: var(--dark-blue); 40 | height: 276px; 41 | } 42 | -------------------------------------------------------------------------------- /04-mouse/04-product-grid.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |

Film Camera

16 | 17 |
18 | 19 |
20 | 21 |

Film Camera

22 | 23 |
24 | 25 |
26 | 27 |

Film Camera

28 | 29 |
30 | 31 |
32 | 33 |

Film Camera

34 | 35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /05-attribute/01-content.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | 5 | p { 6 | text-align: justify; 7 | } 8 | 9 | hr { 10 | border: 0; 11 | background-color: var(--grey); 12 | height: 1px; 13 | margin: 50px; 14 | } 15 | 16 | hr::after { 17 | content: attr(class); 18 | position: absolute; 19 | left: 50%; 20 | transform: translateX(-50%) translateY(-50%); 21 | background-color: white; 22 | color: darkgrey; 23 | padding: 10px; 24 | text-transform: capitalize; 25 | font-style: italic; 26 | } 27 | -------------------------------------------------------------------------------- /05-attribute/01-content.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |

15 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mattis 16 | justo ex, nec commodo metus pellentesque quis. Suspendisse lobortis eros 17 | elit, nec consequat sem posuere et. 18 |

19 | 20 |
21 | 22 |

23 | Mauris nec magna nisi. Maecenas nec leo ullamcorper tellus eleifend 24 | lobortis. Nulla risus orci, porta non diam vitae, posuere efficitur 25 | risus. Sed lorem dolor, imperdiet quis condimentum in, posuere quis 26 | arcu. 27 |

28 | 29 |
30 | 31 |

32 | Aliquam pretium lacus a ex tincidunt, et aliquet magna feugiat. 33 | Suspendisse sagittis condimentum pretium. Aenean a scelerisque arcu, 34 | consequat aliquet felis. Cras dictum nulla nec odio tincidunt faucibus. 35 | Nullam nec fermentum elit. 36 |

37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /05-attribute/02-links.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | 5 | a { 6 | display: inline-block; 7 | position: relative; 8 | margin: 50px; 9 | } 10 | 11 | a::after { 12 | position: absolute; 13 | right: -24px; 14 | top: 6px; 15 | width: 15px; 16 | height: 15px; 17 | background-size: 100%; 18 | } 19 | 20 | a[download]::after { 21 | content: ""; 22 | background-image: url("../assets/download.png"); 23 | } 24 | 25 | a[href$=".pdf"][download]::after { 26 | content: ""; 27 | background-image: url("../assets/pdf.png"); 28 | } 29 | 30 | a[href*="facebook.com"]::after { 31 | content: ""; 32 | background-image: url("../assets/fb.png"); 33 | } 34 | 35 | a[target="_blank"]::after { 36 | content: ""; 37 | background-image: url("../assets/new-window.png"); 38 | } 39 | 40 | a[href^="https://"]::before 41 | { 42 | content: "This link is secure: "; 43 | } 44 | -------------------------------------------------------------------------------- /05-attribute/02-links.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | Download picture
15 | Download PDF
16 | Visit Facebook
17 | webondevices.com 18 | Google.com 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /05-attribute/04-progress.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | 5 | progress { 6 | -webkit-appearance: none; 7 | appearance: none; 8 | position: relative; 9 | width: 100%; 10 | height: 15px; 11 | margin-bottom: 50px; 12 | font-size: 14px; 13 | animation-name: attr(class); 14 | } 15 | 16 | progress::before { 17 | content: attr(title); 18 | position: absolute; 19 | left: 0; 20 | top: 20px; 21 | opacity: 0.4; 22 | } 23 | 24 | progress::after { 25 | position: absolute; 26 | right: 0; 27 | top: 20px; 28 | } 29 | 30 | .percentage::after { 31 | content: attr(value) "0%"; 32 | } 33 | 34 | .steps::after { 35 | content: attr(value) " of " attr(max) " tasks completed"; 36 | } 37 | 38 | progress::-webkit-progress-bar { 39 | background-color: var(--grey); 40 | border-radius: 10px; 41 | overflow: hidden; 42 | } 43 | progress::-webkit-progress-value { 44 | background-color: var(--red); 45 | transition: filter 300ms, width 300ms; 46 | } 47 | 48 | progress[value="1"]::-webkit-progress-value { 49 | filter: hue-rotate(calc(10deg * 1)); 50 | } 51 | progress[value="2"]::-webkit-progress-value { 52 | filter: hue-rotate(calc(10deg * 2)); 53 | } 54 | progress[value="3"]::-webkit-progress-value { 55 | filter: hue-rotate(calc(10deg * 3)); 56 | } 57 | progress[value="4"]::-webkit-progress-value { 58 | filter: hue-rotate(calc(10deg * 4)); 59 | } 60 | progress[value="5"]::-webkit-progress-value { 61 | filter: hue-rotate(calc(10deg * 5)); 62 | } 63 | progress[value="6"]::-webkit-progress-value { 64 | filter: hue-rotate(calc(10deg * 6)); 65 | } 66 | progress[value="7"]::-webkit-progress-value { 67 | filter: hue-rotate(calc(10deg * 7)); 68 | } 69 | progress[value="8"]::-webkit-progress-value { 70 | filter: hue-rotate(calc(10deg * 8)); 71 | } 72 | progress[value="9"]::-webkit-progress-value { 73 | filter: hue-rotate(calc(10deg * 9)); 74 | } 75 | progress[value="10"]::-webkit-progress-value { 76 | filter: hue-rotate(calc(10deg * 10)); 77 | } 78 | -------------------------------------------------------------------------------- /05-attribute/04-progress.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 20 | 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /06-input/00-input-styling.css: -------------------------------------------------------------------------------- 1 | fieldset { 2 | border: none; 3 | padding: 0; 4 | position: relative; 5 | } 6 | 7 | [type="text"] { 8 | font-size: 26px; 9 | border: none; 10 | outline: none; 11 | border-bottom: 3px solid var(--grey); 12 | padding: 5px 0; 13 | transition: border-color 300ms; 14 | } 15 | 16 | [type="text"]:focus { 17 | border-color: black; 18 | } 19 | 20 | [type="text"] + label { 21 | font-size: 26px; 22 | position: absolute; 23 | left: 0; 24 | top: 0; 25 | color: var(--grey); 26 | pointer-events: none; 27 | transform-origin: left; 28 | transition: transform 300ms; 29 | } 30 | 31 | [type="text"]:focus + label, 32 | [type="text"]:not(:placeholder-shown) + label { 33 | transform: scale(0.6) translateY(-40px); 34 | } 35 | 36 | [type="text"]:not(:placeholder-shown):not(:focus):invalid { 37 | border-bottom: 3px solid var(--red); 38 | } 39 | 40 | [type="text"]:not(:placeholder-shown):not(:focus):valid { 41 | border-bottom: 3px solid var(--green); 42 | } 43 | -------------------------------------------------------------------------------- /06-input/00-input-styling.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 22 | 23 |
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /06-input/01-input.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | 5 | fieldset { 6 | border: none; 7 | } 8 | 9 | legend { 10 | font-size: 24px; 11 | font-weight: bold; 12 | } 13 | 14 | input, 15 | button, 16 | label { 17 | display: block; 18 | } 19 | 20 | input { 21 | width: 400px; 22 | height: 30px; 23 | padding: 15px; 24 | font-size: 16px; 25 | outline: none; 26 | border: 2px solid var(--grey); 27 | } 28 | 29 | label { 30 | margin-top: 30px; 31 | } 32 | 33 | .error-message, 34 | .success-message { 35 | display: none; 36 | } 37 | 38 | input:focus { 39 | border: 2px solid black; 40 | } 41 | 42 | input:optional { 43 | background-color: 2px solid var(--yellow); 44 | } 45 | 46 | .error-message { 47 | color: var(--red); 48 | } 49 | 50 | .success-message { 51 | color: var(--green); 52 | } 53 | 54 | input:not(:placeholder-shown):not(:focus):valid { 55 | border: 2px solid var(--green); 56 | } 57 | 58 | input:not(:placeholder-shown):not(:focus):invalid { 59 | border: 2px solid var(--red); 60 | } 61 | 62 | input:not(:placeholder-shown):not(:focus):invalid + .error-message, 63 | input:not(:placeholder-shown):not(:focus):valid 64 | + .error-message 65 | + .success-message { 66 | display: block; 67 | } 68 | 69 | [type="checkbox"] { 70 | width: auto; 71 | } 72 | 73 | [type="submit"] { 74 | width: 150px; 75 | height: 30px; 76 | margin-top: 20px; 77 | border: none; 78 | background-color: var(--blue); 79 | cursor: pointer; 80 | } 81 | 82 | form:invalid [type="submit"] { 83 | background-color: var(--grey); 84 | cursor: not-allowed; 85 | } 86 | 87 | form:invalid [type="submit"]:active { 88 | pointer-events: none; 89 | } 90 | -------------------------------------------------------------------------------- /06-input/01-input.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 | Submit your score 17 | 18 | 19 | 27 | Enter a valid email ending with @gmail.com 30 | Email correct 31 | 32 | 33 | 42 | You haven't reached the minimum score 45 | Congratulations for your excellent score 48 | 49 | 53 | 54 | 55 |
56 |
57 |
58 | 59 | 60 | -------------------------------------------------------------------------------- /07-calc/00-clock-analogue.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --second: 1s; 3 | --minute: calc(var(--second) * 60); 4 | --hour: calc(var(--minute) * 60); 5 | } 6 | 7 | @keyframes rotate { 8 | from { 9 | transform: rotate(0); 10 | } 11 | to { 12 | transform: rotate(1turn); 13 | } 14 | } 15 | 16 | .clock { 17 | --setTimeHour: 14; 18 | --setTimeMinute: 01; 19 | --timeShiftHour: calc(var(--setTimeHour) * var(--hour)); 20 | --timeShiftMinute: calc(var(--setTimeMinute) * var(--minute)); 21 | width: 300px; 22 | height: 300px; 23 | border-radius: 50%; 24 | background-color: var(--grey); 25 | margin: 0 auto; 26 | position: relative; 27 | transform: rotate(180deg); 28 | } 29 | 30 | .hand { 31 | position: absolute; 32 | top: 50%; 33 | left: calc(50% - var(--width) / 2); 34 | width: var(--width); 35 | height: var(--height); 36 | background-color: var(--color); 37 | border-radius: calc(var(--width) / 2); 38 | transform-origin: center 0; 39 | } 40 | 41 | .second { 42 | --width: 5px; 43 | --height: 140px; 44 | --color: var(--yellow); 45 | } 46 | 47 | .minute { 48 | --width: 10px; 49 | --height: 90px; 50 | --color: var(--blue); 51 | } 52 | 53 | .hour { 54 | --width: 10px; 55 | --height: 50px; 56 | --color: var(--dark-blue); 57 | } 58 | 59 | .second.hand { 60 | animation: rotate steps(60) var(--minute) infinite; 61 | } 62 | 63 | .minute.hand { 64 | animation: rotate linear var(--hour) infinite; 65 | animation-delay: calc(var(--timeShiftMinute) * -1); 66 | } 67 | 68 | .hour.hand { 69 | animation: rotate linear calc(var(--hour) * 12) infinite; 70 | animation-delay: calc((var(--timeShiftHour) + var(--timeShiftMinute)) * -1); 71 | } 72 | -------------------------------------------------------------------------------- /07-calc/00-clock-analogue.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /07-calc/00-clock-digital.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --second: 1s; 3 | --minute: calc(var(--second) * 60); 4 | --hour: calc(var(--minute) * 60); 5 | } 6 | 7 | @keyframes tick { 8 | from { 9 | transform: translateY(0); 10 | } 11 | to { 12 | transform: translateY(-100%); 13 | } 14 | } 15 | 16 | @keyframes blink { 17 | from { 18 | content: ":"; 19 | } 20 | to { 21 | content: ""; 22 | } 23 | } 24 | 25 | .clock { 26 | --setTimeHour: 14; 27 | --setTimeMinute: 01; 28 | --timeShiftHour: calc(var(--setTimeHour) * var(--hour)); 29 | --timeShiftMinute: calc(var(--setTimeMinute) * var(--minute)); 30 | width: 150px; 31 | height: 50px; 32 | background-color: var(--grey); 33 | margin: 0 auto; 34 | position: relative; 35 | display: flex; 36 | } 37 | 38 | .section { 39 | position: relative; 40 | width: calc(100% / 3); 41 | overflow: hidden; 42 | } 43 | 44 | .section > ul { 45 | list-style: none; 46 | margin: 0; 47 | padding: 0; 48 | } 49 | 50 | .section > ul > li { 51 | width: 50px; 52 | height: 50px; 53 | font-size: 32px; 54 | text-align: center; 55 | padding-top: 2px; 56 | } 57 | 58 | .hour::after, 59 | .minute::after { 60 | content: ":"; 61 | margin-left: 2px; 62 | position: absolute; 63 | top: 6px; 64 | left: 44px; 65 | font-size: 24px; 66 | } 67 | 68 | .minute::after { 69 | animation: blink var(--second) infinite; 70 | } 71 | 72 | .second > ul { 73 | animation: tick steps(60) var(--minute) infinite; 74 | } 75 | 76 | .minute > ul { 77 | animation: tick steps(60) var(--hour) infinite; 78 | animation-delay: calc(var(--timeShiftMinute) * -1); 79 | } 80 | 81 | .hour > ul { 82 | animation: tick steps(24) calc(24 * var(--hour)) infinite; 83 | animation-delay: calc(var(--timeShiftHour) * -1); 84 | } 85 | -------------------------------------------------------------------------------- /07-calc/00-clock-digital.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
    17 |
  • 00
  • 18 |
  • 01
  • 19 |
  • 02
  • 20 |
  • 03
  • 21 |
  • 04
  • 22 |
  • 05
  • 23 |
  • 06
  • 24 |
  • 07
  • 25 |
  • 08
  • 26 |
  • 09
  • 27 |
  • 10
  • 28 |
  • 11
  • 29 |
  • 12
  • 30 |
  • 13
  • 31 |
  • 14
  • 32 |
  • 15
  • 33 |
  • 16
  • 34 |
  • 17
  • 35 |
  • 18
  • 36 |
  • 19
  • 37 |
  • 20
  • 38 |
  • 21
  • 39 |
  • 22
  • 40 |
  • 23
  • 41 |
42 |
43 |
44 |
    45 |
  • 00
  • 46 |
  • 01
  • 47 |
  • 02
  • 48 |
  • 03
  • 49 |
  • 04
  • 50 |
  • 05
  • 51 |
  • 06
  • 52 |
  • 07
  • 53 |
  • 08
  • 54 |
  • 09
  • 55 |
  • 10
  • 56 |
  • 11
  • 57 |
  • 12
  • 58 |
  • 13
  • 59 |
  • 14
  • 60 |
  • 15
  • 61 |
  • 16
  • 62 |
  • 17
  • 63 |
  • 18
  • 64 |
  • 19
  • 65 |
  • 20
  • 66 |
  • 21
  • 67 |
  • 22
  • 68 |
  • 23
  • 69 |
  • 24
  • 70 |
  • 25
  • 71 |
  • 26
  • 72 |
  • 27
  • 73 |
  • 28
  • 74 |
  • 29
  • 75 |
  • 30
  • 76 |
  • 31
  • 77 |
  • 32
  • 78 |
  • 33
  • 79 |
  • 34
  • 80 |
  • 35
  • 81 |
  • 36
  • 82 |
  • 37
  • 83 |
  • 38
  • 84 |
  • 39
  • 85 |
  • 40
  • 86 |
  • 41
  • 87 |
  • 42
  • 88 |
  • 43
  • 89 |
  • 44
  • 90 |
  • 45
  • 91 |
  • 46
  • 92 |
  • 47
  • 93 |
  • 48
  • 94 |
  • 49
  • 95 |
  • 50
  • 96 |
  • 51
  • 97 |
  • 52
  • 98 |
  • 53
  • 99 |
  • 54
  • 100 |
  • 55
  • 101 |
  • 56
  • 102 |
  • 57
  • 103 |
  • 58
  • 104 |
  • 59
  • 105 |
106 |
107 |
108 |
    109 |
  • 00
  • 110 |
  • 01
  • 111 |
  • 02
  • 112 |
  • 03
  • 113 |
  • 04
  • 114 |
  • 05
  • 115 |
  • 06
  • 116 |
  • 07
  • 117 |
  • 08
  • 118 |
  • 09
  • 119 |
  • 10
  • 120 |
  • 11
  • 121 |
  • 12
  • 122 |
  • 13
  • 123 |
  • 14
  • 124 |
  • 15
  • 125 |
  • 16
  • 126 |
  • 17
  • 127 |
  • 18
  • 128 |
  • 19
  • 129 |
  • 20
  • 130 |
  • 21
  • 131 |
  • 22
  • 132 |
  • 23
  • 133 |
  • 24
  • 134 |
  • 25
  • 135 |
  • 26
  • 136 |
  • 27
  • 137 |
  • 28
  • 138 |
  • 29
  • 139 |
  • 30
  • 140 |
  • 31
  • 141 |
  • 32
  • 142 |
  • 33
  • 143 |
  • 34
  • 144 |
  • 35
  • 145 |
  • 36
  • 146 |
  • 37
  • 147 |
  • 38
  • 148 |
  • 39
  • 149 |
  • 40
  • 150 |
  • 41
  • 151 |
  • 42
  • 152 |
  • 43
  • 153 |
  • 44
  • 154 |
  • 45
  • 155 |
  • 46
  • 156 |
  • 47
  • 157 |
  • 48
  • 158 |
  • 49
  • 159 |
  • 50
  • 160 |
  • 51
  • 161 |
  • 52
  • 162 |
  • 53
  • 163 |
  • 54
  • 164 |
  • 55
  • 165 |
  • 56
  • 166 |
  • 57
  • 167 |
  • 58
  • 168 |
  • 59
  • 169 |
170 |
171 |
172 |
173 | 174 | 175 | -------------------------------------------------------------------------------- /07-calc/01-grid-2.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --unit: 16px; 3 | --padding: calc(var(--unit) * 2); 4 | } 5 | 6 | body, 7 | main { 8 | padding: var(--padding); 9 | } 10 | 11 | main { 12 | --columns: 4; 13 | --totalGutters: calc(var(--columns) - 1); 14 | --availableSpace: calc(100% - var(--totalGutters) * var(--unit)); 15 | --columnWidth: calc(var(--availableSpace) / var(--columns)); 16 | --gutterWidth: var(--unit); 17 | min-height: calc(100vh - 2 * var(--padding)); 18 | display: flex; 19 | flex-wrap: wrap; 20 | align-content: start; 21 | } 22 | 23 | .item { 24 | --span: 1; 25 | --shift: 0; 26 | width: calc( 27 | (var(--columnWidth) * var(--span)) + 28 | (var(--gutterWidth) * (var(--span) - 1)) 29 | ); 30 | margin-right: var(--gutterWidth); 31 | height: 150px; 32 | background-color: var(--blue); 33 | margin-left: calc( 34 | (var(--columnWidth) * (var(--shift))) + 35 | (var(--gutterWidth) * (var(--shift))) 36 | ); 37 | margin-bottom: var(--gutterWidth); 38 | } 39 | 40 | .item:last-child { 41 | margin-right: 0; 42 | } 43 | 44 | nav.item, 45 | header.item { 46 | --span: 4; 47 | margin-right: 0; 48 | } 49 | 50 | article.item { 51 | --span: 3; 52 | } 53 | 54 | aside.item { 55 | margin-right: 0; 56 | } 57 | 58 | footer.item { 59 | --span: 4; 60 | } 61 | 62 | @media (min-width: 600px) { 63 | main { 64 | --columns: 6; 65 | } 66 | 67 | nav.item { 68 | --span: 3; 69 | margin-right: var(--gutterWidth); 70 | } 71 | 72 | header.item { 73 | --span: 3; 74 | margin-right: 0; 75 | } 76 | 77 | article.item { 78 | --span: 4; 79 | --shift: 1; 80 | } 81 | 82 | aside.item { 83 | margin-right: 0; 84 | } 85 | 86 | footer.item { 87 | --span: 6; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /07-calc/01-grid-2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
header
16 | 17 |
article
18 | 19 | 20 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /07-calc/01-grid.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --unit: 16px; 3 | --padding: calc(var(--unit) * 2); 4 | } 5 | 6 | body, 7 | main { 8 | padding: var(--padding); 9 | } 10 | 11 | main { 12 | --columns: 6; 13 | --totalGutters: calc(var(--columns) - 1); 14 | --availableSpace: calc(100% - var(--totalGutters) * var(--unit)); 15 | --columnWidth: calc(var(--availableSpace) / var(--columns)); 16 | --gutterWidth: var(--unit); 17 | height: calc(100vh - 2 * var(--padding)); 18 | display: flex; 19 | flex-wrap: wrap; 20 | align-content: start; 21 | } 22 | 23 | .item { 24 | width: var(--columnWidth); 25 | margin-right: var(--gutterWidth); 26 | height: 100%; 27 | background-color: var(--blue); 28 | } 29 | 30 | .item:last-child { 31 | margin-right: 0; 32 | } 33 | -------------------------------------------------------------------------------- /07-calc/01-grid.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /08-count/01-list.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | counter-reset: list-counter; 4 | } 5 | 6 | li { 7 | margin-bottom: 20px; 8 | margin-left: 50px; 9 | counter-increment: list-counter; 10 | } 11 | 12 | li::before { 13 | content: counter(list-counter) "th"; 14 | } 15 | li:nth-child(10n + 1)::before { 16 | content: counter(list-counter) "st"; 17 | } 18 | li:nth-child(10n + 2)::before { 19 | content: counter(list-counter) "nd"; 20 | } 21 | li:nth-child(10n + 3)::before { 22 | content: counter(list-counter) "rd"; 23 | } 24 | 25 | li:nth-child(100n + 11)::before, 26 | li:nth-child(100n + 12)::before, 27 | li:nth-child(100n + 13)::before { 28 | content: counter(list-counter) "th"; 29 | } 30 | -------------------------------------------------------------------------------- /08-count/01-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 |
15 |

The power of counters

16 | 218 |
219 | 220 | 221 | -------------------------------------------------------------------------------- /08-count/02-calories.css: -------------------------------------------------------------------------------- 1 | main { 2 | width: 500px; 3 | padding: 50px; 4 | counter-reset: calorie-counter; 5 | } 6 | 7 | li { 8 | margin-bottom: 20px; 9 | margin-left: 50px; 10 | 11 | --bad: hsl(0, 50%, 50%); 12 | --normal: hsl(50, 50%, 50%); 13 | --good: hsl(100, 50%, 50%); 14 | } 15 | 16 | .food[data-calorie-categorie="low"] { 17 | counter-increment: calorie-counter 50; 18 | color: var(--good); 19 | } 20 | .food[data-calorie-categorie="medium"] { 21 | counter-increment: calorie-counter 100; 22 | color: var(--normal); 23 | } 24 | .food[data-calorie-categorie="high"] { 25 | counter-increment: calorie-counter 200; 26 | color: var(--bad); 27 | } 28 | 29 | .workout[data-calorie-categorie="low"] { 30 | counter-increment: calorie-counter -50; 31 | color: var(--bad); 32 | } 33 | .workout[data-calorie-categorie="medium"] { 34 | counter-increment: calorie-counter -100; 35 | color: var(--normal); 36 | } 37 | .workout[data-calorie-categorie="high"] { 38 | counter-increment: calorie-counter -200; 39 | color: var(--good); 40 | } 41 | 42 | .result::after { 43 | content: "Total calorie count for the day: " counter(calorie-counter); 44 | } 45 | -------------------------------------------------------------------------------- /08-count/02-calories.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |

Calorie counter

15 | 41 |

42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /08-count/03-basket.css: -------------------------------------------------------------------------------- 1 | :root { 2 | counter-reset: order-total; 3 | } 4 | 5 | [data-name="Chair"] { 6 | --price: 49; 7 | } 8 | [data-name="Clock"] { 9 | --price: 29; 10 | } 11 | [data-name="Table"] { 12 | --price: 199; 13 | } 14 | 15 | [data-amount="1"] { 16 | --amount: 1; 17 | } 18 | [data-amount="2"] { 19 | --amount: 2; 20 | } 21 | [data-amount="3"] { 22 | --amount: 3; 23 | } 24 | [data-amount="4"] { 25 | --amount: 4; 26 | } 27 | [data-amount="5"] { 28 | --amount: 5; 29 | } 30 | 31 | [data-size="small"] { 32 | --delivery: 0; 33 | } 34 | [data-size="medium"] { 35 | --delivery: 29; 36 | } 37 | [data-size="large"] { 38 | --delivery: 49; 39 | } 40 | 41 | .product { 42 | --total-price: var(--price) * var(--amount); 43 | --total-delivery: var(--delivery) * var(--amount); 44 | --item-total: calc(var(--total-price) + var(--total-delivery)); 45 | counter-reset: delivery price amount item-total; 46 | counter-increment: delivery var(--delivery) price var(--price) amount 47 | var(--amount) item-total var(--item-total) order-total var(--item-total); 48 | } 49 | 50 | .product::after { 51 | content: attr(data-name) " x " counter(amount) " --- Price: £" counter(price) 52 | " Delivery: £" counter(delivery) " --- Total: £" counter(item-total); 53 | } 54 | 55 | .total::after { 56 | content: "Order total price: £" counter(order-total); 57 | color: var(--red); 58 | } 59 | -------------------------------------------------------------------------------- /08-count/03-basket.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |

Basket

15 |
21 |
27 |
33 |
34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /09-input-hack/01-checkbox.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | 5 | [type="checkbox"] { 6 | display: none; 7 | } 8 | 9 | [type="checkbox"] + label { 10 | display: block; 11 | width: 200px; 12 | height: 100px; 13 | padding: 36px; 14 | text-align: center; 15 | cursor: pointer; 16 | transform: scale(1); 17 | background-color: var(--grey); 18 | box-shadow: 0 0 0 rgba(0, 0, 0, 0); 19 | transition: box-shadow 300ms, transform 300ms, background-color 300ms; 20 | } 21 | 22 | [type="checkbox"]:checked + label { 23 | transform: scale(1.1); 24 | background-color: var(--green); 25 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); 26 | } 27 | -------------------------------------------------------------------------------- /09-input-hack/01-checkbox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /09-input-hack/02-modal.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | 5 | [type="checkbox"] { 6 | display: none; 7 | } 8 | 9 | .open-button { 10 | width: 200px; 11 | height: 30px; 12 | background-color: var(--blue); 13 | padding: 10px; 14 | cursor: pointer; 15 | } 16 | 17 | .modal { 18 | width: 100%; 19 | height: 100%; 20 | position: fixed; 21 | left: 0; 22 | top: 0; 23 | display: flex; 24 | justify-content: center; 25 | align-items: center; 26 | transition: opacity 300ms; 27 | background-color: rgba(0, 0, 0, 0.7); 28 | } 29 | 30 | .modal-box { 31 | width: 40%; 32 | min-width: 300px; 33 | height: 300px; 34 | position: relative; 35 | display: flex; 36 | justify-content: center; 37 | align-items: center; 38 | background-color: white; 39 | } 40 | 41 | .close-button { 42 | position: absolute; 43 | right: 15px; 44 | top: 15px; 45 | padding: 2px 8px; 46 | border: 4px solid currentColor; 47 | cursor: pointer; 48 | } 49 | 50 | #modal-toggle ~ .modal { 51 | opacity: 0; 52 | pointer-events: none; 53 | } 54 | #modal-toggle:checked ~ .modal { 55 | opacity: 1; 56 | pointer-events: all; 57 | } 58 | 59 | @keyframes slide-in { 60 | from { 61 | transform: translateY(100%); 62 | } 63 | to { 64 | transform: translateY(0); 65 | } 66 | } 67 | 68 | .banner { 69 | width: 100%; 70 | height: 50px; 71 | background-color: var(--dark-blue); 72 | color: white; 73 | position: fixed; 74 | bottom: 0; 75 | left: 0; 76 | padding: 12px; 77 | text-align: center; 78 | animation-name: slide-in; 79 | animation-delay: 3s; 80 | animation-fill-mode: backwards; 81 | animation-duration: 300ms; 82 | transform: translateY(100%); 83 | transition: transform 300ms; 84 | } 85 | 86 | #banner-toggle:checked ~ .banner { 87 | transform: translateY(0); 88 | } 89 | 90 | .close-banner { 91 | background-color: var(--yellow); 92 | color: black; 93 | padding: 6px 8px; 94 | margin-left: 20px; 95 | } 96 | -------------------------------------------------------------------------------- /09-input-hack/02-modal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 22 | 23 | 24 | 28 | 29 |

30 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mattis 31 | justo ex, nec commodo metus pellentesque quis. Suspendisse lobortis eros 32 | elit, nec consequat sem posuere et. Aenean varius facilisis elit, a 33 | mattis ante bibendum a. Ut eu eleifend velit. Donec accumsan placerat 34 | massa quis egestas. Praesent vitae maximus nisl. Nulla ut dui quis purus 35 | tincidunt porta nec id eros. Vivamus in metus quis eros gravida finibus 36 | in sit amet elit. Maecenas eu sagittis augue. Nulla ut dolor et turpis 37 | vestibulum bibendum id at augue. Etiam eu faucibus sem. 38 |

39 | 40 |

41 | Mauris nec magna nisi. Maecenas nec leo ullamcorper tellus eleifend 42 | lobortis. Nulla risus orci, porta non diam vitae, posuere efficitur 43 | risus. Sed lorem dolor, imperdiet quis condimentum in, posuere quis 44 | arcu. Aliquam ex ligula, blandit non elementum non, molestie at metus. 45 | Duis vestibulum facilisis leo bibendum vestibulum. Integer ac justo 46 | augue. Integer mi turpis, porttitor sit amet orci nec, convallis egestas 47 | tortor. Duis convallis sapien ut lorem convallis, nec tristique eros 48 | sodales. Quisque placerat elit vel quam condimentum, quis fermentum 49 | risus elementum. Donec eget tincidunt nisl, nec laoreet massa. Class 50 | aptent taciti sociosqu ad litora torquent per conubia nostra, per 51 | inceptos himenaeos. Vivamus at faucibus ligula. Ut eu rhoncus tellus. 52 |

53 | 54 |

55 | Aliquam pretium lacus a ex tincidunt, et aliquet magna feugiat. 56 | Suspendisse sagittis condimentum pretium. Aenean a scelerisque arcu, 57 | consequat aliquet felis. Cras dictum nulla nec odio tincidunt faucibus. 58 | Nullam nec fermentum elit. Duis in velit vitae felis euismod dignissim 59 | ullamcorper non nisl. Nullam malesuada faucibus malesuada. Duis sem 60 | velit, viverra et diam tempus, convallis sodales orci. Mauris gravida 61 | eros at lorem varius dignissim. Vivamus nec nibh lorem. 62 |

63 | 64 |

65 | Curabitur aliquet leo mi, non molestie orci mollis ut. Curabitur 66 | pretium, turpis rutrum tempus mattis, ex tellus lobortis sapien, vel 67 | vehicula urna purus ut ex. Sed at nisl sit amet nibh auctor hendrerit 68 | quis non est. Praesent hendrerit dui consectetur nisi lacinia, tincidunt 69 | scelerisque nunc condimentum. Etiam imperdiet nibh sed orci efficitur 70 | auctor. Pellentesque habitant morbi tristique senectus et netus et 71 | malesuada fames ac turpis egestas. Donec scelerisque neque quis lacus 72 | facilisis elementum. Sed nisl justo, vulputate non diam id, ornare 73 | luctus ligula. Praesent metus felis, feugiat non sapien eget, commodo 74 | aliquet risus. Integer congue lacinia nulla, ut vulputate augue. 75 | Suspendisse risus ex, eleifend at velit eget, ultricies hendrerit sem. 76 | Integer sit amet tincidunt erat, sed convallis sem. 77 |

78 | 79 |

80 | Nam tristique mi eu lectus rutrum, vel porta magna pharetra. Vestibulum 81 | dictum leo dolor, non sagittis arcu elementum nec. Cras commodo erat sit 82 | amet dolor efficitur, a eleifend libero ultrices. Vivamus facilisis 83 | bibendum posuere. Etiam ornare massa sit amet blandit pharetra. Ut vel 84 | egestas mi. Duis tempor massa elit. Nulla nec neque magna. Vestibulum 85 | posuere facilisis justo, egestas vulputate neque pellentesque sit amet. 86 |

87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /09-input-hack/03-checkbox-accordion.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | 5 | ul { 6 | margin: 0; 7 | padding: 0; 8 | } 9 | 10 | li { 11 | list-style: none; 12 | margin-bottom: 10px; 13 | } 14 | 15 | [type="checkbox"] { 16 | display: none; 17 | } 18 | 19 | [type="checkbox"] + label { 20 | display: block; 21 | width: 100%; 22 | height: 50px; 23 | padding: 12px; 24 | text-align: center; 25 | background-color: var(--grey); 26 | transition: background-color 300ms; 27 | cursor: pointer; 28 | } 29 | 30 | [type="checkbox"]:checked + label { 31 | background-color: var(--green); 32 | } 33 | 34 | .content { 35 | height: 0; 36 | overflow: hidden; 37 | opacity: 0; 38 | transition: opacity 1s; 39 | } 40 | 41 | .content > * { 42 | margin: 20px; 43 | } 44 | 45 | [type="checkbox"]:checked ~ .content { 46 | height: auto; 47 | opacity: 1; 48 | } 49 | -------------------------------------------------------------------------------- /09-input-hack/03-checkbox-accordion.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /09-input-hack/04-radio-accordion.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | ul { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | li { 10 | list-style: none; 11 | margin-bottom: 10px; 12 | } 13 | 14 | [type="radio"] { 15 | display: none; 16 | } 17 | 18 | [type="radio"] + label { 19 | display: block; 20 | width: 100%; 21 | height: 50px; 22 | background-color: var(--grey); 23 | padding: 12px; 24 | text-align: center; 25 | transition: background-color 300ms; 26 | } 27 | 28 | [type="radio"]:checked + label { 29 | background-color: var(--green); 30 | } 31 | 32 | .content { 33 | height: 0; 34 | overflow: hidden; 35 | opacity: 0; 36 | transition: opacity 1s; 37 | } 38 | 39 | .content > * { 40 | margin: 20px; 41 | } 42 | 43 | [type="radio"]:checked ~ .content { 44 | height: auto; 45 | opacity: 1; 46 | } 47 | -------------------------------------------------------------------------------- /09-input-hack/04-radio-accordion.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /09-input-hack/05-focus-accordion.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | ul { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | li { 10 | list-style: none; 11 | margin-bottom: 10px; 12 | } 13 | 14 | .heading { 15 | display: block; 16 | width: 100%; 17 | height: 50px; 18 | background-color: var(--grey); 19 | padding: 12px; 20 | text-align: center; 21 | transition: background-color 300ms; 22 | } 23 | 24 | .heading:focus { 25 | background-color: var(--green); 26 | } 27 | 28 | .content { 29 | height: 0; 30 | overflow: hidden; 31 | opacity: 0; 32 | transition: opacity 1s; 33 | } 34 | 35 | .content > * { 36 | margin: 20px; 37 | } 38 | 39 | .heading:focus + .content { 40 | height: auto; 41 | opacity: 1; 42 | } 43 | -------------------------------------------------------------------------------- /09-input-hack/05-focus-accordion.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /09-input-hack/06-tabs.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | height: 100%; 4 | } 5 | 6 | [type="radio"] { 7 | display: none; 8 | } 9 | 10 | [type="radio"]:checked + .tab { 11 | background-color: var(--blue); 12 | } 13 | 14 | .tab:hover { 15 | text-decoration: underline; 16 | } 17 | 18 | .tab { 19 | display: block; 20 | float: left; 21 | width: calc(100% / 3); 22 | padding: 10px; 23 | background-color: var(--grey); 24 | text-align: center; 25 | cursor: pointer; 26 | } 27 | 28 | [id^="content"] { 29 | display: none; 30 | padding: 50px; 31 | background-color: var(--blue); 32 | } 33 | 34 | #home:checked ~ #content-home, 35 | #work:checked ~ #content-work, 36 | #contact:checked ~ #content-contact { 37 | display: block; 38 | } 39 | -------------------------------------------------------------------------------- /09-input-hack/06-tabs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

25 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mattis 26 | justo ex, nec commodo metus pellentesque quis. Suspendisse lobortis 27 | eros elit, nec consequat sem posuere et. Aenean varius facilisis elit, 28 | a mattis ante bibendum a. Ut eu eleifend velit. Donec accumsan 29 | placerat massa quis egestas. Praesent vitae maximus nisl. Nulla ut dui 30 | quis purus tincidunt porta nec id eros. Vivamus in metus quis eros 31 | gravida finibus in sit amet elit. Maecenas eu sagittis augue. Nulla ut 32 | dolor et turpis vestibulum bibendum id at augue. Etiam eu faucibus 33 | sem. 34 |

35 |
36 | 37 |
38 |

39 | Mauris nec magna nisi. Maecenas nec leo ullamcorper tellus eleifend 40 | lobortis. Nulla risus orci, porta non diam vitae, posuere efficitur 41 | risus. Sed lorem dolor, imperdiet quis condimentum in, posuere quis 42 | arcu. Aliquam ex ligula, blandit non elementum non, molestie at metus. 43 | Duis vestibulum facilisis leo bibendum vestibulum. Integer ac justo 44 | augue. Integer mi turpis, porttitor sit amet orci nec, convallis 45 | egestas tortor. Duis convallis sapien ut lorem convallis, nec 46 | tristique eros sodales. Quisque placerat elit vel quam condimentum, 47 | quis fermentum risus elementum. Donec eget tincidunt nisl, nec laoreet 48 | massa. Class aptent taciti sociosqu ad litora torquent per conubia 49 | nostra, per inceptos himenaeos. Vivamus at faucibus ligula. Ut eu 50 | rhoncus tellus. 51 |

52 |
53 | 54 |
55 |

56 | Aliquam pretium lacus a ex tincidunt, et aliquet magna feugiat. 57 | Suspendisse sagittis condimentum pretium. Aenean a scelerisque arcu, 58 | consequat aliquet felis. Cras dictum nulla nec odio tincidunt 59 | faucibus. Nullam nec fermentum elit. Duis in velit vitae felis euismod 60 | dignissim ullamcorper non nisl. Nullam malesuada faucibus malesuada. 61 | Duis sem velit, viverra et diam tempus, convallis sodales orci. Mauris 62 | gravida eros at lorem varius dignissim. Vivamus nec nibh lorem. 63 |

64 |
65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /09-input-hack/07-ratings.css: -------------------------------------------------------------------------------- 1 | main { 2 | padding: 50px; 3 | } 4 | 5 | .rating-widget { 6 | display: flex; 7 | flex-direction: row-reverse; 8 | width: 250px; 9 | height: 50px; 10 | } 11 | 12 | [type="radio"] { 13 | display: none; 14 | } 15 | 16 | [type="radio"] + label { 17 | display: block; 18 | width: 50px; 19 | height: 50px; 20 | background-image: url("../assets/star-grey.svg"); 21 | background-size: 50px; 22 | cursor: pointer; 23 | } 24 | 25 | .rating-widget:not(:hover) > [type="radio"]:checked ~ label, 26 | [type="radio"]:hover ~ label { 27 | background-image: url("../assets/star-yellow.svg"); 28 | } 29 | -------------------------------------------------------------------------------- /09-input-hack/07-ratings.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # All you need is HTML and CSS 2 | 3 | This repository holds all the example projects from my book: 4 | All you need is HTML and CSS: Building Interactive Web Interfaces with no JavaScript 5 | [UK Amazon link](https://www.amazon.co.uk/dp/B08ZQ3NSYF/ref=sr_1_1) 6 | [US Amazon link](https://www.amazon.com/All-you-need-HTML-CSS/dp/B08ZQ3NSYF/ref=sr_1_2) 7 | 8 | # Other cool HTML, CSS and JavaScript tricks from me: 9 | 10 | [Medium](https://matemarschalko.medium.com/) 11 | 12 | ## About the book 13 | 14 | If you are a person who is just getting started with web development, the ideas in this book will allow you to level up and build interactive, animated web interfaces without knowing much about JavaScript. 15 | 16 | If you are a JavaScript developer, then this book will remind you that there are many many things we can build with these simple languages without having to touch JavaScript at all. 17 | 18 | In this book we will push the limits of what’s possible with just simple HTML and CSS! 19 | 20 | Starting with the anchor element, we will build scrolling and animating carousels, image maps with dynamic, dismissible popups then move onto investigating mouse and keyboard interactions, toggle and focus states. 21 | 22 | We will then move onto calculating and counting with CSS: we will build an analogue and a digital clock, a calorie counter and a shopping basket. 23 | 24 | Finally, with the checkbox and radio buttons we will push things even further and build a content accordion three ways, a tab interface and even a fully functioning star rating component. 25 | 26 | ## Book content available online 27 | 28 | Some example projects from the book are available online for free: 29 | 30 | - [Animated page scroll with HTML and CSS only](https://levelup.gitconnected.com/animated-page-scroll-with-html-and-css-only-3788c4e2b853) 31 | - [CSS-only Interactive, Swipeable Image Carousel](https://matemarschalko.medium.com/css-only-interactive-swipeable-image-carousel-3a38afe3da58) 32 | -------------------------------------------------------------------------------- /assets/camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/camera.png -------------------------------------------------------------------------------- /assets/car1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/car1.jpg -------------------------------------------------------------------------------- /assets/car2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/car2.jpg -------------------------------------------------------------------------------- /assets/car3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/car3.jpg -------------------------------------------------------------------------------- /assets/car4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/car4.jpg -------------------------------------------------------------------------------- /assets/car5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/car5.jpg -------------------------------------------------------------------------------- /assets/desk.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/desk.jpeg -------------------------------------------------------------------------------- /assets/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/download.png -------------------------------------------------------------------------------- /assets/fb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/fb.png -------------------------------------------------------------------------------- /assets/new-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/new-window.png -------------------------------------------------------------------------------- /assets/pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webondevices/html-css-wizardry/2fe8f79ad2fa5628ba5bd353c5c68bf641bb1ded/assets/pdf.png -------------------------------------------------------------------------------- /assets/star-grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/star-yellow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /base.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Roboto:100,300,400,700,900"); 2 | 3 | :root { 4 | --blue: #74bcdd; 5 | --dark-blue: #2d3e51; 6 | --red: #f74442; 7 | --yellow: #fbca32; 8 | --green: #5be95b; 9 | --grey: #ebeced; 10 | } 11 | 12 | *, 13 | *::after, 14 | *::before { 15 | box-sizing: border-box; 16 | } 17 | 18 | html, 19 | body { 20 | width: 100%; 21 | min-height: 100%; 22 | } 23 | 24 | body { 25 | margin: 0; 26 | padding: 10px; 27 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==), 28 | radial-gradient(ellipse at center, #effaff 0%, #c5d0d8 100%); 29 | font-family: "Roboto", sans-serif; 30 | font-size: 18px; 31 | line-height: 1.5; 32 | color: var(--dark-blue); 33 | } 34 | 35 | h1 { 36 | margin: 0 0 10px; 37 | font-weight: 100; 38 | font-size: 48px; 39 | } 40 | 41 | h2 { 42 | margin-bottom: 0; 43 | font-size: 36px; 44 | } 45 | 46 | a, 47 | a:visited { 48 | color: var(--red); 49 | font-weight: bold; 50 | } 51 | 52 | main { 53 | width: 100%; 54 | min-width: 300px; 55 | max-width: 800px; 56 | margin: 0 auto; 57 | padding: 30px; 58 | background-color: white; 59 | box-shadow: 0 15px 50px rgba(0, 0, 0, 0.25); 60 | border-radius: 8px; 61 | } 62 | 63 | button { 64 | width: 200px; 65 | height: 40px; 66 | background-color: var(--blue); 67 | border: none; 68 | outline: none; 69 | cursor: pointer; 70 | color: var(--dark-blue); 71 | font-size: 16px; 72 | border-bottom: 4px solid currentColor; 73 | } 74 | 75 | @media (min-width: 500px) { 76 | body, 77 | main, 78 | section { 79 | padding: 50px; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | width: 100%; 4 | height: 100%; 5 | margin: 0; 6 | font-family: "Roboto", sans-serif; 7 | } 8 | 9 | body { 10 | display: flex; 11 | } 12 | 13 | section { 14 | width: 100%; 15 | height: 100%; 16 | } 17 | 18 | code { 19 | padding-bottom: 30px !important; 20 | } 21 | 22 | iframe { 23 | width: 100%; 24 | height: 100%; 25 | background-color: white; 26 | } 27 | 28 | .notes { 29 | background-color: rgb(220, 220, 220); 30 | overflow-y: scroll; 31 | position: relative; 32 | } 33 | 34 | .slide { 35 | width: 100%; 36 | min-height: 100%; 37 | box-sizing: border-box; 38 | padding: 20px 20px 60px; 39 | position: relative; 40 | } 41 | 42 | .slide > img { 43 | width: 100%; 44 | } 45 | 46 | h1 { 47 | font-size: 2.5vw; 48 | margin: 0; 49 | } 50 | 51 | p { 52 | font-size: 2vw; 53 | margin: 25px; 54 | line-height: 1.5; 55 | } 56 | 57 | code { 58 | font-size: 1.5vw; 59 | } 60 | 61 | .demo { 62 | font-size: 24px; 63 | display: block; 64 | margin-bottom: 10px; 65 | color: green; 66 | font-style: italic; 67 | font-family: serif; 68 | } 69 | 70 | #fullscreen { 71 | display: none; 72 | } 73 | 74 | #fullscreen + label { 75 | display: block; 76 | background-color: rgb(220, 220, 220); 77 | position: absolute; 78 | padding: 10px; 79 | right: 0; 80 | bottom: 0; 81 | z-index: 2; 82 | } 83 | 84 | #fullscreen:checked + label { 85 | background-color: green; 86 | color: white; 87 | } 88 | 89 | #fullscreen:checked ~ iframe { 90 | position: absolute; 91 | left: 0; 92 | top: 0; 93 | } 94 | 95 | .next { 96 | display: block; 97 | background-color: rgb(184, 184, 184); 98 | position: absolute; 99 | padding: 20px; 100 | left: 0; 101 | bottom: 0; 102 | } 103 | 104 | .progress { 105 | width: 0; 106 | background-color: grey; 107 | transition: all 300ms; 108 | height: 10px; 109 | position: fixed; 110 | left: 0; 111 | top: 0; 112 | } 113 | [id="s0"]:target ~ .progress { 114 | width: calc((100% / 14) * 1); 115 | background-color: hsl(calc((360deg / 14) * 1), 75%, 50%); 116 | } 117 | [id="s1"]:target ~ .progress { 118 | width: calc((100% / 14) * 2); 119 | background-color: hsl(calc((360deg / 14) * 2), 75%, 50%); 120 | } 121 | [id="s2"]:target ~ .progress { 122 | width: calc((100% / 14) * 3); 123 | background-color: hsl(calc((360deg / 14) * 3), 75%, 50%); 124 | } 125 | [id="s3"]:target ~ .progress { 126 | width: calc((100% / 14) * 4); 127 | background-color: hsl(calc((360deg / 14) * 4), 75%, 50%); 128 | } 129 | [id="s4"]:target ~ .progress { 130 | width: calc((100% / 14) * 5); 131 | background-color: hsl(calc((360deg / 14) * 5), 75%, 50%); 132 | } 133 | [id="s5"]:target ~ .progress { 134 | width: calc((100% / 14) * 6); 135 | background-color: hsl(calc((360deg / 14) * 6), 75%, 50%); 136 | } 137 | [id="s6"]:target ~ .progress { 138 | width: calc((100% / 14) * 7); 139 | background-color: hsl(calc((360deg / 14) * 7), 75%, 50%); 140 | } 141 | [id="s7"]:target ~ .progress { 142 | width: calc((100% / 14) * 8); 143 | background-color: hsl(calc((360deg / 14) * 8), 75%, 50%); 144 | } 145 | [id="s8"]:target ~ .progress { 146 | width: calc((100% / 14) * 9); 147 | background-color: hsl(calc((360deg / 14) * 9), 75%, 50%); 148 | } 149 | [id="s9"]:target ~ .progress { 150 | width: calc((100% / 14) * 10); 151 | background-color: hsl(calc((360deg / 14) * 10), 75%, 50%); 152 | } 153 | [id="s10"]:target ~ .progress { 154 | width: calc((100% / 14) * 11); 155 | background-color: hsl(calc((360deg / 14) * 11), 75%, 50%); 156 | } 157 | [id="s11"]:target ~ .progress { 158 | width: calc((100% / 14) * 12); 159 | background-color: hsl(calc((360deg / 14) * 12), 75%, 50%); 160 | } 161 | [id="s12"]:target ~ .progress { 162 | width: calc((100% / 14) * 13); 163 | background-color: hsl(calc((360deg / 14) * 13), 75%, 50%); 164 | } 165 | [id="s13"]:target ~ .progress { 166 | width: calc((100% / 14) * 14); 167 | background-color: hsl(calc((360deg / 14) * 14), 75%, 50%); 168 | } 169 | --------------------------------------------------------------------------------