├── 000 ├── index.html ├── script.js └── style.css ├── 001-expanding-cards ├── index.html ├── output.gif ├── script.js └── style.css ├── 002-progress-steps ├── index.html ├── output.gif ├── script.js └── style.css ├── 003-rotating-navigation ├── index.html ├── output.gif ├── script.js └── style.css ├── 004-hidden-search-widget ├── index.html ├── output.gif ├── script.js └── style.css ├── 005-blurry-loading ├── index.html ├── output.gif ├── script.js └── style.css ├── 006-scroll-animation ├── index.html ├── output.gif ├── script.js └── style.css ├── 007-split-landing-page ├── index.html ├── output.gif ├── ps.jpg ├── script.js ├── style.css └── xbox.jpg ├── 008-form-wave-animation ├── index.html ├── output.gif ├── script.js └── style.css ├── 009-sound-board ├── index.html ├── output.gif ├── script.js ├── sounds │ ├── applause.mp3 │ ├── boo.mp3 │ ├── gasp.mp3 │ ├── tada.mp3 │ ├── victory.mp3 │ └── wrong.mp3 └── style.css ├── 010-dad-jokes ├── index.html ├── output.gif ├── script.js └── style.css ├── 011-event-keycodes ├── index.html ├── output.gif ├── script.js └── style.css ├── 012-faq-collapse ├── index.html ├── output.gif ├── script.js └── style.css ├── 013-random-choice-picker ├── index.html ├── output.gif ├── script.js └── style.css ├── 014-animated-navigation ├── index.html ├── output.gif ├── script.js └── style.css ├── 015-increment-counter ├── index.html ├── output.gif ├── script.js └── style.css ├── 016-drink-water ├── index.html ├── output.gif ├── script.js └── style.css ├── 017-movie-app ├── index.html ├── output.gif ├── script.js └── style.css ├── 018-background-slider ├── index.html ├── output.gif ├── script.js └── style.css ├── 019-theme-clock ├── index.html ├── output.gif ├── script.js └── style.css ├── 020-button-ripple-effect ├── index.html ├── output.gif ├── script.js └── style.css ├── 021-drag-n-drop ├── index.html ├── output.gif ├── script.js └── style.css ├── 022-drawing-app ├── index.html ├── output.gif ├── script.js └── style.css ├── 023-kinetic-css-loader ├── index.html ├── output.gif ├── script.js └── style.css ├── 024-content-placeholder ├── index.html ├── output.gif ├── script.js └── style.css ├── 025-sticky-navbar ├── index.html ├── output.gif ├── script.js └── style.css ├── 026-vertical-slider ├── index.html ├── output.gif ├── script.js └── style.css ├── 027-toast-notification ├── index.html ├── output.gif ├── script.js └── style.css ├── 028-github-profiles ├── index.html ├── output.gif ├── script.js └── style.css ├── 029-double-click-heart ├── index.html ├── output.gif ├── script.js └── style.css ├── 030-auto-text-effect ├── index.html ├── output.gif ├── script.js └── style.css ├── 031-random-password ├── index.html ├── output.gif ├── script.js └── style.css ├── 032-good-cheap-fast ├── index.html ├── output.gif ├── script.js └── style.css ├── 033-notes-app ├── index.html ├── output.gif ├── script.js └── style.css ├── 034-animated-countdown ├── index.html ├── output.gif ├── script.js └── style.css ├── 035-image-carousel ├── index.html ├── output.gif ├── script.js └── style.css ├── 036-hoverboard ├── index.html ├── output.gif ├── script.js └── style.css ├── 037-pokedex ├── index.html ├── output.gif ├── script.js └── style.css ├── 038-mobile-tab-navigation ├── index.html ├── output.gif ├── script.js └── style.css ├── 039-password-strength-background ├── index.html ├── output.gif ├── script.js └── style.css ├── 040-3d-background-boxes ├── index.html ├── output.gif ├── script.js └── style.css ├── 041-verify-account-ui ├── index.html ├── output.gif ├── script.js └── style.css ├── 042-live-user-filter ├── index.html ├── output.gif ├── script.js └── style.css ├── 043-feedback-ui-design ├── index.html ├── output.png ├── script.js └── style.css ├── 044-custom-range-slider ├── index.html ├── output.png ├── script.js └── style.css ├── 045-netflix-mobile-navigation ├── index.html ├── output.gif ├── output.png ├── script.js └── style.css ├── 046-quiz-app ├── index.html ├── output.gif ├── script.js └── style.css ├── 047-testimonial-box-switcher ├── index.html ├── output.gif ├── script.js └── style.css ├── 048-random-image-generator ├── index.html ├── output.png ├── script.js └── style.css ├── 049-todo-list ├── index.html ├── output.gif ├── script.js └── style.css ├── 050-insect-catch-game ├── index.html ├── output.gif ├── script.js └── style.css └── README.md /000/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | My Project 21 | 22 | 23 | 24 |

Project Starter

25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /000/script.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /000/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Mulish", sans-serif; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | overflow: hidden; 15 | margin: 0; 16 | } 17 | -------------------------------------------------------------------------------- /001-expanding-cards/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | Expanding Cards 15 | 16 | 17 | 18 |
19 |
25 |

Explore The World

26 |
27 |
33 |

Wild Forest

34 |
35 |
41 |

Sunny Beach

42 |
43 |
49 |

City on Winter

50 |
51 |
57 |

Mountains - Clouds

58 |
59 |
60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /001-expanding-cards/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/001-expanding-cards/output.gif -------------------------------------------------------------------------------- /001-expanding-cards/script.js: -------------------------------------------------------------------------------- 1 | const panels = document.querySelectorAll(".panel"); 2 | 3 | panels.forEach((panel) => { 4 | panel.addEventListener("click", () => { 5 | removeActiveClasses(); 6 | panel.classList.add("active"); 7 | }); 8 | }); 9 | 10 | function removeActiveClasses() { 11 | panels.forEach((panel) => { 12 | panel.classList.remove("active"); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /001-expanding-cards/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: "Mulish", sans-serif; 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | .container { 20 | display: flex; 21 | width: 90vw; 22 | } 23 | 24 | .panel { 25 | background-size: cover; 26 | background-position: center; 27 | background-repeat: no-repeat; 28 | height: 80vh; 29 | border-radius: 50px; 30 | color: white; 31 | cursor: pointer; 32 | flex: 0.5; /* ! Confusion */ 33 | margin: 10px; 34 | position: relative; 35 | transition: flex 0.7s ease-in; 36 | } 37 | 38 | .panel h3 { 39 | font-size: 24px; 40 | position: absolute; 41 | bottom: 20px; 42 | left: 20px; 43 | margin: 0; 44 | opacity: 0; 45 | } 46 | 47 | .panel.active { 48 | flex: 5; 49 | } 50 | 51 | .panel.active h3 { 52 | opacity: 1; 53 | transition: opacity 0.3s ease-in 0.4s; 54 | } 55 | 56 | @media (max-width: 480px) { 57 | .container { 58 | width: 100vw; 59 | } 60 | 61 | /* ! Confusion */ 62 | .panel:nth-of-type(4), 63 | .panel:nth-of-type(5) { 64 | display: none; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /002-progress-steps/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | Progress Steps 15 | 16 | 17 | 18 |
19 |
20 |
21 |
1
22 |
2
23 |
3
24 |
4
25 |
26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /002-progress-steps/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/002-progress-steps/output.gif -------------------------------------------------------------------------------- /002-progress-steps/script.js: -------------------------------------------------------------------------------- 1 | const progress = document.getElementById("progress"); 2 | const prev = document.getElementById("prev"); 3 | const next = document.getElementById("next"); 4 | const circles = document.querySelectorAll(".circle"); 5 | 6 | let currentActive = 1; 7 | 8 | next.addEventListener("click", () => { 9 | currentActive++; 10 | if (currentActive > circles.length) { 11 | currentActive = circles.length; 12 | } 13 | 14 | update(); 15 | }); 16 | 17 | prev.addEventListener("click", () => { 18 | currentActive--; 19 | if (currentActive < 1) { 20 | currentActive = 1; 21 | } 22 | update(); 23 | }); 24 | 25 | function update() { 26 | circles.forEach((circle, idx) => { 27 | if (idx < currentActive) { 28 | circle.classList.add("active"); 29 | } else { 30 | circle.classList.remove("active"); 31 | } 32 | }); 33 | 34 | const actives = document.querySelectorAll(".active"); 35 | 36 | progress.style.width = 37 | ((actives.length - 1) / (circles.length - 1)) * 100 + "%"; 38 | 39 | if(currentActive === 1){ 40 | prev.disabled = true; 41 | }else if (currentActive === circles.length){ 42 | next.disabled = true; 43 | }else{ 44 | prev.disabled = false; 45 | next.disabled = false; 46 | } 47 | } -------------------------------------------------------------------------------- /002-progress-steps/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Mulish&display=swap"); 2 | 3 | :root { 4 | --line-border-fill: #3498db; 5 | --line-border-empty: #383838; 6 | } 7 | 8 | * { 9 | box-sizing: border-box; 10 | } 11 | 12 | body { 13 | background-color: #1f1f1f; 14 | font-family: "Mulish", sans-serif; 15 | display: flex; 16 | align-items: center; 17 | justify-content: center; 18 | height: 100vh; 19 | overflow: hidden; 20 | margin: 0; 21 | } 22 | 23 | .container { 24 | text-align: center; 25 | } 26 | 27 | .progress-container { 28 | display: flex; 29 | justify-content: space-between; 30 | position: relative; 31 | margin-bottom: 30px; 32 | max-width: 100%; 33 | width: 350px; 34 | } 35 | 36 | .progress-container::before { 37 | content: ""; 38 | background-color: var(--line-border-empty); 39 | position: absolute; 40 | top: 50%; 41 | left: 0; 42 | transform: translateY(-50%); 43 | height: 4px; 44 | width: 100%; 45 | z-index: -1; 46 | } 47 | 48 | .progress { 49 | background-color: var(--line-border-fill); 50 | position: absolute; 51 | top: 50%; 52 | left: 0; 53 | transform: translateY(-50%); 54 | height: 4px; 55 | width: 0%; 56 | z-index: -1; 57 | transition: 0.4s ease; 58 | } 59 | 60 | .circle { 61 | background-color: #1f1f1f; 62 | color: #e2e2e2; 63 | border-radius: 50%; 64 | height: 30px; 65 | width: 30px; 66 | display: flex; 67 | align-items: center; 68 | justify-content: center; 69 | border: 3px solid var(--line-border-empty); 70 | transition: 0.4s ease; 71 | } 72 | 73 | .circle.active { 74 | border-color: var(--line-border-fill); 75 | } 76 | 77 | .btn { 78 | background-color: var(--line-border-fill); 79 | color: #fff; 80 | border: 0; 81 | border-radius: 6px; 82 | cursor: pointer; 83 | font-family: inherit; 84 | padding: 8px 30px; 85 | margin: 5px; 86 | font-size: 14px; 87 | } 88 | 89 | .btn:active { 90 | transform: scale(0.98); 91 | } 92 | 93 | .btn:focus { 94 | outline: 0; 95 | } 96 | 97 | .btn:disabled { 98 | background-color: var(--line-border-empty); 99 | cursor: not-allowed; 100 | } 101 | -------------------------------------------------------------------------------- /003-rotating-navigation/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/003-rotating-navigation/output.gif -------------------------------------------------------------------------------- /003-rotating-navigation/script.js: -------------------------------------------------------------------------------- 1 | const open = document.getElementById("open"); 2 | const close = document.getElementById("close"); 3 | const container = document.querySelector(".container"); 4 | 5 | open.addEventListener("click", () => container.classList.add("show-nav")); 6 | 7 | close.addEventListener("click", () => container.classList.remove("show-nav")); 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /003-rotating-navigation/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Lato&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: 'Lato', sans-serif; 9 | background-color: #333; 10 | color: #222; 11 | overflow-x: hidden; 12 | margin: 0; 13 | } 14 | 15 | .container { 16 | background-color: #fafafa; 17 | transform-origin: top left; 18 | transition: transform 0.5s linear; 19 | width: 100vw; 20 | min-height: 100vh; 21 | padding: 50px; 22 | } 23 | 24 | .container.show-nav { 25 | transform: rotate(-20deg); 26 | } 27 | 28 | .circle-container { 29 | position: fixed; 30 | top: -100px; 31 | left: -100px; 32 | } 33 | 34 | .circle { 35 | background-color: #ff7979; 36 | height: 200px; 37 | width: 200px; 38 | border-radius: 50%; 39 | position: relative; 40 | transition: transform 0.5s linear; 41 | } 42 | 43 | .container.show-nav .circle { 44 | transform: rotate(-70deg); 45 | } 46 | 47 | .circle button { 48 | cursor: pointer; 49 | position: absolute; 50 | top: 50%; 51 | left: 50%; 52 | height: 100px; 53 | background: transparent; 54 | border: 0; 55 | font-size: 26px; 56 | color: #fff; 57 | } 58 | 59 | .circle button:focus { 60 | outline: none; 61 | } 62 | 63 | .circle button#open { 64 | left: 60%; 65 | } 66 | 67 | .circle button#close { 68 | top: 60%; 69 | transform: rotate(90deg); 70 | transform-origin: top left; 71 | } 72 | 73 | .container.show-nav + nav li { 74 | transform: translateX(0); 75 | transition-delay: 0.3s; 76 | } 77 | 78 | nav { 79 | position: fixed; 80 | bottom: 40px; 81 | left: 0; 82 | z-index: 100; 83 | } 84 | 85 | nav ul { 86 | list-style-type: none; 87 | padding-left: 30px; 88 | } 89 | 90 | nav ul li { 91 | text-transform: uppercase; 92 | color: #fff; 93 | margin: 40px 0; 94 | transform: translateX(-100%); 95 | transition: transform 0.4s ease-in; 96 | } 97 | 98 | nav ul li i { 99 | font-size: 20px; 100 | margin-right: 10px; 101 | } 102 | 103 | nav ul li + li { 104 | margin-left: 15px; 105 | transform: translateX(-150%); 106 | } 107 | 108 | nav ul li + li + li { 109 | margin-left: 30px; 110 | transform: translateX(-200%); 111 | } 112 | 113 | nav a{ 114 | color: #fafafa; 115 | text-decoration: none; 116 | transition: all 0.5s; 117 | } 118 | 119 | nav a:hover { 120 | color: #FF7979; 121 | font-weight: bold; 122 | } 123 | 124 | .content img { 125 | max-width: 100%; 126 | } 127 | 128 | .content { 129 | max-width: 1000px; 130 | margin: 50px auto; 131 | } 132 | 133 | .content h1 { 134 | margin: 0; 135 | } 136 | 137 | .content small { 138 | color: #555; 139 | font-style: italic; 140 | } 141 | 142 | .content p { 143 | color: #333; 144 | line-height: 1.5; 145 | } -------------------------------------------------------------------------------- /004-hidden-search-widget/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | Hidden Search Widget 20 | 21 | 22 | 23 | 24 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /004-hidden-search-widget/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/004-hidden-search-widget/output.gif -------------------------------------------------------------------------------- /004-hidden-search-widget/script.js: -------------------------------------------------------------------------------- 1 | const search = document.querySelector(".search"); 2 | const btn = document.querySelector(".btn"); 3 | const input = document.querySelector(".input"); 4 | 5 | btn.addEventListener("click", () => { 6 | search.classList.toggle("active"); 7 | input.focus(); 8 | }); 9 | -------------------------------------------------------------------------------- /004-hidden-search-widget/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-image: linear-gradient(90deg, #7d5fff, #7158e2); 9 | font-family: "Roboto", sans-serif; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | overflow: hidden; 15 | margin: 0; 16 | } 17 | 18 | .search { 19 | position: relative; 20 | height: 50px; 21 | } 22 | 23 | .search .input { 24 | background-color: white; 25 | border: 0; 26 | font-size: 18px; 27 | padding: 15px; 28 | height: 50px; 29 | width: 50px; 30 | transition: width 0.3s ease; 31 | } 32 | 33 | .btn{ 34 | background-color: white; 35 | border: 0; 36 | cursor: pointer; 37 | font-size: 24px; 38 | position: absolute; 39 | top:0; 40 | left: 0; 41 | height: 50px; 42 | width: 50px; 43 | transition: transform 0.3s ease; 44 | } 45 | 46 | .btn:focus, .input:focus{ 47 | outline: none; 48 | } 49 | 50 | .search.active .input{ 51 | width: 200px; 52 | } 53 | 54 | .search.active .btn{ 55 | transform: translateX(198px); 56 | } 57 | -------------------------------------------------------------------------------- /005-blurry-loading/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Blurry Loading 21 | 22 | 23 | 24 | 25 |
26 |
0%
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /005-blurry-loading/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/005-blurry-loading/output.gif -------------------------------------------------------------------------------- /005-blurry-loading/script.js: -------------------------------------------------------------------------------- 1 | const loadText = document.querySelector(".loading-text"); 2 | const bg = document.querySelector(".bg"); 3 | 4 | let load = 0; 5 | 6 | let int = setInterval(blurring, 30); 7 | 8 | function blurring() { 9 | load++; 10 | if (load > 99) { 11 | clearInterval(int); 12 | } 13 | 14 | loadText.innerText = `${load}%`; 15 | loadText.style.opacity = scale(load, 0, 100, 1, 0); 16 | bg.style.filter = `blur(${scale(load, 0, 100, 30, 0)}px)`; 17 | } 18 | 19 | 20 | // https://stackoverflow.com/questions/10756313/javascript-jquery-map-a-range-of-numbers-to-another-range-of-numbers 21 | const scale = (num, in_min, in_max, out_min, out_max) => { 22 | return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min 23 | } -------------------------------------------------------------------------------- /005-blurry-loading/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Ubuntu"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Ubuntu", sans-serif; 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | height: 100vh; 13 | overflow: hidden; 14 | margin: 0; 15 | } 16 | 17 | .bg { 18 | background: url('https://images.unsplash.com/photo-1576161787924-01bb08dad4a4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2104&q=80') 19 | no-repeat center center/cover; 20 | position: absolute; 21 | top: -30px; 22 | left: -30px; 23 | width: calc(100vw + 60px); 24 | height: calc(100vh + 60px); 25 | z-index: -1; 26 | filter: blur(0px); 27 | } 28 | 29 | .loading-text { 30 | font-size: 50px; 31 | color: #fff; 32 | } -------------------------------------------------------------------------------- /006-scroll-animation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Scroll Animation 21 | 22 | 23 | 24 |

Scroll to see the animation

25 |
26 |

Content

27 |
28 |
29 |

Content

30 |
31 |
32 |

Content

33 |
34 |
35 |

Content

36 |
37 |
38 |

Content

39 |
40 |
41 |

Content

42 |
43 |
44 |

Content

45 |
46 |
47 |

Content

48 |
49 |
50 |

Content

51 |
52 |
53 |

Content

54 |
55 |
56 |

Content

57 |
58 |
59 |

Content

60 |
61 |
62 |

Content

63 |
64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /006-scroll-animation/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/006-scroll-animation/output.gif -------------------------------------------------------------------------------- /006-scroll-animation/script.js: -------------------------------------------------------------------------------- 1 | const boxes = document.querySelectorAll(".box"); 2 | 3 | window.addEventListener("scroll", checkBoxes); 4 | 5 | checkBoxes(); 6 | 7 | function checkBoxes() { 8 | const triggerBottom = (window.innerHeight / 5) * 4; 9 | 10 | boxes.forEach((box) => { 11 | const boxTop = box.getBoundingClientRect().top; 12 | 13 | if (boxTop < triggerBottom) { 14 | box.classList.add("show"); 15 | } else { 16 | box.classList.remove("show"); 17 | } 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /006-scroll-animation/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #efedd6; 9 | font-family: "Roboto", sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | margin: 0; 15 | overflow-x: hidden; 16 | } 17 | 18 | h1 { 19 | margin: 10px; 20 | } 21 | 22 | .box { 23 | background-color: steelblue; 24 | color: #fff; 25 | display: flex; 26 | align-items: center; 27 | justify-content: center; 28 | width: 400px; 29 | height: 200px; 30 | margin: 10px; 31 | border-radius: 10px; 32 | box-shadow: 2px 4px 5px rgba(0, 0, 0, 0.3); 33 | transform: translateX(400%); 34 | transition: transform 0.4s ease; 35 | } 36 | 37 | .box:nth-of-type(even) { 38 | transform: translateX(-400%); 39 | } 40 | 41 | .box.show { 42 | transform: translateX(0); 43 | } 44 | 45 | .box h2 { 46 | font-size: 45px; 47 | } 48 | -------------------------------------------------------------------------------- /007-split-landing-page/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Split Landing Page 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 |

Playstation 5

29 | Buy Now 30 |
31 | 32 |
33 |

XBox Series X

34 | Buy Now 35 |
36 |
37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /007-split-landing-page/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/007-split-landing-page/output.gif -------------------------------------------------------------------------------- /007-split-landing-page/ps.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/007-split-landing-page/ps.jpg -------------------------------------------------------------------------------- /007-split-landing-page/script.js: -------------------------------------------------------------------------------- 1 | const left = document.querySelector(".left"); 2 | const right = document.querySelector(".right"); 3 | const container = document.querySelector(".container"); 4 | 5 | left.addEventListener("mouseenter", () => container.classList.add("hover-left")); 6 | left.addEventListener('mouseleave', () => container.classList.remove("hover-left")); 7 | 8 | right.addEventListener("mouseenter", () => container.classList.add("hover-right")); 9 | right.addEventListener('mouseleave', () => container.classList.remove("hover-right"));v -------------------------------------------------------------------------------- /007-split-landing-page/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"); 2 | 3 | :root { 4 | --left-bg-color: rgba(87, 84, 236, 0.7); 5 | --right-bg-color: rgba(43, 43, 43, 0.8); 6 | --left-btn-hover-color: rgba(87, 84, 236, 1); 7 | --right-btn-hover-color: rgba(28, 122, 28, 1); 8 | --hover-width: 75%; 9 | --other-width: 25%; 10 | } 11 | 12 | * { 13 | box-sizing: border-box; 14 | } 15 | 16 | body { 17 | font-family: "Roboto", sans-serif; 18 | height: 100vh; 19 | overflow: hidden; 20 | margin: 0; 21 | } 22 | 23 | h1{ 24 | font-size: 4rem; 25 | color: white; 26 | position: absolute; 27 | left: 50%; 28 | top: 20%; 29 | transform: translateX(-50%); 30 | white-space: nowrap; 31 | } 32 | 33 | .btn{ 34 | position: absolute; 35 | display: flex; 36 | justify-content: center; 37 | align-items: center; 38 | left: 50%; 39 | top: 40%; 40 | transform: translateX(-50%); 41 | text-decoration: none; 42 | color: white; 43 | border: #fff solid 0.2rem; 44 | font-size: 1rem; 45 | font-weight: bold; 46 | text-transform: uppercase; 47 | width: 15rem; 48 | padding: 1.5rem; 49 | } 50 | 51 | .split.left .btn:hover{ 52 | background-color: var(--left-btn-hover-color); 53 | border-color: var(--left-btn-hover-color); 54 | } 55 | 56 | .split.right .btn:hover{ 57 | background-color: var(--right-btn-hover-color); 58 | border-color: var(--right-btn-hover-color); 59 | } 60 | 61 | .container { 62 | position: relative; 63 | width: 100%; 64 | height: 100%; 65 | background: #333; 66 | } 67 | 68 | .split { 69 | position: absolute; 70 | width: 50%; 71 | height: 100%; 72 | overflow: hidden; 73 | transition: all 2s ease; 74 | } 75 | 76 | .split.left { 77 | left: 0; 78 | background: url("./ps.jpg"); 79 | background-repeat: no-repeat; 80 | background-size: cover; 81 | } 82 | 83 | .split.left::before { 84 | content: ""; 85 | position: absolute; 86 | width: 100%; 87 | height: 100%; 88 | background-color: var(--left-bg-color); 89 | } 90 | 91 | .split.right { 92 | right: 0; 93 | background: url("./xbox.jpg"); 94 | background-repeat: no-repeat; 95 | background-size: cover; 96 | } 97 | 98 | .split.right::before{ 99 | content: ""; 100 | position: absolute; 101 | width: 100%; 102 | height: 100%; 103 | background-color: var(--right-bg-color); 104 | } 105 | 106 | .hover-left .left{ 107 | width: var(--hover-width); 108 | } 109 | 110 | .hover-left .right{ 111 | width: var(--other-width); 112 | } 113 | 114 | .hover-right .right{ 115 | width: var(--hover-width); 116 | } 117 | 118 | .hover-right .left{ 119 | width: var(--other-width); 120 | } 121 | 122 | -------------------------------------------------------------------------------- /007-split-landing-page/xbox.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/007-split-landing-page/xbox.jpg -------------------------------------------------------------------------------- /008-form-wave-animation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 15 | 16 | 17 | Form Input Wave 18 | 19 | 20 | 21 |
22 |

Please Login

23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 | 33 |

Don't have an account? Register

34 |
35 |
36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /008-form-wave-animation/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/008-form-wave-animation/output.gif -------------------------------------------------------------------------------- /008-form-wave-animation/script.js: -------------------------------------------------------------------------------- 1 | const labels = document.querySelectorAll(".form-control label"); 2 | 3 | console.log(labels); 4 | 5 | labels.forEach((label) => { 6 | label.innerHTML = label.innerText 7 | .split("") 8 | .map((letter, idx) => `${letter}`) 9 | .join(""); 10 | }); 11 | -------------------------------------------------------------------------------- /008-form-wave-animation/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: steelblue; 9 | color: white; 10 | font-family: "Mulish", sans-serif; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | height: 100vh; 16 | overflow: hidden; 17 | margin: 0; 18 | } 19 | 20 | .container { 21 | background-color: rgba(0, 0, 0, 0.4); 22 | padding: 20px 40px; 23 | border-radius: 5px; 24 | } 25 | 26 | .container h1 { 27 | text-align: center; 28 | margin-bottom: 30px; 29 | } 30 | 31 | .container a { 32 | text-decoration: none; 33 | color: lightblue; 34 | } 35 | 36 | .btn { 37 | cursor: pointer; 38 | display: inline-block; 39 | width: 100%; 40 | background-color: lightblue; 41 | padding: 15px; 42 | font-family: inherit; 43 | font-size: 16px; 44 | border: 0; 45 | border-radius: 5px; 46 | } 47 | 48 | .btn:focus { 49 | outline: 0; 50 | } 51 | 52 | .btn:active { 53 | transform: scale(0.98); 54 | } 55 | 56 | .text { 57 | margin-top: 30px; 58 | } 59 | 60 | .form-control { 61 | position: relative; 62 | margin: 20px 0 40px; 63 | width: 300px; 64 | } 65 | 66 | .form-control input { 67 | background-color: transparent; 68 | border: 0; 69 | border-bottom: 2px #fff solid; 70 | display: block; 71 | width: 100%; 72 | padding: 15px 0; 73 | font-size: 18px; 74 | color: #fff; 75 | } 76 | 77 | .form-control input:focus, 78 | .form-control input:valid { 79 | outline: 0; 80 | border-bottom-color: lightblue; 81 | } 82 | 83 | .form-control label { 84 | position: absolute; 85 | top: 15px; 86 | left: 0; 87 | } 88 | 89 | .form-control label span { 90 | display: inline-block; 91 | font-size: 18px; 92 | min-width: 5px; 93 | transition: 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); 94 | } 95 | 96 | .form-control input:focus + label span, 97 | .form-control input:valid + label span { 98 | color: lightblue; 99 | transform: translateY(-30px); 100 | } 101 | -------------------------------------------------------------------------------- /009-sound-board/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Sound Board 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /009-sound-board/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/009-sound-board/output.gif -------------------------------------------------------------------------------- /009-sound-board/script.js: -------------------------------------------------------------------------------- 1 | const sounds = ["applause", "boo", "gasp", "tada", "victory", "wrong"]; 2 | 3 | sounds.forEach((sound) => { 4 | const btn = document.createElement("button"); 5 | btn.classList.add("btn"); 6 | 7 | btn.innerText = sound; 8 | 9 | btn.addEventListener("click", () => { 10 | stopSongs(); 11 | document.getElementById(sound).play(); 12 | }); 13 | 14 | document.getElementById("buttons").appendChild(btn); 15 | }); 16 | 17 | function stopSongs() { 18 | sounds.forEach((sound) => { 19 | const song = document.getElementById(sound); 20 | song.pause(); 21 | song.currentTime = 0; 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /009-sound-board/sounds/applause.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/009-sound-board/sounds/applause.mp3 -------------------------------------------------------------------------------- /009-sound-board/sounds/boo.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/009-sound-board/sounds/boo.mp3 -------------------------------------------------------------------------------- /009-sound-board/sounds/gasp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/009-sound-board/sounds/gasp.mp3 -------------------------------------------------------------------------------- /009-sound-board/sounds/tada.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/009-sound-board/sounds/tada.mp3 -------------------------------------------------------------------------------- /009-sound-board/sounds/victory.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/009-sound-board/sounds/victory.mp3 -------------------------------------------------------------------------------- /009-sound-board/sounds/wrong.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/009-sound-board/sounds/wrong.mp3 -------------------------------------------------------------------------------- /009-sound-board/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: rgb(161, 100, 223); 9 | font-family: "Poppins", sans-serif; 10 | display: flex; 11 | flex-wrap: wrap; 12 | align-items: center; 13 | justify-content: center; 14 | text-align: center; 15 | height: 100vh; 16 | overflow: hidden; 17 | margin: 0; 18 | } 19 | 20 | .btn { 21 | background-color: rebeccapurple; 22 | border-radius: 5px; 23 | border: none; 24 | color: white; 25 | margin: 1rem; 26 | padding: 1.5rem 3rem; 27 | font-size: 1.2rem; 28 | font-family: inherit; 29 | cursor: pointer; 30 | } 31 | 32 | .btn:hover { 33 | opacity: 0.9; 34 | } 35 | 36 | .btn:focus { 37 | outline: none; 38 | } 39 | -------------------------------------------------------------------------------- /010-dad-jokes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Dad Jokes 21 | 22 | 23 | 24 | 25 |
26 |

Don't Laugh Challenge

27 |
28 | //joke goes here 29 |
30 | 31 | 32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /010-dad-jokes/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/010-dad-jokes/output.gif -------------------------------------------------------------------------------- /010-dad-jokes/script.js: -------------------------------------------------------------------------------- 1 | const jokeEl = document.getElementById("joke"); 2 | const jokeBtn = document.getElementById("jokeBtn"); 3 | 4 | generateJoke(); 5 | 6 | 7 | // using .then 8 | // --------------- 9 | 10 | // function generateJoke() { 11 | // const config = { 12 | // headers: { 13 | // Accept: "application/json", 14 | // }, 15 | // }; 16 | // fetch("https://icanhazdadjoke.com/", config) 17 | // .then((res) => res.json()) 18 | // .then((data) => { 19 | // jokeEl.innerHTML = data.joke; 20 | // }); 21 | // } 22 | 23 | 24 | // using async await 25 | // ----------------- 26 | async function generateJoke() { 27 | const config = { 28 | headers: { 29 | Accept: "application/json", 30 | }, 31 | }; 32 | const res = await fetch("https://icanhazdadjoke.com/", config); 33 | const data = await res.json(); 34 | jokeEl.innerHTML = data.joke; 35 | } 36 | 37 | jokeBtn.addEventListener("click", generateJoke); 38 | -------------------------------------------------------------------------------- /010-dad-jokes/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #686de0; 9 | font-family: "Roboto", sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | padding: 20px; 18 | } 19 | 20 | .container { 21 | background-color: #fff; 22 | border-radius: 10px; 23 | box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.1), 0 6px 6px rgba(0, 0, 0, 0.1); 24 | padding: 50px 20px; 25 | text-align: center; 26 | max-width: 100%; 27 | width: 800px; 28 | } 29 | 30 | h3 { 31 | margin: 0; 32 | opacity: 0.5; 33 | letter-spacing: 2px; 34 | } 35 | 36 | .joke { 37 | font-size: 30px; 38 | letter-spacing: 1px; 39 | line-height: 40px; 40 | margin: 50px auto; 41 | max-width: 600px; 42 | } 43 | 44 | .btn { 45 | background-color: #9f68e0; 46 | border: 0; 47 | border-radius: 10px; 48 | color: white; 49 | box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.1), 0 6px 6px rgba(0, 0, 0, 0.1); 50 | padding: 14px 40px; 51 | font-size: 16px; 52 | cursor: pointer; 53 | } 54 | 55 | .btn:active { 56 | transform: scale(0.98); 57 | } 58 | 59 | .btn:focus { 60 | outline: 0; 61 | } 62 | -------------------------------------------------------------------------------- /011-event-keycodes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Event Key Codes 21 | 22 | 23 | 24 |
25 | 26 | 27 |
28 | Press any key to get the Key Code 29 |
30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /011-event-keycodes/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/011-event-keycodes/output.gif -------------------------------------------------------------------------------- /011-event-keycodes/script.js: -------------------------------------------------------------------------------- 1 | const insert = document.getElementById("insert"); 2 | 3 | window.addEventListener("keydown", (event) => { 4 | insert.innerHTML = ` 5 |
6 | ${event.key === " " ? "space" : event.key} 7 | event.key 8 |
9 |
10 | ${event.keyCode} 11 | event.keyCode 12 |
13 |
14 | ${event.code} 15 | event.code 16 |
17 | `; 18 | }); 19 | -------------------------------------------------------------------------------- /011-event-keycodes/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #e1e1e1; 9 | font-family: "Mulish", sans-serif; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | text-align: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | .key { 20 | border: 1px solid #999; 21 | background-color: #eee; 22 | box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1); 23 | display: inline-flex; 24 | align-items: center; 25 | font-size: 20px; 26 | padding: 20px; 27 | flex-direction: column; 28 | margin: 10px; 29 | font-weight: bold; 30 | min-width: 150px; 31 | position: relative; 32 | } 33 | 34 | .key small { 35 | position: absolute; 36 | top: -24px; 37 | left: 0; 38 | text-align: center; 39 | width: 100%; 40 | color: #555; 41 | font-size: 14px; 42 | } 43 | -------------------------------------------------------------------------------- /012-faq-collapse/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/012-faq-collapse/output.gif -------------------------------------------------------------------------------- /012-faq-collapse/script.js: -------------------------------------------------------------------------------- 1 | const toggles = document.querySelectorAll(".faq-toggle"); 2 | 3 | toggles.forEach((toggle) => { 4 | toggle.addEventListener("click", () => { 5 | toggle.parentNode.classList.toggle("active"); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /012-faq-collapse/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Mulish", sans-serif; 9 | background-color: #f0f0f0; 10 | } 11 | 12 | h1 { 13 | margin: 50px 0 30px; 14 | text-align: center; 15 | } 16 | 17 | .faq-container { 18 | max-width: 600px; 19 | margin: 0 auto; 20 | } 21 | 22 | .faq { 23 | background-color: transparent; 24 | border: 1px solid #9fa4a8; 25 | border-radius: 10px; 26 | margin: 20px 0; 27 | padding: 30px; 28 | position: relative; 29 | overflow: hidden; 30 | transition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55); 31 | } 32 | 33 | .faq.active { 34 | background-color: white; 35 | box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1), 0 3px 6px rgba(0, 0, 0, 0.1); 36 | } 37 | 38 | .faq.active::before, 39 | .faq.active::after { 40 | content: "\f075"; 41 | font-family: "Font Awesome 5 Free"; 42 | color: #2ecc71; 43 | font-size: 7rem; 44 | position: absolute; 45 | opacity: 0.2; 46 | top: 20px; 47 | left: 20px; 48 | z-index: 0; 49 | } 50 | 51 | .faq.active::before { 52 | color: #3498db; 53 | top: -10px; 54 | left: -10px; 55 | transform: rotateY(180deg); 56 | } 57 | 58 | .faq-title { 59 | margin: 0 35px 0 0; 60 | } 61 | 62 | .faq-text { 63 | display: none; 64 | margin: 30px 0 0; 65 | } 66 | 67 | .faq.active .faq-text { 68 | display: block; 69 | } 70 | 71 | .faq-toggle { 72 | background-color: transparent; 73 | border: 0; 74 | border-radius: 50%; 75 | cursor: pointer; 76 | display: flex; 77 | align-items: center; 78 | justify-content: center; 79 | font-size: 16px; 80 | position: absolute; 81 | padding: 0; 82 | top: 30px; 83 | right: 30px; 84 | height: 30px; 85 | width: 30px; 86 | } 87 | 88 | .faq-toggle:focus { 89 | outline: 0; 90 | } 91 | 92 | .faq-toggle .fa-times { 93 | color: white; 94 | display: none; 95 | } 96 | 97 | .faq.active .faq-toggle .fa-times { 98 | display: block; 99 | } 100 | 101 | .faq.active .faq-toggle .fa-chevron-down { 102 | display: none; 103 | } 104 | 105 | .faq.active .faq-toggle { 106 | background-color: #9fa4a8; 107 | } 108 | -------------------------------------------------------------------------------- /013-random-choice-picker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Random Choice Picker 21 | 22 | 23 | 24 |
25 |

Enter all of the choices divided by a comma (',') 26 |
Press Enter when you are done. 27 |

28 | 29 | 30 | 31 |
32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /013-random-choice-picker/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/013-random-choice-picker/output.gif -------------------------------------------------------------------------------- /013-random-choice-picker/script.js: -------------------------------------------------------------------------------- 1 | const tagsEl = document.getElementById("tags"); 2 | const textarea = document.getElementById("textarea"); 3 | 4 | textarea.focus(); 5 | 6 | textarea.addEventListener("keyup", (e) => { 7 | createTags(e.target.value); 8 | if (e.key === "Enter") { 9 | setTimeout(() => { 10 | e.target.value = ""; 11 | }, 10); 12 | randomSelect(); 13 | } 14 | }); 15 | 16 | function createTags(input) { 17 | const tags = input 18 | .split(",") 19 | .filter((tag) => tag.trim() != "") 20 | .map((tag) => tag.trim()); 21 | 22 | tagsEl.innerHTML = ""; 23 | tags.forEach((tag) => { 24 | const tagEl = document.createElement("span"); 25 | tagEl.classList.add("tag"); 26 | tagEl.innerText = tag; 27 | tagsEl.appendChild(tagEl); 28 | }); 29 | } 30 | 31 | function randomSelect() { 32 | const times = 30; 33 | const interval = setInterval(() => { 34 | const randomTag = pickRandomTag(); 35 | highlightTag(randomTag); 36 | setTimeout(() => { 37 | unHighlightTag(randomTag); 38 | }, 100); 39 | }, 100); 40 | 41 | setTimeout(() => { 42 | clearInterval(interval); 43 | setTimeout(() => { 44 | const randomTag = pickRandomTag(); 45 | highlightTag(randomTag); 46 | }, 100); 47 | }, times * 100); 48 | } 49 | 50 | function pickRandomTag() { 51 | const tags = document.querySelectorAll(".tag"); 52 | return tags[Math.floor(Math.random() * tags.length)]; 53 | } 54 | 55 | function highlightTag(tag) { 56 | tag.classList.add("highlight"); 57 | } 58 | 59 | function unHighlightTag(tag) { 60 | tag.classList.remove("highlight"); 61 | } 62 | -------------------------------------------------------------------------------- /013-random-choice-picker/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Mulish&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #2b88f0; 9 | font-family: 'Mulish', sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | h3 { 20 | color: white; 21 | margin: 10px 0 20px; 22 | text-align: center; 23 | } 24 | 25 | .container { 26 | width: 500px; 27 | } 28 | 29 | textarea { 30 | border: none; 31 | display: block; 32 | width: 100%; 33 | height: 100px; 34 | font-family: inherit; 35 | padding: 10px; 36 | margin: 0 0 20px; 37 | font-size: 16px; 38 | } 39 | 40 | .tag{ 41 | background-color: #f0932b; 42 | color: white; 43 | border-radius: 50px; 44 | padding: 10px 20px; 45 | margin: 0 5px 10px 0; 46 | font-size: 14px; 47 | display: inline-block; 48 | } 49 | 50 | .tag.highlight{ 51 | background-color: #273c75; 52 | } 53 | -------------------------------------------------------------------------------- /014-animated-navigation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Animated Navigation 21 | 22 | 23 | 24 | 25 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /014-animated-navigation/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/014-animated-navigation/output.gif -------------------------------------------------------------------------------- /014-animated-navigation/script.js: -------------------------------------------------------------------------------- 1 | const toggle = document.getElementById("toggle"); 2 | const nav = document.getElementById("nav"); 3 | 4 | toggle.addEventListener("click", () => { 5 | nav.classList.toggle("active"); 6 | }); 7 | -------------------------------------------------------------------------------- /014-animated-navigation/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #eafbff; 9 | background-image: linear-gradient( 10 | to bottom, 11 | #eafbff 0%, 12 | #eafbff 50%, 13 | #5290f9 50%, 14 | #5290f9 100% 15 | ); 16 | font-family: "Mulish", sans-serif; 17 | display: flex; 18 | align-items: center; 19 | justify-content: center; 20 | height: 100vh; 21 | margin: 0; 22 | } 23 | 24 | nav{ 25 | background-color: white; 26 | padding: 20px; 27 | width: 80px; 28 | display: flex; 29 | align-items: center; 30 | justify-content: center; 31 | border-radius: 3px; 32 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); 33 | transition: width 0.6s linear; 34 | } 35 | 36 | nav.active{ 37 | width: 350px; 38 | } 39 | 40 | nav ul{ 41 | display: flex; 42 | list-style: none; 43 | padding: 0; 44 | margin: 0; 45 | width: 0; 46 | transition: width 0.6s linear; 47 | } 48 | 49 | nav.active ul { 50 | width: 100%; 51 | } 52 | 53 | nav ul li { 54 | transform: rotateY(0deg); 55 | opacity: 0; 56 | transition: transform 0.6s linear, opacity 0.6s linear; 57 | } 58 | 59 | nav.active ul li { 60 | opacity: 1; 61 | transform: rotateY(360deg); 62 | } 63 | 64 | nav ul a{ 65 | position: relative; 66 | color: black; 67 | text-decoration: none; 68 | margin: 0 10px; 69 | } 70 | 71 | .icon { 72 | background-color: #fff; 73 | border: 0; 74 | cursor: pointer; 75 | padding: 0; 76 | position: relative; 77 | height: 30px; 78 | width: 30px; 79 | } 80 | 81 | .icon:focus{ 82 | outline: 0; 83 | } 84 | 85 | .icon .line{ 86 | background-color: #5290f9; 87 | height: 2px; 88 | width: 20px; 89 | position: absolute; 90 | top: 10px; 91 | left: 5px; 92 | transition: transform 0.6s linear; 93 | } 94 | 95 | .icon .line2{ 96 | top: auto; 97 | bottom: 10px; 98 | } 99 | 100 | nav.active .icon .line1{ 101 | transform: rotate(-765deg) translateY(5.5px); 102 | } 103 | 104 | nav.active .icon .line2{ 105 | transform: rotate(765deg) translateY(-5.5px); 106 | } 107 | 108 | -------------------------------------------------------------------------------- /015-increment-counter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Increment Counter 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | Twitter Follower 29 |
30 | 31 |
32 | 33 |
34 | Youtube Subscriber 35 |
36 | 37 |
38 | 39 |
40 | Facebook Follower 41 |
42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /015-increment-counter/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/015-increment-counter/output.gif -------------------------------------------------------------------------------- /015-increment-counter/script.js: -------------------------------------------------------------------------------- 1 | const counters = document.querySelectorAll(".counter"); 2 | 3 | counters.forEach((counter) => { 4 | counter.innerText = "0"; 5 | 6 | const updateCounter = () => { 7 | const target = +counter.getAttribute("data-target"); 8 | const c = +counter.innerText; 9 | 10 | const increment = target / 200; 11 | 12 | if(c < target){ 13 | counter.innerText = `${Math.ceil(c + increment)}`; 14 | setTimeout(updateCounter, 1); 15 | }else{ 16 | counter.innerText = target; 17 | } 18 | }; 19 | 20 | updateCounter(); 21 | }); 22 | -------------------------------------------------------------------------------- /015-increment-counter/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #8e44ad; 9 | color: white; 10 | font-family: 'Roboto Mono', monospace; 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | .counter-container{ 20 | display: flex; 21 | flex-direction: column; 22 | align-items: center; 23 | justify-content: center; 24 | text-align: center; 25 | margin: 30px 50px; 26 | } 27 | 28 | .counter{ 29 | font-size: 60px; 30 | margin-top: 10px; 31 | } 32 | 33 | @media (max-width: 700px) { 34 | body{ 35 | flex-direction: column; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /016-drink-water/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Drink Water 21 | 22 | 23 | 24 | 25 |

Drink Water

26 |

Goal: 2 Liters

27 | 28 |
29 |
30 | 31 | Remained 32 |
33 |
34 |
35 | 36 |

Select how many glasses of water that you have drink

37 | 38 |
39 |
250 ml
40 |
250 ml
41 |
250 ml
42 |
250 ml
43 |
250 ml
44 |
250 ml
45 |
250 ml
46 |
250 ml
47 |
48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /016-drink-water/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/016-drink-water/output.gif -------------------------------------------------------------------------------- /016-drink-water/script.js: -------------------------------------------------------------------------------- 1 | const smallCups = document.querySelectorAll(".cup-small"); 2 | const liters = document.getElementById("liters"); 3 | const percentage = document.getElementById("percentage"); 4 | const remained = document.getElementById("remained"); 5 | 6 | updateBigCup(); 7 | 8 | smallCups.forEach((cup, idx) => { 9 | cup.addEventListener("click", () => highlightCups(idx)); 10 | }); 11 | 12 | function highlightCups(idx) { 13 | if (idx != smallCups.length - 1) { 14 | if ( 15 | smallCups[idx].classList.contains("full") && 16 | !smallCups[idx].nextElementSibling.classList.contains("full") 17 | ) { 18 | idx--; 19 | } 20 | } 21 | 22 | smallCups.forEach((cup, idx2) => { 23 | if (idx2 <= idx) { 24 | cup.classList.add("full"); 25 | } else { 26 | cup.classList.remove("full"); 27 | } 28 | }); 29 | 30 | updateBigCup(); 31 | } 32 | 33 | function updateBigCup() { 34 | const fullCups = document.querySelectorAll(".cup-small.full").length; 35 | const totalCups = smallCups.length; 36 | 37 | if (fullCups == 0) { 38 | percentage.style.visibility = "hidden"; 39 | percentage.style.height = 0; 40 | } else { 41 | percentage.style.visibility = "visible"; 42 | percentage.style.height = `${(fullCups / totalCups) * 330}px`; 43 | percentage.innerText = `${(fullCups / totalCups) * 100}%`; 44 | } 45 | 46 | if (fullCups === totalCups) { 47 | remained.style.visibility = "hidden"; 48 | remained.style.height = 0; 49 | } else { 50 | remained.style.visibility = "visible"; 51 | liters.innerText = `${2 - (250 * fullCups) / 1000} L`; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /016-drink-water/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600&display=swap'); 2 | 3 | :root{ 4 | --border-color: #144fc6; 5 | --fill-color: #6ab3f8; 6 | } 7 | 8 | * { 9 | box-sizing: border-box; 10 | } 11 | 12 | body { 13 | background-color: #3494e4; 14 | color: #fff; 15 | font-family: "Montserrat", sans-serif; 16 | display: flex; 17 | flex-direction: column; 18 | align-items: center; 19 | margin-bottom: 40px; 20 | } 21 | 22 | h1{ 23 | margin: 10px 0 0; 24 | } 25 | 26 | h3{ 27 | font-weight: 400; 28 | margin: 10px 0; 29 | } 30 | 31 | .cup{ 32 | background-color: white; 33 | border: 4px solid var(--border-color); 34 | color: var(--border-color); 35 | border-radius: 0 0 40px 40px; 36 | height: 330px; 37 | width: 150px; 38 | margin: 30px 0; 39 | display: flex; 40 | flex-direction: column; 41 | overflow: hidden; 42 | } 43 | 44 | .cup.cup-small{ 45 | width: 50px; 46 | height: 95px; 47 | border-radius: 0 0 15px 15px; 48 | background-color: rgba(255, 255, 255, 0.9); 49 | cursor: pointer; 50 | font-size: 14px; 51 | align-items: center; 52 | justify-content: center; 53 | text-align: center; 54 | margin: 5px; 55 | transition: all 0.3s ease; 56 | } 57 | 58 | .cup.cup-small.full{ 59 | background-color: var(--fill-color); 60 | color: white; 61 | } 62 | 63 | .cups{ 64 | display: flex; 65 | flex-wrap: wrap; 66 | width: 280px; 67 | justify-content: center; 68 | align-content: center; 69 | } 70 | 71 | .remained{ 72 | display: flex; 73 | flex-direction: column; 74 | align-items: center; 75 | justify-content: center; 76 | text-align: center; 77 | flex: 1; 78 | transition: all 0.3s ease; 79 | } 80 | 81 | .remained span{ 82 | font-size: 20px; 83 | font-weight: bold; 84 | } 85 | 86 | .remained small{ 87 | font-size: 12px; 88 | } 89 | 90 | .percentage{ 91 | background-color: var(--fill-color); 92 | font-size: 30px; 93 | display: flex; 94 | align-items: center; 95 | justify-content: center; 96 | font-weight: bold; 97 | font-size: 30px; 98 | height: 0; 99 | transition: 0.3s ease; 100 | } 101 | 102 | .text{ 103 | text-align: center; 104 | margin: 0 0 5px; 105 | } -------------------------------------------------------------------------------- /017-movie-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Movie App 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 |
29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /017-movie-app/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/017-movie-app/output.gif -------------------------------------------------------------------------------- /017-movie-app/script.js: -------------------------------------------------------------------------------- 1 | const API_URL = 2 | "https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=3fd2be6f0c70a2a598f084ddfb75487c&page=1"; 3 | const IMG_PATH = "https://image.tmdb.org/t/p/w1280"; 4 | const SEARCH_API = 5 | 'https://api.themoviedb.org/3/search/movie?api_key=3fd2be6f0c70a2a598f084ddfb75487c&query="'; 6 | 7 | const form = document.getElementById("form"); 8 | const search = document.getElementById("search"); 9 | const main = document.getElementById("main"); 10 | 11 | getMovies(API_URL); 12 | 13 | async function getMovies(url) { 14 | const res = await fetch(url); 15 | const data = await res.json(); 16 | console.log(data.results); 17 | showMovies(data.results); 18 | } 19 | 20 | form.addEventListener("submit", (e) => { 21 | e.preventDefault(); 22 | 23 | const searchTerm = search.value; 24 | 25 | if (searchTerm && searchTerm !== "") { 26 | getMovies(SEARCH_API + searchTerm); 27 | search.value = ""; 28 | } else { 29 | window.location.reload(); 30 | } 31 | }); 32 | 33 | function showMovies(movies) { 34 | main.innerHTML = ""; 35 | movies.forEach((movie) => { 36 | const { title, poster_path, vote_average, overview } = movie; 37 | const movieEl = document.createElement("div"); 38 | movieEl.classList.add("movie"); 39 | 40 | movieEl.innerHTML = ` 41 | ${title} 42 |
43 |

${title}

44 | ${vote_average} 45 |
46 |
47 |

${title}

48 |

Overview

49 | ${overview} 50 |
51 | `; 52 | 53 | main.appendChild(movieEl); 54 | }); 55 | } 56 | 57 | function getClassByRate(vote) { 58 | if (vote >= 8) { 59 | return "green"; 60 | } else if (vote >= 5) { 61 | return "orange"; 62 | } else { 63 | return "red"; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /017-movie-app/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap"); 2 | :root { 3 | --primary-color: #22254b; 4 | --secondary-color: #373b69; 5 | } 6 | 7 | * { 8 | box-sizing: border-box; 9 | } 10 | 11 | body { 12 | background-color: var(--primary-color); 13 | font-family: "Poppins", sans-serif; 14 | margin: 0; 15 | } 16 | 17 | header { 18 | padding: 1rem; 19 | display: flex; 20 | justify-content: flex-end; 21 | background-color: var(--secondary-color); 22 | } 23 | 24 | .search { 25 | background-color: transparent; 26 | border: 2px solid var(--primary-color); 27 | border-radius: 50px; 28 | font-family: inherit; 29 | font-size: 1rem; 30 | padding: 0.5rem 1rem; 31 | color: white; 32 | } 33 | 34 | .search::placeholder { 35 | color: #7378c5; 36 | } 37 | 38 | .search:focus { 39 | outline: none; 40 | background-color: var(--primary-color); 41 | } 42 | 43 | main { 44 | display: flex; 45 | justify-content: center; 46 | align-items: center; 47 | flex-wrap: wrap; 48 | gap: 1rem; 49 | padding: 2rem; 50 | } 51 | 52 | .movie { 53 | width: 300px; 54 | height: 600px; 55 | background-color: var(--secondary-color); 56 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2); 57 | overflow: hidden; 58 | position: relative; 59 | border-radius: 3px; 60 | cursor: pointer; 61 | } 62 | 63 | .movie img { 64 | width: 100%; 65 | } 66 | 67 | .movie-info { 68 | color: #eee; 69 | display: flex; 70 | align-items: center; 71 | justify-content: space-between; 72 | padding: 0.5rem 1rem 1rem; 73 | letter-spacing: 0.5px; 74 | } 75 | 76 | .movie-info span { 77 | background-color: var(--primary-color); 78 | padding: 0.25rem; 79 | border-radius: 3px; 80 | font-weight: bold; 81 | } 82 | 83 | .movie-info span.green { 84 | color: greenyellow; 85 | } 86 | 87 | .movie-info span.orange { 88 | color: orange; 89 | } 90 | 91 | .movie-info span.red { 92 | color: red; 93 | } 94 | 95 | .overview { 96 | background-color: #fff; 97 | padding: 2rem; 98 | position: absolute; 99 | left: 0; 100 | bottom: 0; 101 | right: 0; 102 | max-height: 100%; 103 | transform: translateY(101%); 104 | transition: transform 0.3s ease-in; 105 | } 106 | 107 | .movie:hover .overview { 108 | transform: translateY(0); 109 | } 110 | -------------------------------------------------------------------------------- /018-background-slider/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Background Slider 21 | 22 | 23 | 24 |
25 |
28 |
31 | 32 |
35 | 36 |
39 | 40 |
43 | 44 | 47 | 48 | 51 |
52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /018-background-slider/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/018-background-slider/output.gif -------------------------------------------------------------------------------- /018-background-slider/script.js: -------------------------------------------------------------------------------- 1 | 2 | const body = document.body; 3 | const slides = document.querySelectorAll(".slide"); 4 | const leftBtn = document.getElementById("left"); 5 | const rightBtn = document.getElementById("right"); 6 | 7 | let activeSlide = 0; 8 | 9 | rightBtn.addEventListener("click", () => { 10 | activeSlide++; 11 | 12 | if (activeSlide > slides.length - 1) { 13 | activeSlide = 0; 14 | } 15 | 16 | setBgToBody(); 17 | setActiveSlide(); 18 | }); 19 | 20 | leftBtn.addEventListener("click", () => { 21 | activeSlide--; 22 | 23 | if (activeSlide < 0) { 24 | activeSlide = slides.length - 1; 25 | } 26 | 27 | setBgToBody(); 28 | setActiveSlide(); 29 | }); 30 | 31 | setBgToBody(); 32 | 33 | function setBgToBody() { 34 | body.style.backgroundImage = slides[activeSlide].style.backgroundImage; 35 | } 36 | 37 | function setActiveSlide() { 38 | slides.forEach((slide) => slide.classList.remove("active")); 39 | 40 | slides[activeSlide].classList.add("active"); 41 | } -------------------------------------------------------------------------------- /018-background-slider/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: 'Roboto', sans-serif; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | overflow: hidden; 15 | margin: 0; 16 | background-position: center center; 17 | background-size: cover; 18 | transition: 0.4s; 19 | } 20 | 21 | body::before { 22 | content: ''; 23 | position: absolute; 24 | top: 0; 25 | left: 0; 26 | width: 100%; 27 | height: 100vh; 28 | background-color: rgba(0, 0, 0, 0.7); 29 | z-index: -1; 30 | } 31 | 32 | .slider-container { 33 | box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); 34 | height: 70vh; 35 | width: 70vw; 36 | position: relative; 37 | overflow: hidden; 38 | } 39 | 40 | .slide { 41 | opacity: 0; 42 | height: 100vh; 43 | width: 100vw; 44 | background-position: center center; 45 | background-size: cover; 46 | position: absolute; 47 | top: -15vh; 48 | left: -15vw; 49 | transition: 0.4s ease; 50 | z-index: 1; 51 | } 52 | 53 | .slide.active { 54 | opacity: 1; 55 | } 56 | 57 | .arrow { 58 | position: fixed; 59 | background-color: transparent; 60 | color: #fff; 61 | padding: 20px; 62 | font-size: 30px; 63 | border: 2px solid orange; 64 | top: 50%; 65 | transform: translateY(-50%); 66 | cursor: pointer; 67 | } 68 | 69 | .arrow:focus { 70 | outline: 0; 71 | } 72 | 73 | .left-arrow { 74 | left: calc(15vw - 65px); 75 | } 76 | 77 | .right-arrow { 78 | right: calc(15vw - 65px); 79 | } -------------------------------------------------------------------------------- /019-theme-clock/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Theme Clock 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | 35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /019-theme-clock/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/019-theme-clock/output.gif -------------------------------------------------------------------------------- /019-theme-clock/script.js: -------------------------------------------------------------------------------- 1 | const hourEl = document.querySelector(".hour"); 2 | const minuteEl = document.querySelector(".minute"); 3 | const secondEl = document.querySelector(".second"); 4 | const timeEl = document.querySelector(".time"); 5 | const dateEl = document.querySelector(".date"); 6 | const toggle = document.querySelector(".toggle"); 7 | 8 | const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; 9 | 10 | const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; 11 | 12 | toggle.addEventListener("click", (e) => { 13 | const html = document.querySelector("html"); 14 | if (html.classList.contains("dark")) { 15 | html.classList.remove("dark"); 16 | e.target.innerHTML = "Dark Mode"; 17 | } else { 18 | html.classList.add("dark"); 19 | e.target.innerHTML = "Light Mode"; 20 | } 21 | }); 22 | 23 | function setTime() { 24 | const time = new Date(); 25 | const month = time.getMonth(); 26 | const day = time.getDay(); 27 | const date = time.getDate(); 28 | const hours = time.getHours(); 29 | const hoursForClock = hours % 12; 30 | const minutes = time.getMinutes(); 31 | const seconds = time.getSeconds(); 32 | const ampm = hours >= 12 ? "PM" : "AM"; 33 | 34 | hourEl.style.transform = `translate(-50%, -100%) rotate(${scale(hoursForClock, 0, 11, 0, 360)}deg)`; 35 | minuteEl.style.transform = `translate(-50%, -100%) rotate(${scale(minutes, 0, 59, 0, 360)}deg)`; 36 | secondEl.style.transform = `translate(-50%, -100%) rotate(${scale(seconds, 0, 59, 0, 360)}deg)`; 37 | 38 | timeEl.innerHTML = `${hoursForClock}:${minutes < 10 ? `0${minuteEl}` : minutes} ${ampm}`; 39 | dateEl.innerHTML = `${days[day]}, ${months[month]} ${date}`; 40 | 41 | } 42 | 43 | const scale = (num, in_min, in_max, out_min, out_max) => { 44 | return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min; 45 | }; 46 | 47 | setInterval(setTime, 1000); 48 | -------------------------------------------------------------------------------- /020-button-ripple-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Button Ripple Effect 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /020-button-ripple-effect/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/020-button-ripple-effect/output.gif -------------------------------------------------------------------------------- /020-button-ripple-effect/script.js: -------------------------------------------------------------------------------- 1 | const buttons = document.querySelectorAll(".ripple"); 2 | 3 | buttons.forEach((button) => { 4 | button.addEventListener("click", function (e) { 5 | const x = e.clientX; 6 | const y = e.clientY; 7 | 8 | const buttonTop = e.target.offsetTop; 9 | const buttonLeft = e.target.offsetLeft; 10 | 11 | const xInside = x - buttonLeft; 12 | const yInside = y - buttonTop; 13 | 14 | const circle = document.createElement("span"); 15 | circle.classList.add("circle"); 16 | circle.style.top = yInside + "px"; 17 | circle.style.left = xInside + "px"; 18 | 19 | this.appendChild(circle); 20 | 21 | setTimeout(() => circle.remove(), 5000); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /020-button-ripple-effect/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #000; 9 | font-family: "Mulish", sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | button { 20 | background-color: purple; 21 | color: white; 22 | border: 1px purple solid; 23 | font-size: 14px; 24 | text-transform: uppercase; 25 | letter-spacing: 2px; 26 | padding: 20px 30px; 27 | overflow: hidden; 28 | margin: 10px 0; 29 | cursor: pointer; 30 | position: relative; 31 | } 32 | 33 | button:focus { 34 | outline: none; 35 | } 36 | 37 | button .circle { 38 | position: absolute; 39 | background-color: white; 40 | width: 100px; 41 | height: 100px; 42 | border-radius: 50%; 43 | transform: translate(-50%, -50%) scale(0); 44 | animation: scale 0.5s ease-out; 45 | } 46 | 47 | @keyframes scale { 48 | to { 49 | transform: translate(-50%, -50%) scale(3); 50 | opacity: 0; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /021-drag-n-drop/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Drag N Drop 21 | 22 | 23 | 24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /021-drag-n-drop/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/021-drag-n-drop/output.gif -------------------------------------------------------------------------------- /021-drag-n-drop/script.js: -------------------------------------------------------------------------------- 1 | const fill = document.querySelector(".fill"); 2 | const empties = document.querySelectorAll(".empty"); 3 | 4 | fill.addEventListener("dragstart", dragStart); 5 | fill.addEventListener("dragend", dragEnd); 6 | 7 | for (const empty of empties) { 8 | empty.addEventListener("dragover", dragOver); 9 | empty.addEventListener("dragenter", dragEnter); 10 | empty.addEventListener("dragleave", dragleave); 11 | empty.addEventListener("drop", dragDrop); 12 | } 13 | 14 | function dragStart() { 15 | this.className += " hold"; 16 | setTimeout(() => (this.className = ""), 0); 17 | } 18 | 19 | function dragEnd() { 20 | this.className = "fill"; 21 | } 22 | 23 | function dragOver(e) { 24 | e.preventDefault(); 25 | } 26 | 27 | function dragEnter(e) { 28 | e.preventDefault(); 29 | this.className += " hovered"; 30 | } 31 | 32 | function dragleave() { 33 | this.className = "empty"; 34 | } 35 | 36 | function dragDrop() { 37 | this.className = "empty"; 38 | this.append(fill); 39 | } 40 | -------------------------------------------------------------------------------- /021-drag-n-drop/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | background-color: steelblue; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | height: 100vh; 11 | overflow: hidden; 12 | margin: 0; 13 | } 14 | 15 | .empty { 16 | height: 150px; 17 | width: 150px; 18 | margin: 10px; 19 | border: solid 3px black; 20 | background: white; 21 | } 22 | 23 | .fill { 24 | background-image: url("https://source.unsplash.com/random/150x150"); 25 | height: 145px; 26 | width: 145px; 27 | cursor: pointer; 28 | } 29 | 30 | .hold { 31 | border: solid 5px #ccc; 32 | } 33 | 34 | .hovered { 35 | background-color: #333; 36 | border-color: #fff; 37 | border-style: dashed; 38 | } 39 | 40 | @media (max-width: 800px) { 41 | body { 42 | flex-direction: column; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /022-drawing-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Drawing App 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 6 30 | 31 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /022-drawing-app/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/022-drawing-app/output.gif -------------------------------------------------------------------------------- /022-drawing-app/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #f5f5f5; 9 | font-family: "Mulish", sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | margin: 0; 16 | } 17 | 18 | canvas { 19 | border: 2px solid steelblue; 20 | cursor: crosshair; 21 | } 22 | 23 | .toolbox { 24 | background-color: steelblue; 25 | display: flex; 26 | width: fit-content; 27 | justify-content: center; 28 | align-items: center; 29 | gap: 0.5rem; 30 | border-radius: 50px; 31 | padding: 1rem; 32 | margin: 5px; 33 | } 34 | 35 | .toolbox > * { 36 | background-color: white; 37 | border: none; 38 | display: inline-flex; 39 | align-items: center; 40 | justify-content: center; 41 | font-size: 1.5rem; 42 | height: 40px; 43 | width: 40px; 44 | padding: 0.25rem; 45 | border-radius: 50%; 46 | outline: none; 47 | cursor: pointer; 48 | } 49 | 50 | input[type="color"]::-webkit-color-swatch-wrapper, 51 | input[type="color"]::-webkit-color-swatch { 52 | border: none; 53 | } 54 | 55 | input[type="color"]::-moz-color-swatch { 56 | border: none; 57 | } 58 | 59 | input[type="color"] { 60 | border: none; 61 | outline: none; 62 | } 63 | -------------------------------------------------------------------------------- /023-kinetic-css-loader/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Kinetic CSS Loader 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /023-kinetic-css-loader/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/023-kinetic-css-loader/output.gif -------------------------------------------------------------------------------- /023-kinetic-css-loader/script.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /023-kinetic-css-loader/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | background-color: #2c3e50; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | height: 100vh; 11 | overflow: hidden; 12 | margin: 0; 13 | } 14 | 15 | .kinetic { 16 | position: relative; 17 | height: 80px; 18 | width: 80px; 19 | } 20 | 21 | .kinetic::after, 22 | .kinetic::before { 23 | content: ""; 24 | position: absolute; 25 | top: 0; 26 | left: 0; 27 | width: 0; 28 | height: 0; 29 | border: 50px solid transparent; 30 | border-bottom-color: white; 31 | animation: rotateA 2s linear infinite 0.5s; 32 | } 33 | 34 | .kinetic::before { 35 | transform: rotate(90deg); 36 | animation: rotateB 2s linear infinite; 37 | } 38 | 39 | @keyframes rotateA { 40 | 0%, 41 | 25% { 42 | transform: rotate(0deg); 43 | } 44 | 45 | 50%, 46 | 75% { 47 | transform: rotate(180deg); 48 | } 49 | 50 | 100% { 51 | transform: rotate(360deg); 52 | } 53 | } 54 | 55 | @keyframes rotateB { 56 | 0%, 57 | 25% { 58 | transform: rotate(90deg); 59 | } 60 | 61 | 50%, 62 | 75% { 63 | transform: rotate(270deg); 64 | } 65 | 66 | 100% { 67 | transform: rotate(450deg); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /024-content-placeholder/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Content Placeholder 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 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /024-content-placeholder/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/024-content-placeholder/output.gif -------------------------------------------------------------------------------- /024-content-placeholder/script.js: -------------------------------------------------------------------------------- 1 | const header = document.getElementById("header"); 2 | const title = document.getElementById("title"); 3 | const excerpt = document.getElementById("excerpt"); 4 | const profile_img = document.getElementById("profile_img"); 5 | const name = document.getElementById("name"); 6 | const date = document.getElementById("date"); 7 | 8 | const animated_bgs = document.querySelectorAll(".animated-bg"); 9 | const animated_bg_texts = document.querySelectorAll(".animated-bg-text"); 10 | 11 | setTimeout(getData, 2500); 12 | 13 | function getData() { 14 | header.innerHTML = 15 | ''; 16 | title.innerHTML = "Lorem ipsum dolor sit amet"; 17 | excerpt.innerHTML = 18 | "Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore perferendis"; 19 | profile_img.innerHTML = 20 | ''; 21 | name.innerHTML = "John Doe"; 22 | date.innerHTML = "Oct 08, 2020"; 23 | 24 | animated_bgs.forEach((bg) => bg.classList.remove("animated-bg")); 25 | animated_bg_texts.forEach((bg) => bg.classList.remove("animated-bg-text")); 26 | } 27 | -------------------------------------------------------------------------------- /024-content-placeholder/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Mulish&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #ecf0f1; 9 | font-family: "Mulish", sans-serif; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | overflow: hidden; 15 | margin: 0; 16 | } 17 | 18 | img { 19 | max-width: 100%; 20 | } 21 | 22 | .card { 23 | box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); 24 | border-radius: 10px; 25 | overflow: hidden; 26 | width: 350px; 27 | } 28 | 29 | .card-header { 30 | height: 200px; 31 | 32 | } 33 | 34 | .card-header img{ 35 | object-fit: cover; 36 | height: 100%; 37 | width: 100%; 38 | } 39 | 40 | .card-content{ 41 | background-color: #fff; 42 | padding: 30px; 43 | } 44 | 45 | .card-title{ 46 | height: 20px; 47 | margin: 0; 48 | } 49 | 50 | .card-excerpt{ 51 | color: #777; 52 | margin: 10px 0 20px; 53 | } 54 | 55 | .author{ 56 | display: flex; 57 | } 58 | 59 | .profile-img{ 60 | border-radius: 50%; 61 | overflow: hidden; 62 | height: 40px; 63 | width: 40px; 64 | } 65 | 66 | .author-info{ 67 | display: flex; 68 | flex-direction: column; 69 | justify-content: space-around; 70 | margin-left: 10px; 71 | width: 100px; 72 | } 73 | 74 | .author-info small{ 75 | color: #aaa; 76 | margin-top: 5px; 77 | } 78 | 79 | .animated-bg { 80 | background-image: linear-gradient( 81 | to right, 82 | #f6f7f8 0%, 83 | #edeef1 10%, 84 | #f6f7f8 20%, 85 | #f6f7f8 100% 86 | ); 87 | background-size: 200% 100%; 88 | animation: bgPos 1s linear infinite; 89 | } 90 | 91 | .animated-bg-text { 92 | border-radius: 50px; 93 | display: inline-block; 94 | margin: 0; 95 | height: 10px; 96 | width: 100%; 97 | } 98 | 99 | @keyframes bgPos { 100 | 0% { 101 | background-position: 50% 0; 102 | } 103 | 104 | 100% { 105 | background-position: -150% 0; 106 | } 107 | } -------------------------------------------------------------------------------- /025-sticky-navbar/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/025-sticky-navbar/output.gif -------------------------------------------------------------------------------- /025-sticky-navbar/script.js: -------------------------------------------------------------------------------- 1 | const nav = document.querySelector(".nav"); 2 | window.addEventListener("scroll", fixNav); 3 | 4 | function fixNav() { 5 | if (window.scrollY > nav.offsetHeight + 150) { 6 | nav.classList.add("active"); 7 | } else { 8 | nav.classList.remove("active"); 9 | } 10 | } -------------------------------------------------------------------------------- /025-sticky-navbar/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Open+Sans&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: "Open Sans", sans-serif; 11 | color: #222; 12 | padding-bottom: 50px; 13 | } 14 | 15 | .container { 16 | max-width: 1200px; 17 | margin: 0 auto; 18 | } 19 | 20 | .nav { 21 | position: fixed; 22 | background-color: #222; 23 | top: 0; 24 | left: 0; 25 | right: 0; 26 | transition: all 0.3s ease-in-out; 27 | } 28 | 29 | .nav .container { 30 | display: flex; 31 | justify-content: space-between; 32 | align-items: center; 33 | padding: 20px 0; 34 | transition: all 0.3s ease-in-out; 35 | } 36 | 37 | .nav ul { 38 | display: flex; 39 | list-style-type: none; 40 | align-items: center; 41 | justify-content: center; 42 | } 43 | 44 | .nav a { 45 | color: #fff; 46 | text-decoration: none; 47 | padding: 7px 15px; 48 | transition: all 0.3s ease-in-out; 49 | } 50 | 51 | .nav.active { 52 | background-color: #fff; 53 | box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); 54 | } 55 | 56 | .nav.active a { 57 | color: #000; 58 | } 59 | 60 | .nav.active .container { 61 | padding: 10px 0; 62 | } 63 | 64 | .nav a.current, 65 | .nav a:hover { 66 | color: #c0392b; 67 | font-weight: bold; 68 | } 69 | 70 | .hero { 71 | background-image: url("https://images.pexels.com/photos/450035/pexels-photo-450035.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"); 72 | background-repeat: no-repeat; 73 | background-size: cover; 74 | background-position: bottom center; 75 | height: 100vh; 76 | color: #fff; 77 | display: flex; 78 | justify-content: center; 79 | align-items: center; 80 | text-align: center; 81 | position: relative; 82 | margin-bottom: 20px; 83 | z-index: -2; 84 | } 85 | 86 | .hero::before { 87 | content: ""; 88 | position: absolute; 89 | top: 0; 90 | left: 0; 91 | height: 100%; 92 | width: 100%; 93 | background-color: rgba(0, 0, 0, 0.6); 94 | z-index: -1; 95 | } 96 | 97 | .hero h1 { 98 | font-size: 46px; 99 | margin: -20px 0 20px; 100 | } 101 | 102 | .hero p { 103 | font-size: 20px; 104 | letter-spacing: 1px; 105 | } 106 | 107 | .content h2, .content h3 { 108 | font-size: 150%; 109 | margin: 20px 0; 110 | } 111 | 112 | .content p{ 113 | color: #555; 114 | line-height: 30px; 115 | letter-spacing: 1.2px; 116 | } -------------------------------------------------------------------------------- /026-vertical-slider/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Vertical Slider 21 | 22 | 23 | 24 |
25 |
26 |
27 |

Nature flower

28 |

all in pink

29 |
30 |
31 |

Bluuue Sky

32 |

with it's mountains

33 |
34 |
35 |

Lonely castle

36 |

in the wilderness

37 |
38 |
39 |

Flying eagle

40 |

in the sunset

41 |
42 |
43 |
44 |
46 |
47 |
49 |
50 |
52 |
53 |
55 |
56 |
57 |
58 | 61 | 64 |
65 |
66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /026-vertical-slider/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/026-vertical-slider/output.gif -------------------------------------------------------------------------------- /026-vertical-slider/script.js: -------------------------------------------------------------------------------- 1 | const sliderContainer = document.querySelector(".slider-container"); 2 | const rightSlide = document.querySelector(".right-slide"); 3 | const leftSlide = document.querySelector(".left-slide"); 4 | const upButton = document.querySelector(".up-button"); 5 | const downButton = document.querySelector(".down-button"); 6 | const slidesLength = rightSlide.querySelectorAll("div").length; 7 | 8 | let activeSlideIndex = 0; 9 | 10 | leftSlide.style.top = `-${(slidesLength - 1) * 100}vh`; 11 | 12 | upButton.addEventListener("click", () => changeSlide("up")); 13 | downButton.addEventListener("click", () => changeSlide("down")); 14 | 15 | const changeSlide = (direction) => { 16 | const sliderHeight = sliderContainer.clientHeight; 17 | if (direction === "up") { 18 | activeSlideIndex++; 19 | if (activeSlideIndex > slidesLength - 1) { 20 | activeSlideIndex = 0; 21 | } 22 | } else if (direction === "down") { 23 | activeSlideIndex--; 24 | if (activeSlideIndex < 0) { 25 | activeSlideIndex = slidesLength - 1; 26 | } 27 | } 28 | rightSlide.style.transform = `translateY(-${ 29 | activeSlideIndex * sliderHeight 30 | }px)`; 31 | leftSlide.style.transform = `translateY(${ 32 | activeSlideIndex * sliderHeight 33 | }px)`; 34 | }; 35 | -------------------------------------------------------------------------------- /026-vertical-slider/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Open+Sans&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: "Open Sans", sans-serif; 11 | height: 100vh; 12 | } 13 | 14 | .slider-container { 15 | position: relative; 16 | overflow: hidden; 17 | width: 100vw; 18 | height: 100vh; 19 | } 20 | 21 | .left-slide { 22 | height: 100%; 23 | width: 35%; 24 | position: absolute; 25 | top: 0; 26 | left: 0; 27 | transition: all 0.5s ease-in-out; 28 | } 29 | 30 | .left-slide > div { 31 | height: 100%; 32 | width: 100%; 33 | display: flex; 34 | flex-direction: column; 35 | justify-content: center; 36 | align-items: center; 37 | text-align: center; 38 | color: white; 39 | } 40 | 41 | .left-slide h1 { 42 | font-size: 40px; 43 | margin-bottom: 10px; 44 | margin-top: -30px; 45 | } 46 | 47 | .right-slide { 48 | height: 100%; 49 | position: absolute; 50 | top: 0; 51 | left: 35%; 52 | width: 65%; 53 | transition: all 0.5s ease-in-out; 54 | } 55 | 56 | .right-slide > div { 57 | background-repeat: no-repeat; 58 | background-size: cover; 59 | background-position: center center; 60 | height: 100%; 61 | width: 100%; 62 | } 63 | 64 | button { 65 | background-color: #fff; 66 | border: none; 67 | color: #aaa; 68 | cursor: pointer; 69 | font-size: 16px; 70 | padding: 15px; 71 | } 72 | 73 | button:hover { 74 | color: #222; 75 | } 76 | 77 | button:focus { 78 | outline: none; 79 | } 80 | 81 | .slider-container .action-buttons button { 82 | position: absolute; 83 | left: 35%; 84 | top: 50%; 85 | z-index: 100; 86 | } 87 | 88 | .slider-container .action-buttons .down-button { 89 | transform: translateX(-100%); 90 | border-top-left-radius: 5px; 91 | border-bottom-left-radius: 5px; 92 | } 93 | 94 | .slider-container .action-buttons .up-button { 95 | transform: translateY(-100%); 96 | border-top-right-radius: 5px; 97 | border-bottom-right-radius: 5px; 98 | } 99 | -------------------------------------------------------------------------------- /027-toast-notification/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Toast Notification 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /027-toast-notification/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/027-toast-notification/output.gif -------------------------------------------------------------------------------- /027-toast-notification/script.js: -------------------------------------------------------------------------------- 1 | const button = document.getElementById("button"); 2 | const toasts = document.getElementById("toasts"); 3 | 4 | const messages = [ 5 | "Message One", 6 | "Message Two", 7 | "Message Three", 8 | "Message Four", 9 | ]; 10 | 11 | const types = ["info", "success", "error"]; 12 | 13 | button.addEventListener("click", () => createNotification()); 14 | 15 | function createNotification(message = null, type = null) { 16 | const notif = document.createElement("div"); 17 | notif.classList.add("toast"); 18 | notif.classList.add(type ? type : getRandomType()); 19 | 20 | notif.innerText = message ? message : getRandomMessage(); 21 | 22 | toasts.appendChild(notif); 23 | 24 | setTimeout(() => { 25 | notif.remove(); 26 | }, 3000); 27 | } 28 | 29 | function getRandomMessage() { 30 | return messages[Math.floor(Math.random() * messages.length)]; 31 | } 32 | 33 | function getRandomType() { 34 | return types[Math.floor(Math.random() * types.length)]; 35 | } 36 | -------------------------------------------------------------------------------- /027-toast-notification/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: rebeccapurple; 9 | font-family: 'Poppins', sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | .btn { 20 | background-color: #ffffff; 21 | color: rebeccapurple; 22 | font-family: inherit; 23 | font-weight: bold; 24 | padding: 1rem; 25 | border-radius: 5px; 26 | border: none; 27 | cursor: pointer; 28 | } 29 | 30 | .btn:focus { 31 | outline: none; 32 | } 33 | 34 | .btn:active { 35 | transform: scale(0.98); 36 | } 37 | 38 | #toasts { 39 | position: fixed; 40 | bottom: 10px; 41 | right: 10px; 42 | display: flex; 43 | flex-direction: column; 44 | align-items: flex-end; 45 | } 46 | 47 | .toast { 48 | background-color: #fff; 49 | border-radius: 5px; 50 | padding: 1rem 2rem; 51 | margin: 0.5rem; 52 | } 53 | 54 | .toast.info { 55 | color: rebeccapurple; 56 | } 57 | 58 | .toast.success { 59 | color: green; 60 | } 61 | 62 | .toast.error { 63 | color: red; 64 | } -------------------------------------------------------------------------------- /028-github-profiles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | GitHub Profiles 21 | 22 | 23 | 24 |
25 | 26 |
27 | 28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /028-github-profiles/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/028-github-profiles/output.gif -------------------------------------------------------------------------------- /028-github-profiles/script.js: -------------------------------------------------------------------------------- 1 | const APIURL = "https://api.github.com/users/"; 2 | 3 | const main = document.getElementById("main"); 4 | const form = document.getElementById("form"); 5 | const search = document.getElementById("search"); 6 | 7 | async function getUser(username) { 8 | try { 9 | const { data } = await axios(APIURL + username); 10 | createUserCard(data); 11 | getRepos(username); 12 | } catch (err) { 13 | if (err.response.status == 404) { 14 | createErrorCard("No profile with this username"); 15 | } 16 | } 17 | } 18 | 19 | async function getRepos(username) { 20 | try { 21 | const { data } = await axios(APIURL + username + "/repos?sort=created"); 22 | addReposToCard(data); 23 | } catch (err) { 24 | createErrorCard("Problem fetching repos"); 25 | } 26 | } 27 | 28 | function createUserCard(user) { 29 | const cardHTML = ` 30 |
31 |
32 | ${user.name} 33 |
34 |
35 |

${user.name}

36 |

${user.bio}

37 | 42 | 43 |
44 |
45 |
46 | `; 47 | main.innerHTML = cardHTML; 48 | } 49 | 50 | function createErrorCard(msg) { 51 | const cardHTML = ` 52 |
53 |

${msg}

54 |
55 | `; 56 | 57 | main.innerHTML = cardHTML; 58 | } 59 | 60 | function addReposToCard(repos) { 61 | const reposEl = document.getElementById("repos"); 62 | 63 | repos.slice(0, 5).forEach((repo) => { 64 | const repoEl = document.createElement("a"); 65 | repoEl.classList.add("repo"); 66 | repoEl.href = repo.html_url; 67 | repoEl.target = "_blank"; 68 | repoEl.innerText = repo.name; 69 | 70 | reposEl.appendChild(repoEl); 71 | }); 72 | } 73 | 74 | form.addEventListener("submit", (e) => { 75 | e.preventDefault(); 76 | const user = search.value; 77 | if (user) { 78 | getUser(user); 79 | search.value = ""; 80 | } 81 | }); 82 | -------------------------------------------------------------------------------- /028-github-profiles/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #2a2a72; 9 | color: #fff; 10 | font-family: 'Poppins', sans-serif; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | height: 100vh; 16 | overflow: hidden; 17 | margin: 0; 18 | } 19 | 20 | .user-form { 21 | width: 100%; 22 | max-width: 700px; 23 | } 24 | 25 | .user-form input { 26 | width: 100%; 27 | display: block; 28 | background-color: #4c2885; 29 | border: none; 30 | border-radius: 10px; 31 | color: #fff; 32 | padding: 1rem; 33 | margin-bottom: 2rem; 34 | font-family: inherit; 35 | font-size: 1rem; 36 | box-shadow: 0 5px 10px rgba(154, 160, 185, 0.05), 37 | 0 15px 40px rgba(0, 0, 0, 0.1); 38 | } 39 | 40 | .user-form input::placeholder { 41 | color: #bbb; 42 | } 43 | 44 | .user-form input:focus { 45 | outline: none; 46 | } 47 | 48 | .card { 49 | max-width: 800px; 50 | background-color: #4c2885; 51 | border-radius: 20px; 52 | box-shadow: 0 5px 10px rgba(154, 160, 185, 0.05), 53 | 0 15px 40px rgba(0, 0, 0, 0.1); 54 | display: flex; 55 | padding: 3rem; 56 | margin: 0 1.5rem; 57 | } 58 | 59 | .avatar { 60 | border-radius: 50%; 61 | border: 10px solid #2a2a72; 62 | height: 150px; 63 | width: 150px; 64 | } 65 | 66 | .user-info { 67 | color: #eee; 68 | margin-left: 2rem; 69 | } 70 | 71 | .user-info h2 { 72 | margin-top: 0; 73 | } 74 | 75 | .user-info ul { 76 | list-style-type: none; 77 | display: flex; 78 | justify-content: space-between; 79 | padding: 0; 80 | max-width: 400px; 81 | } 82 | 83 | .user-info ul li { 84 | display: flex; 85 | align-items: center; 86 | } 87 | 88 | .user-info ul li strong { 89 | font-size: 0.9rem; 90 | margin-left: 0.5rem; 91 | } 92 | 93 | .repo { 94 | text-decoration: none; 95 | color: #fff; 96 | background-color: #212a72; 97 | font-size: 0.7rem; 98 | padding: 0.25rem 0.5rem; 99 | margin-right: 0.5rem; 100 | margin-bottom: 0.5rem; 101 | display: inline-block; 102 | } 103 | 104 | @media (max-width: 500px) { 105 | .card { 106 | flex-direction: column; 107 | align-items: center; 108 | } 109 | 110 | .user-form { 111 | max-width: 400px; 112 | } 113 | } -------------------------------------------------------------------------------- /029-double-click-heart/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Double Click Heart 21 | 22 | 23 | 24 |

Double click on the image to it

25 | You liked it 0 times 26 | 27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /029-double-click-heart/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/029-double-click-heart/output.gif -------------------------------------------------------------------------------- /029-double-click-heart/script.js: -------------------------------------------------------------------------------- 1 | const loveMe = document.querySelector('.loveMe') 2 | const times = document.querySelector('#times') 3 | 4 | let clickTime = 0 5 | let timesClicked = 0 6 | 7 | loveMe.addEventListener('click', (e) => { 8 | if(clickTime === 0) { 9 | clickTime = new Date().getTime() 10 | } else { 11 | if((new Date().getTime() - clickTime) < 800) { 12 | createHeart(e) 13 | clickTime = 0 14 | } else { 15 | clickTime = new Date().getTime() 16 | } 17 | } 18 | }) 19 | 20 | const createHeart = (e) => { 21 | const heart = document.createElement('i') 22 | heart.classList.add('fas') 23 | heart.classList.add('fa-heart') 24 | 25 | const x = e.clientX 26 | const y = e.clientY 27 | 28 | const leftOffset = e.target.offsetLeft 29 | const topOffset = e.target.offsetTop 30 | 31 | const xInside = x - leftOffset 32 | const yInside = y - topOffset 33 | 34 | heart.style.top = `${yInside}px` 35 | heart.style.left = `${xInside}px` 36 | 37 | loveMe.appendChild(heart) 38 | 39 | times.innerHTML = ++timesClicked 40 | 41 | setTimeout(() => heart.remove(), 1000) 42 | } -------------------------------------------------------------------------------- /029-double-click-heart/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Oswald'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: 'Oswald', sans-serif; 9 | text-align: center; 10 | overflow: hidden; 11 | margin: 0; 12 | } 13 | 14 | h3 { 15 | margin-bottom: 0; 16 | text-align: center; 17 | } 18 | 19 | small { 20 | display: block; 21 | margin-bottom: 20px; 22 | text-align: center; 23 | } 24 | 25 | .fa-heart { 26 | color: red; 27 | } 28 | 29 | .loveMe { 30 | height: 440px; 31 | width: 300px; 32 | background: url('https://images.unsplash.com/photo-1504215680853-026ed2a45def?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80') 33 | no-repeat center center/cover; 34 | margin: auto; 35 | cursor: pointer; 36 | max-width: 100%; 37 | position: relative; 38 | box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); 39 | } 40 | 41 | .loveMe .fa-heart { 42 | position: absolute; 43 | animation: grow 0.6s linear; 44 | transform: translate(-50%, -50%) scale(0); 45 | } 46 | 47 | @keyframes grow { 48 | to { 49 | transform: translate(-50%, -50%) scale(10); 50 | opacity: 0; 51 | } 52 | } -------------------------------------------------------------------------------- /030-auto-text-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Auto Text Effect 21 | 22 | 23 | 24 |

Starting...

25 | 26 |
27 | 28 | 29 |
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /030-auto-text-effect/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/030-auto-text-effect/output.gif -------------------------------------------------------------------------------- /030-auto-text-effect/script.js: -------------------------------------------------------------------------------- 1 | const textEl = document.getElementById('text') 2 | const speedEl = document.getElementById('speed') 3 | const text = 'We Love Programming!' 4 | let idx = 1 5 | let speed = 300 / speedEl.value 6 | 7 | writeText() 8 | 9 | function writeText() { 10 | textEl.innerText = text.slice(0, idx) 11 | 12 | idx++ 13 | 14 | if(idx > text.length) { 15 | idx = 1 16 | } 17 | 18 | setTimeout(writeText, speed) 19 | } 20 | 21 | 22 | speedEl.addEventListener('input', (e) => speed = 300 / e.target.value) -------------------------------------------------------------------------------- /030-auto-text-effect/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: darksalmon; 9 | font-family: 'Roboto', sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | div { 20 | position: absolute; 21 | bottom: 20px; 22 | background: rgba(0, 0, 0, 0.1); 23 | padding: 10px 20px; 24 | font-size: 18px; 25 | } 26 | 27 | input { 28 | width: 50px; 29 | padding: 5px; 30 | font-size: 18px; 31 | background-color: darksalmon; 32 | border: none; 33 | text-align: center; 34 | } 35 | 36 | input:focus { 37 | outline: none; 38 | } -------------------------------------------------------------------------------- /031-random-password/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Random Password 21 | 22 | 23 | 24 |
25 |

Password Generator

26 |
27 | 28 | 31 |
32 |
33 |
34 | 35 | 36 |
37 |
38 | 39 | 40 |
41 |
42 | 43 | 44 |
45 |
46 | 47 | 48 |
49 |
50 | 51 | 52 |
53 |
54 | 55 | 58 |
59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /031-random-password/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/031-random-password/output.gif -------------------------------------------------------------------------------- /031-random-password/script.js: -------------------------------------------------------------------------------- 1 | const resultEl = document.getElementById("result"); 2 | const lengthEl = document.getElementById("length"); 3 | const uppercaseEl = document.getElementById("uppercase"); 4 | const lowercaseEl = document.getElementById("lowercase"); 5 | const numbersEl = document.getElementById("numbers"); 6 | const symbolsEl = document.getElementById("symbols"); 7 | const generateEl = document.getElementById("generate"); 8 | const clipboardEl = document.getElementById("clipboard"); 9 | 10 | const randomFunc = { 11 | lower: getRandomLower, 12 | upper: getRandomUpper, 13 | number: getRandomNumber, 14 | symbol: getRandomSymbol, 15 | }; 16 | 17 | clipboardEl.addEventListener("click", () => { 18 | const textarea = document.createElement("textarea"); 19 | const password = resultEl.innerText; 20 | 21 | if (!password) { 22 | return; 23 | } 24 | 25 | textarea.value = password; 26 | document.body.appendChild(textarea); 27 | textarea.select(); 28 | document.execCommand("copy"); 29 | textarea.remove(); 30 | alert("Password copied to clipboard!"); 31 | }); 32 | 33 | generateEl.addEventListener("click", () => { 34 | const length = +lengthEl.value; 35 | const hasLower = lowercaseEl.checked; 36 | const hasUpper = uppercaseEl.checked; 37 | const hasNumber = numbersEl.checked; 38 | const hasSymbol = symbolsEl.checked; 39 | 40 | resultEl.innerText = generatePassword( 41 | hasLower, 42 | hasUpper, 43 | hasNumber, 44 | hasSymbol, 45 | length 46 | ); 47 | }); 48 | 49 | function generatePassword(lower, upper, number, symbol, length) { 50 | let generatedPassword = ""; 51 | const typesCount = lower + upper + number + symbol; 52 | const typesArr = [{ lower }, { upper }, { number }, { symbol }].filter( 53 | (item) => Object.values(item)[0] 54 | ); 55 | 56 | if (typesCount === 0) { 57 | return ""; 58 | } 59 | 60 | for (let i = 0; i < length; i += typesCount) { 61 | typesArr.forEach((type) => { 62 | const funcName = Object.keys(type)[0]; 63 | generatedPassword += randomFunc[funcName](); 64 | }); 65 | } 66 | 67 | const finalPassword = generatedPassword.slice(0, length); 68 | 69 | return finalPassword; 70 | } 71 | 72 | function getRandomLower() { 73 | return String.fromCharCode(Math.floor(Math.random() * 26) + 97); 74 | } 75 | 76 | function getRandomUpper() { 77 | return String.fromCharCode(Math.floor(Math.random() * 26) + 65); 78 | } 79 | 80 | function getRandomNumber() { 81 | return String.fromCharCode(Math.floor(Math.random() * 10) + 48); 82 | } 83 | 84 | function getRandomSymbol() { 85 | const symbols = "!@#$%^&*(){}[]=<>/,."; 86 | return symbols[Math.floor(Math.random() * symbols.length)]; 87 | } 88 | -------------------------------------------------------------------------------- /031-random-password/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Muli&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #3b3b98; 9 | color: #fff; 10 | font-family: 'Muli', sans-serif; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | height: 100vh; 16 | overflow: hidden; 17 | padding: 10px; 18 | margin: 0; 19 | } 20 | 21 | h2 { 22 | margin: 10px 0 20px; 23 | text-align: center; 24 | } 25 | 26 | .container { 27 | background-color: #23235b; 28 | box-shadow: 0px 2px 10px rgba(255, 255, 255, 0.2); 29 | padding: 20px; 30 | width: 350px; 31 | max-width: 100%; 32 | } 33 | 34 | .result-container { 35 | background-color: rgba(0, 0, 0, 0.4); 36 | display: flex; 37 | justify-content: flex-start; 38 | align-items: center; 39 | position: relative; 40 | font-size: 18px; 41 | letter-spacing: 1px; 42 | padding: 12px 10px; 43 | height: 50px; 44 | width: 100%; 45 | } 46 | 47 | .result-container #result { 48 | word-wrap: break-word; 49 | max-width: calc(100% - 40px); 50 | } 51 | 52 | .result-container .btn { 53 | position: absolute; 54 | top: 5px; 55 | right: 5px; 56 | width: 40px; 57 | height: 40px; 58 | font-size: 20px; 59 | } 60 | 61 | .btn { 62 | border: none; 63 | background-color: #3b3b98; 64 | color: #fff; 65 | font-size: 16px; 66 | padding: 8px 12px; 67 | cursor: pointer; 68 | } 69 | 70 | .btn-large { 71 | display: block; 72 | width: 100%; 73 | } 74 | 75 | .setting { 76 | display: flex; 77 | justify-content: space-between; 78 | align-items: center; 79 | margin: 15px 0; 80 | } -------------------------------------------------------------------------------- /032-good-cheap-fast/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Good, Cheap, Fast 21 | 22 | 23 | 24 | 25 |

How do you want your project to be?

26 |
27 | 28 | 31 | Good 32 |
33 | 34 |
35 | 36 | 39 | Cheap 40 |
41 | 42 |
43 | 44 | 47 | Fast 48 |
49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /032-good-cheap-fast/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/032-good-cheap-fast/output.gif -------------------------------------------------------------------------------- /032-good-cheap-fast/script.js: -------------------------------------------------------------------------------- 1 | const toggles = document.querySelectorAll(".toggle"); 2 | const good = document.querySelector("#good"); 3 | const cheap = document.querySelector("#cheap"); 4 | const fast = document.querySelector("#fast"); 5 | 6 | toggles.forEach((toggle) => 7 | toggle.addEventListener("change", (e) => doTheTrick(e.target)) 8 | ); 9 | 10 | function doTheTrick(theClickedOne) { 11 | if (good.checked && cheap.checked && fast.checked) { 12 | if (good === theClickedOne) { 13 | fast.checked = false; 14 | } 15 | 16 | if (cheap === theClickedOne) { 17 | good.checked = false; 18 | } 19 | 20 | if (fast === theClickedOne) { 21 | cheap.checked = false; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /032-good-cheap-fast/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Roboto", sans-serif; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | overflow: hidden; 15 | margin: 0; 16 | } 17 | 18 | .toggle-container { 19 | display: flex; 20 | align-items: center; 21 | margin: 10px 0; 22 | width: 200px; 23 | } 24 | 25 | .toggle { 26 | visibility: hidden; 27 | } 28 | 29 | .label { 30 | position: relative; 31 | background-color: #d0d0d0; 32 | border-radius: 50px; 33 | cursor: pointer; 34 | display: inline-block; 35 | margin: 0 15px 0; 36 | width: 80px; 37 | height: 40px; 38 | } 39 | 40 | .toggle:checked + .label { 41 | background-color: #8e44ad; 42 | } 43 | 44 | .ball { 45 | background: #fff; 46 | height: 34px; 47 | width: 34px; 48 | border-radius: 50%; 49 | position: absolute; 50 | top: 3px; 51 | left: 3px; 52 | align-items: center; 53 | justify-content: center; 54 | animation: slideOff 0.3s linear forwards; 55 | } 56 | 57 | .toggle:checked + .label .ball { 58 | animation: slideOn 0.3s linear forwards; 59 | } 60 | 61 | @keyframes slideOn { 62 | 0% { 63 | transform: translateX(0) scale(1); 64 | } 65 | 50% { 66 | transform: translateX(20px) scale(1.2); 67 | } 68 | 100% { 69 | transform: translateX(40px) scale(1); 70 | } 71 | } 72 | 73 | @keyframes slideOff { 74 | 0% { 75 | transform: translateX(40px) scale(1); 76 | } 77 | 50% { 78 | transform: translateX(20px) scale(1.2); 79 | } 80 | 100% { 81 | transform: translateX(0) scale(1); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /033-notes-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Notes App 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /033-notes-app/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/033-notes-app/output.gif -------------------------------------------------------------------------------- /033-notes-app/script.js: -------------------------------------------------------------------------------- 1 | const addBtn = document.getElementById("add"); 2 | 3 | const notes = JSON.parse(localStorage.getItem("notes")); 4 | 5 | if (notes) { 6 | notes.forEach((note) => addNewNote(note)); 7 | } 8 | 9 | addBtn.addEventListener("click", () => addNewNote()); 10 | 11 | function addNewNote(text = "") { 12 | const note = document.createElement("div"); 13 | note.classList.add("note"); 14 | 15 | note.innerHTML = ` 16 |
17 | 18 | 19 |
20 | 21 |
22 | 23 | `; 24 | 25 | const editBtn = note.querySelector(".edit"); 26 | const deleteBtn = note.querySelector(".delete"); 27 | const main = note.querySelector(".main"); 28 | const textArea = note.querySelector("textarea"); 29 | 30 | textArea.value = text; 31 | main.innerHTML = marked(text); 32 | 33 | deleteBtn.addEventListener("click", () => { 34 | note.remove(); 35 | 36 | updateLS(); 37 | }); 38 | 39 | editBtn.addEventListener("click", () => { 40 | main.classList.toggle("hidden"); 41 | textArea.classList.toggle("hidden"); 42 | }); 43 | 44 | textArea.addEventListener("input", (e) => { 45 | const { value } = e.target; 46 | 47 | main.innerHTML = marked(value); 48 | 49 | updateLS(); 50 | }); 51 | 52 | document.body.appendChild(note); 53 | } 54 | 55 | function updateLS() { 56 | const notesText = document.querySelectorAll("textarea"); 57 | 58 | const notes = []; 59 | 60 | notesText.forEach((note) => notes.push(note.value)); 61 | 62 | localStorage.setItem("notes", JSON.stringify(notes)); 63 | } 64 | -------------------------------------------------------------------------------- /033-notes-app/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | outline: none; 6 | } 7 | 8 | body { 9 | background-color: #7bdaf3; 10 | font-family: "Poppins", sans-serif; 11 | display: flex; 12 | flex-wrap: wrap; 13 | margin: 0; 14 | padding-top: 3rem; 15 | } 16 | 17 | .add { 18 | position: fixed; 19 | top: 1rem; 20 | right: 1rem; 21 | background-color: #9ec862; 22 | color: #fff; 23 | border: none; 24 | border-radius: 3px; 25 | padding: 0.5rem 1rem; 26 | cursor: pointer; 27 | } 28 | 29 | .add:active { 30 | transform: scale(0.98); 31 | } 32 | 33 | .note { 34 | background-color: #fff; 35 | box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1); 36 | margin: 30px 20px; 37 | height: 400px; 38 | width: 400px; 39 | overflow: hidden; 40 | } 41 | 42 | .note .tools { 43 | background-color: #9ec862; 44 | display: flex; 45 | justify-content: flex-end; 46 | padding: 0.5rem; 47 | } 48 | 49 | .note .tools button { 50 | background-color: transparent; 51 | border: none; 52 | color: #fff; 53 | cursor: pointer; 54 | font-size: 1rem; 55 | margin-left: 0.5rem; 56 | } 57 | 58 | .note textarea { 59 | outline: none; 60 | font-family: inherit; 61 | font-size: 1.2rem; 62 | border: none; 63 | height: 400px; 64 | width: 100%; 65 | padding: 20px; 66 | } 67 | 68 | .main { 69 | padding: 20px; 70 | } 71 | 72 | .hidden { 73 | display: none; 74 | } 75 | -------------------------------------------------------------------------------- /034-animated-countdown/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Animated Countdown 21 | 22 | 23 | 24 |
25 |
26 | 3 27 | 2 28 | 1 29 | 0 30 |
31 |

Get Ready

32 |
33 | 34 |
35 |

GO

36 | 37 |
38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /034-animated-countdown/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/034-animated-countdown/output.gif -------------------------------------------------------------------------------- /034-animated-countdown/script.js: -------------------------------------------------------------------------------- 1 | const nums = document.querySelectorAll('.nums span'); 2 | const counter = document.querySelector('.counter'); 3 | const finalMessage = document.querySelector('.final'); 4 | const replay = document.querySelector('#replay'); 5 | 6 | 7 | runAnimation(); 8 | 9 | function resetDOM() { 10 | counter.classList.remove("hide"); 11 | finalMessage.classList.remove("show"); 12 | 13 | nums.forEach((num) => { 14 | num.classList.value = ""; 15 | }); 16 | 17 | nums[0].classList.add("in"); 18 | } 19 | 20 | function runAnimation(){ 21 | nums.forEach((num, idx) => { 22 | const nextToLast = nums.length - 1; 23 | 24 | num.addEventListener("animationend", (e) => { 25 | if(e.animationName === "goIn" && idx !== nextToLast){ 26 | num.classList.remove("in"); 27 | num.classList.add("out"); 28 | }else if (e.animationName === "goOut" && num.nextElementSibling){ 29 | num.nextElementSibling.classList.add("in"); 30 | } else{ 31 | counter.classList.add("hide"); 32 | finalMessage.classList.add("show"); 33 | } 34 | }) 35 | }) 36 | } 37 | 38 | replay.addEventListener('click', () => { 39 | resetDOM() 40 | runAnimation() 41 | }) -------------------------------------------------------------------------------- /035-image-carousel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Image Carousel 21 | 22 | 23 | 24 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /035-image-carousel/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/035-image-carousel/output.gif -------------------------------------------------------------------------------- /035-image-carousel/script.js: -------------------------------------------------------------------------------- 1 | const imgs = document.getElementById('imgs') 2 | const leftBtn = document.getElementById('left') 3 | const rightBtn = document.getElementById('right') 4 | 5 | const img = document.querySelectorAll('#imgs img') 6 | 7 | let idx = 0 8 | 9 | let interval = setInterval(run, 2000) 10 | 11 | function run() { 12 | idx++ 13 | changeImage() 14 | } 15 | 16 | function changeImage() { 17 | if(idx > img.length - 1) { 18 | idx = 0 19 | } else if(idx < 0) { 20 | idx = img.length - 1 21 | } 22 | 23 | imgs.style.transform = `translateX(${-idx * 500}px)` 24 | } 25 | 26 | function resetInterval() { 27 | clearInterval(interval) 28 | interval = setInterval(run, 2000) 29 | } 30 | 31 | rightBtn.addEventListener('click', () => { 32 | idx++ 33 | changeImage() 34 | resetInterval() 35 | }) 36 | 37 | leftBtn.addEventListener('click', () => { 38 | idx-- 39 | changeImage() 40 | resetInterval() 41 | }) -------------------------------------------------------------------------------- /035-image-carousel/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: 'Roboto', sans-serif; 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | height: 100vh; 13 | margin: 0; 14 | } 15 | 16 | img { 17 | width: 500px; 18 | height: 500px; 19 | object-fit: cover; 20 | } 21 | 22 | .carousel { 23 | box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3); 24 | height: 530px; 25 | width: 500px; 26 | overflow: hidden; 27 | } 28 | 29 | .image-container { 30 | display: flex; 31 | transform: translateX(0); 32 | transition: transform 0.5s ease-in-out; 33 | } 34 | 35 | .buttons-container { 36 | display: flex; 37 | justify-content: space-between; 38 | } 39 | 40 | .btn { 41 | background-color: rebeccapurple; 42 | color: #fff; 43 | border: none; 44 | padding: 0.5rem; 45 | cursor: pointer; 46 | width: 49.5%; 47 | } 48 | 49 | .btn:hover { 50 | opacity: 0.9; 51 | } 52 | 53 | .btn:focus { 54 | outline: none; 55 | } -------------------------------------------------------------------------------- /036-hoverboard/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Hoverborad 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /036-hoverboard/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/036-hoverboard/output.gif -------------------------------------------------------------------------------- /036-hoverboard/script.js: -------------------------------------------------------------------------------- 1 | 2 | const container = document.getElementById('container') 3 | const colors = ['#e74c3c', '#8e44ad', '#3498db', '#e67e22', '#2ecc71'] 4 | const SQUARES = 500 5 | 6 | for(let i = 0; i < SQUARES; i++) { 7 | const square = document.createElement('div') 8 | square.classList.add('square') 9 | 10 | square.addEventListener('mouseover', () => setColor(square)) 11 | 12 | square.addEventListener('mouseout', () => removeColor(square)) 13 | 14 | container.appendChild(square) 15 | } 16 | 17 | function setColor(element) { 18 | const color = getRandomColor() 19 | element.style.background = color 20 | element.style.boxShadow = `0 0 2px ${color}, 0 0 10px ${color}` 21 | } 22 | 23 | function removeColor(element) { 24 | element.style.background = '#1d1d1d' 25 | element.style.boxShadow = '0 0 2px #000' 26 | } 27 | 28 | function getRandomColor() { 29 | return colors[Math.floor(Math.random() * colors.length)] 30 | } -------------------------------------------------------------------------------- /036-hoverboard/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | background-color: #111; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | height: 100vh; 11 | overflow: hidden; 12 | margin: 0; 13 | } 14 | 15 | .container { 16 | display: flex; 17 | align-items: center; 18 | justify-content: center; 19 | flex-wrap: wrap; 20 | max-width: 400px; 21 | } 22 | 23 | .square { 24 | background-color: #1d1d1d; 25 | box-shadow: 0 0 2px #000; 26 | height: 16px; 27 | width: 16px; 28 | margin: 2px; 29 | transition: 2s ease; 30 | } 31 | 32 | .square:hover { 33 | transition-duration: 0s; 34 | } -------------------------------------------------------------------------------- /037-pokedex/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Pokedex 21 | 22 | 23 | 24 |

Pokedex

25 |
26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /037-pokedex/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/037-pokedex/output.gif -------------------------------------------------------------------------------- /037-pokedex/script.js: -------------------------------------------------------------------------------- 1 | const poke_container = document.getElementById("poke-container"); 2 | const pokemon_count = 150; 3 | const colors = { 4 | fire: "#FDDFDF", 5 | grass: "#DEFDE0", 6 | electric: "#FCF7DE", 7 | water: "#DEF3FD", 8 | ground: "#f4e7da", 9 | rock: "#d5d5d4", 10 | fairy: "#fceaff", 11 | poison: "#98d7a5", 12 | bug: "#f8d5a3", 13 | dragon: "#97b3e6", 14 | psychic: "#eaeda1", 15 | flying: "#F5F5F5", 16 | fighting: "#E6E0D4", 17 | normal: "#F5F5F5", 18 | }; 19 | 20 | const main_types = Object.keys(colors); 21 | 22 | const fetchPokemons = async () => { 23 | for (let i = 1; i <= pokemon_count; i++) { 24 | await getPokemon(i); 25 | } 26 | }; 27 | 28 | const getPokemon = async (id) => { 29 | const url = `https://pokeapi.co/api/v2/pokemon/${id}`; 30 | const res = await fetch(url); 31 | const data = await res.json(); 32 | // console.log(data); 33 | createPokemonCard(data); 34 | }; 35 | 36 | const createPokemonCard = (pokemon) => { 37 | const pokemonEl = document.createElement("div"); 38 | pokemonEl.classList.add("pokemon"); 39 | 40 | const name = pokemon.name[0].toUpperCase() + pokemon.name.slice(1); 41 | const id = pokemon.id.toString().padStart(3, "0"); 42 | 43 | const poke_types = pokemon.types.map((type) => type.type.name); 44 | const type = main_types.find((type) => poke_types.indexOf(type) > -1); 45 | const color = colors[type]; 46 | const pokeImg = pokemon.sprites.front_default; 47 | 48 | pokemonEl.style.backgroundColor = color; 49 | 50 | const pokemonInnerHTML = ` 51 |
52 | 53 | 54 |
55 |
56 | #${id} 57 |

${name}

58 | Type: ${type} 59 |
60 | `; 61 | 62 | pokemonEl.innerHTML = pokemonInnerHTML; 63 | 64 | poke_container.appendChild(pokemonEl); 65 | }; 66 | 67 | fetchPokemons(); 68 | -------------------------------------------------------------------------------- /037-pokedex/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Lato:300,400&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background: #efefbb; 9 | background: linear-gradient(to right, #d4d3dd, #efefbb); 10 | font-family: 'Lato', sans-serif; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | margin: 0; 16 | } 17 | 18 | h1 { 19 | letter-spacing: 3px; 20 | } 21 | 22 | .poke-container { 23 | display: flex; 24 | flex-wrap: wrap; 25 | align-items: space-between; 26 | justify-content: center; 27 | margin: 0 auto; 28 | max-width: 1200px; 29 | } 30 | 31 | .pokemon { 32 | background-color: #eee; 33 | border-radius: 10px; 34 | box-shadow: 0 3px 15px rgba(100, 100, 100, 0.5); 35 | margin: 10px; 36 | padding: 20px; 37 | text-align: center; 38 | } 39 | 40 | .pokemon .img-container { 41 | background-color: rgba(255, 255, 255, 0.6); 42 | border-radius: 50%; 43 | width: 120px; 44 | height: 120px; 45 | text-align: center; 46 | } 47 | 48 | .pokemon .img-container img { 49 | max-width: 90%; 50 | margin-top: 20px; 51 | } 52 | 53 | .pokemon .info { 54 | margin-top: 20px; 55 | } 56 | 57 | .pokemon .info .number { 58 | background-color: rgba(0, 0, 0, 0.1); 59 | padding: 5px 10px; 60 | border-radius: 10px; 61 | font-size: 0.8em; 62 | } 63 | 64 | .pokemon .info .name { 65 | margin: 15px 0 7px; 66 | letter-spacing: 1px; 67 | } -------------------------------------------------------------------------------- /038-mobile-tab-navigation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Mobile Tab Navigation 21 | 22 | 23 | 24 | 25 |
26 | home 27 | work 28 | blog 29 | about 30 | 50 |
51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /038-mobile-tab-navigation/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/038-mobile-tab-navigation/output.gif -------------------------------------------------------------------------------- /038-mobile-tab-navigation/script.js: -------------------------------------------------------------------------------- 1 | const contents = document.querySelectorAll('.content') 2 | const listItems = document.querySelectorAll('nav ul li') 3 | 4 | listItems.forEach((item, idx) => { 5 | item.addEventListener('click', () => { 6 | hideAllContents() 7 | hideAllItems() 8 | 9 | item.classList.add('active') 10 | contents[idx].classList.add('show') 11 | }) 12 | }) 13 | 14 | function hideAllContents() { 15 | contents.forEach(content => content.classList.remove('show')) 16 | } 17 | 18 | 19 | function hideAllItems() { 20 | listItems.forEach(item => item.classList.remove('active')) 21 | } -------------------------------------------------------------------------------- /038-mobile-tab-navigation/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: rgba(155, 89, 182, 0.7); 9 | font-family: 'Open Sans', sans-serif; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | margin: 0; 15 | } 16 | 17 | .phone { 18 | position: relative; 19 | overflow: hidden; 20 | border: 3px solid #eee; 21 | border-radius: 15px; 22 | height: 600px; 23 | width: 340px; 24 | } 25 | 26 | .phone .content { 27 | opacity: 0; 28 | object-fit: cover; 29 | position: absolute; 30 | top: 0; 31 | left: 0; 32 | height: calc(100% - 60px); 33 | width: 100%; 34 | transition: opacity 0.4s ease; 35 | } 36 | 37 | .phone .content.show { 38 | opacity: 1; 39 | } 40 | 41 | nav { 42 | position: absolute; 43 | bottom: 0; 44 | left: 0; 45 | margin-top: -5px; 46 | width: 100%; 47 | } 48 | 49 | nav ul { 50 | background-color: #fff; 51 | display: flex; 52 | list-style-type: none; 53 | padding: 0; 54 | margin: 0; 55 | height: 60px; 56 | } 57 | 58 | nav li { 59 | color: #777; 60 | cursor: pointer; 61 | flex: 1; 62 | padding: 10px; 63 | text-align: center; 64 | } 65 | 66 | nav ul li p { 67 | font-size: 12px; 68 | margin: 2px 0; 69 | } 70 | 71 | nav ul li:hover, 72 | nav ul li.active { 73 | color: #8e44ad; 74 | } -------------------------------------------------------------------------------- /039-password-strength-background/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | Password Strength Background 27 | 28 | 29 | 30 | 31 |
32 |
33 |

Image Password Strength

34 |

Change the password to see the effect

35 |
36 | 37 | 38 |
39 | 40 |
41 | 42 | 43 |
44 | 45 | 48 |
49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /039-password-strength-background/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/039-password-strength-background/output.gif -------------------------------------------------------------------------------- /039-password-strength-background/script.js: -------------------------------------------------------------------------------- 1 | const password = document.getElementById('password') 2 | const background = document.getElementById('background') 3 | 4 | password.addEventListener('input', (e) => { 5 | const input = e.target.value 6 | const length = input.length 7 | const blurValue = 20 - length * 2 8 | background.style.filter = `blur(${blurValue}px)` 9 | }) -------------------------------------------------------------------------------- /039-password-strength-background/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | display: flex; 7 | flex-direction: column; 8 | align-items: center; 9 | justify-content: center; 10 | height: 100vh; 11 | overflow: hidden; 12 | margin: 0; 13 | } 14 | 15 | .background { 16 | background: url('https://images.unsplash.com/photo-1556745757-8d76bdb6984b') 17 | no-repeat center center/cover; 18 | position: absolute; 19 | top: -20px; 20 | bottom: -20px; 21 | left: -20px; 22 | right: -20px; 23 | z-index: -1; 24 | filter: blur(20px); 25 | } -------------------------------------------------------------------------------- /040-3d-background-boxes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 3D Background Boxes 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /040-3d-background-boxes/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/040-3d-background-boxes/output.gif -------------------------------------------------------------------------------- /040-3d-background-boxes/script.js: -------------------------------------------------------------------------------- 1 | const boxesContainer = document.getElementById("boxes"); 2 | const btn = document.getElementById("btn"); 3 | 4 | btn.addEventListener("click", () => boxesContainer.classList.toggle("big")); 5 | 6 | function createBoxes() { 7 | for (let i = 0; i < 4; i++) { 8 | for (let j = 0; j < 4; j++) { 9 | const box = document.createElement("div"); 10 | box.classList.add("box"); 11 | box.style.backgroundPosition = `${-j * 125}px ${-i * 125}px`; 12 | boxesContainer.appendChild(box); 13 | } 14 | } 15 | } 16 | 17 | createBoxes(); 18 | -------------------------------------------------------------------------------- /040-3d-background-boxes/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"); 2 | @import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap"); 3 | 4 | * { 5 | box-sizing: border-box; 6 | } 7 | 8 | body { 9 | background-color: #fafafa; 10 | font-family: "Roboto", sans-serif; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | height: 100vh; 16 | overflow: hidden; 17 | } 18 | 19 | .magic { 20 | background-color: #f9ca24; 21 | color: #fff; 22 | font-family: "Poppins", sans-serif; 23 | border: 0; 24 | border-radius: 3px; 25 | font-size: 16px; 26 | padding: 12px 20px; 27 | cursor: pointer; 28 | position: fixed; 29 | top: 20px; 30 | letter-spacing: 1px; 31 | box-shadow: 0 3px rgba(249, 202, 36, 0.5); 32 | z-index: 100; 33 | } 34 | 35 | .magic:focus { 36 | outline: none; 37 | } 38 | 39 | .magic:active { 40 | box-shadow: none; 41 | transform: translateY(2px); 42 | } 43 | 44 | .boxes { 45 | display: flex; 46 | flex-wrap: wrap; 47 | justify-content: space-around; 48 | height: 500px; 49 | width: 500px; 50 | position: relative; 51 | transition: 0.4s ease; 52 | } 53 | 54 | .boxes.big { 55 | width: 600px; 56 | height: 600px; 57 | } 58 | 59 | .boxes.big .box { 60 | transform: rotateZ(360deg); 61 | } 62 | 63 | .box { 64 | background-image: url("https://media.giphy.com/media/EZqwsBSPlvSda/giphy.gif"); 65 | background-repeat: no-repeat; 66 | background-size: 500px 500px; 67 | position: relative; 68 | height: 125px; 69 | width: 125px; 70 | transition: 0.4s ease; 71 | } 72 | 73 | .box::after { 74 | content: ""; 75 | background-color: #f6e58d; 76 | position: absolute; 77 | top: 8px; 78 | right: -15px; 79 | height: 100%; 80 | width: 15px; 81 | transform: skewY(45deg); 82 | } 83 | 84 | .box::before { 85 | content: ""; 86 | background-color: #f9ca24; 87 | position: absolute; 88 | bottom: -15px; 89 | left: 8px; 90 | height: 15px; 91 | width: 100%; 92 | transform: skewX(45deg); 93 | } 94 | -------------------------------------------------------------------------------- /041-verify-account-ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Verify Your Account 21 | 22 | 23 | 24 | 25 |
26 |

Verify Your Account

27 |

We emailed you the six digit code to cool_guy@email.com
Enter the code below to confirm your email address.

28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 | This is design only. We didn't actually send you an email as we don't have your email, right? 38 | 39 |
40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /041-verify-account-ui/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/041-verify-account-ui/output.gif -------------------------------------------------------------------------------- /041-verify-account-ui/script.js: -------------------------------------------------------------------------------- 1 | const codes = document.querySelectorAll('.code') 2 | 3 | codes[0].focus() 4 | 5 | codes.forEach((code, idx) => { 6 | code.addEventListener('keydown', (e) => { 7 | if(e.key >= 0 && e.key <=9) { 8 | codes[idx].value = '' 9 | setTimeout(() => codes[idx + 1].focus(), 10) 10 | } else if(e.key === 'Backspace') { 11 | setTimeout(() => codes[idx - 1].focus(), 10) 12 | } 13 | }) 14 | }) -------------------------------------------------------------------------------- /041-verify-account-ui/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Muli:300,700&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #fbfcfe; 9 | font-family: 'Muli', sans-serif; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | overflow: hidden; 15 | margin: 0; 16 | } 17 | 18 | .container { 19 | background-color: #fff; 20 | border: 3px #000 solid; 21 | border-radius: 10px; 22 | padding: 30px; 23 | max-width: 1000px; 24 | text-align: center; 25 | } 26 | 27 | .code-container { 28 | display: flex; 29 | align-items: center; 30 | justify-content: center; 31 | margin: 40px 0; 32 | } 33 | 34 | .code { 35 | border-radius: 5px; 36 | font-size: 75px; 37 | height: 120px; 38 | width: 100px; 39 | border: 1px solid #eee; 40 | margin: 1%; 41 | text-align: center; 42 | font-weight: 300; 43 | -moz-appearance: textfield; 44 | } 45 | 46 | .code::-webkit-outer-spin-button, 47 | .code::-webkit-inner-spin-button { 48 | -webkit-appearance: none; 49 | margin: 0; 50 | } 51 | 52 | .code:valid { 53 | border-color: #3498db; 54 | box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.25); 55 | } 56 | 57 | .info { 58 | background-color: #eaeaea; 59 | display: inline-block; 60 | padding: 10px; 61 | line-height: 20px; 62 | max-width: 400px; 63 | color: #777; 64 | border-radius: 5px; 65 | } 66 | 67 | @media (max-width: 600px) { 68 | .code-container { 69 | flex-wrap: wrap; 70 | } 71 | 72 | .code { 73 | font-size: 60px; 74 | height: 80px; 75 | max-width: 70px; 76 | } 77 | } -------------------------------------------------------------------------------- /042-live-user-filter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Live User Filter 21 | 22 | 23 | 24 | 25 |
26 |
27 |

Live User Filter

28 | Search by name and/or location 29 | 30 |
31 | 32 | 37 |
38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /042-live-user-filter/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/042-live-user-filter/output.gif -------------------------------------------------------------------------------- /042-live-user-filter/script.js: -------------------------------------------------------------------------------- 1 | const result = document.getElementById('result') 2 | const filter = document.getElementById('filter') 3 | const listItems = [] 4 | 5 | getData() 6 | 7 | filter.addEventListener('input', (e) => filterData(e.target.value)) 8 | 9 | async function getData() { 10 | const res = await fetch('https://randomuser.me/api?results=50') 11 | 12 | const { results } = await res.json() 13 | 14 | // Clear result 15 | result.innerHTML = '' 16 | 17 | results.forEach(user => { 18 | const li = document.createElement('li') 19 | 20 | listItems.push(li) 21 | 22 | li.innerHTML = ` 23 | ${user.name.first} 24 |
25 |

${user.name.first} ${user.name.last}

26 |

${user.location.city}, ${user.location.country}

27 |
28 | ` 29 | 30 | result.appendChild(li) 31 | }) 32 | } 33 | 34 | function filterData(searchTerm) { 35 | listItems.forEach(item => { 36 | if(item.innerText.toLowerCase().includes(searchTerm.toLowerCase())) { 37 | item.classList.remove('hide') 38 | } else { 39 | item.classList.add('hide') 40 | } 41 | }) 42 | } -------------------------------------------------------------------------------- /042-live-user-filter/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #f8f9fd; 9 | font-family: 'Roboto', sans-serif; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | overflow: hidden; 15 | margin: 0; 16 | } 17 | 18 | .container { 19 | border-radius: 5px; 20 | box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2); 21 | overflow: hidden; 22 | width: 300px; 23 | } 24 | 25 | .title { 26 | margin: 0; 27 | } 28 | 29 | .subtitle { 30 | display: inline-block; 31 | margin: 5px 0 20px; 32 | opacity: 0.8; 33 | } 34 | 35 | .header { 36 | background-color: #3e57db; 37 | color: #fff; 38 | padding: 30px 20px; 39 | } 40 | 41 | .header input { 42 | background-color: rgba(0, 0, 0, 0.3); 43 | border: 0; 44 | border-radius: 50px; 45 | color: #fff; 46 | font-size: 14px; 47 | padding: 10px 15px; 48 | width: 100%; 49 | } 50 | 51 | .header input:focus { 52 | outline: none; 53 | } 54 | 55 | .user-list { 56 | background-color: #fff; 57 | list-style-type: none; 58 | margin: 0; 59 | padding: 0; 60 | max-height: 400px; 61 | overflow-y: auto; 62 | } 63 | 64 | .user-list li { 65 | display: flex; 66 | padding: 20px; 67 | } 68 | 69 | .user-list img { 70 | border-radius: 50%; 71 | object-fit: cover; 72 | height: 50px; 73 | width: 50px; 74 | } 75 | 76 | .user-list .user-info { 77 | margin-left: 10px; 78 | } 79 | 80 | .user-list .user-info h4 { 81 | margin: 0 0 10px; 82 | } 83 | 84 | .user-list .user-info p { 85 | font-size: 12px; 86 | } 87 | 88 | .user-list li:not(:last-of-type) { 89 | border-bottom: 1px solid #eee; 90 | } 91 | 92 | .user-list li.hide { 93 | display: none; 94 | } -------------------------------------------------------------------------------- /043-feedback-ui-design/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Let Us Know Your Feedback 21 | 22 | 23 | 24 |
25 | How satisfied are you with our
customer support performance?
26 |
27 |
28 | 31 | Unhappy 32 |
33 | 34 |
35 | 38 | Neutral 39 |
40 | 41 |
42 | 45 | Satisfied 46 |
47 |
48 | 49 |
50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /043-feedback-ui-design/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/043-feedback-ui-design/output.png -------------------------------------------------------------------------------- /043-feedback-ui-design/script.js: -------------------------------------------------------------------------------- 1 | const ratings = document.querySelectorAll('.rating') 2 | const ratingsContainer = document.querySelector('.ratings-container') 3 | const sendBtn = document.querySelector('#send') 4 | const panel = document.querySelector('#panel') 5 | let selectedRating = 'Satisfied' 6 | 7 | ratingsContainer.addEventListener('click', (e) => { 8 | if(e.target.parentNode.classList.contains('rating') && e.target.nextElementSibling) { 9 | removeActive() 10 | e.target.parentNode.classList.add('active') 11 | selectedRating = e.target.nextElementSibling.innerHTML 12 | } else if( 13 | e.target.parentNode.classList.contains('rating') && 14 | e.target.previousSibling && 15 | e.target.previousElementSibling.nodeName === 'IMG' 16 | ) { 17 | removeActive() 18 | e.target.parentNode.classList.add('active') 19 | selectedRating = e.target.innerHTML 20 | } 21 | 22 | }) 23 | 24 | sendBtn.addEventListener('click', (e) => { 25 | panel.innerHTML = ` 26 | 27 | Thank You! 28 |
29 | Feedback: ${selectedRating} 30 |

We'll use your feedback to improve our customer support

31 | ` 32 | }) 33 | 34 | function removeActive() { 35 | for(let i = 0; i < ratings.length; i++) { 36 | ratings[i].classList.remove('active') 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /043-feedback-ui-design/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Montserrat&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #fef9f2; 9 | font-family: 'Montserrat', sans-serif; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | overflow: hidden; 15 | margin: 0; 16 | } 17 | 18 | .panel-container { 19 | background-color: #fff; 20 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); 21 | border-radius: 4px; 22 | font-size: 90%; 23 | display: flex; 24 | flex-direction: column; 25 | justify-content: center; 26 | align-items: center; 27 | text-align: center; 28 | padding: 30px; 29 | max-width: 400px; 30 | } 31 | 32 | .panel-container strong { 33 | line-height: 20px; 34 | } 35 | 36 | .ratings-container { 37 | display: flex; 38 | margin: 20px 0; 39 | } 40 | 41 | .rating { 42 | flex: 1; 43 | cursor: pointer; 44 | padding: 20px; 45 | margin: 10px 5px; 46 | } 47 | 48 | .rating:hover, 49 | .rating.active { 50 | border-radius: 4px; 51 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); 52 | } 53 | 54 | .rating img { 55 | width: 40px; 56 | } 57 | 58 | .rating small { 59 | color: #555; 60 | display: inline-block; 61 | margin: 10px 0 0; 62 | } 63 | 64 | .rating:hover small, 65 | .rating.active small { 66 | color: #111; 67 | } 68 | 69 | .btn { 70 | background-color: #302d2b; 71 | color: #fff; 72 | border: 0; 73 | border-radius: 4px; 74 | padding: 12px 30px; 75 | cursor: pointer; 76 | } 77 | 78 | .btn:focus { 79 | outline: 0; 80 | } 81 | 82 | .btn:active { 83 | transform: scale(0.98); 84 | } 85 | 86 | .fa-heart { 87 | color: red; 88 | font-size: 30px; 89 | margin-bottom: 10px; 90 | } 91 | -------------------------------------------------------------------------------- /044-custom-range-slider/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Custom Range Slider 21 | 22 | 23 | 24 |

Custom Range Slider

25 |
26 | 27 | 28 |
29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /044-custom-range-slider/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/044-custom-range-slider/output.png -------------------------------------------------------------------------------- /044-custom-range-slider/script.js: -------------------------------------------------------------------------------- 1 | const range = document.getElementById("range"); 2 | 3 | range.addEventListener("input", (e) => { 4 | const value = +e.target.value; 5 | const label = e.target.nextElementSibling; 6 | 7 | const range_width = getComputedStyle(e.target).getPropertyValue("width"); 8 | const label_width = getComputedStyle(label).getPropertyValue("width"); 9 | 10 | const num_width = +range_width.substring(0, range_width.length - 2); 11 | const num_label_width = +label_width.substring(0, label_width.length - 2); 12 | 13 | const max = +e.target.max; 14 | const min = +e.target.min; 15 | 16 | const left = 17 | value * (num_width / max) - 18 | num_label_width / 2 + 19 | scale(value, min, max, 10, -10); 20 | 21 | label.style.left = `${left}px`; 22 | 23 | label.innerHTML = value; 24 | }); 25 | 26 | const scale = (num, in_min, in_max, out_min, out_max) => { 27 | return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min; 28 | }; 29 | -------------------------------------------------------------------------------- /044-custom-range-slider/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Lato&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); 9 | font-family: "Lato", sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | h2 { 20 | position: absolute; 21 | top: 10px; 22 | } 23 | 24 | .range-container { 25 | position: relative; 26 | } 27 | 28 | input[type="range"] { 29 | width: 300px; 30 | margin: 18px 0; 31 | -webkit-appearance: none; 32 | } 33 | 34 | input[type="range"]:focus { 35 | outline: none; 36 | } 37 | 38 | input[type="range"] + label { 39 | background-color: #fff; 40 | position: absolute; 41 | top: -25px; 42 | left: 110px; 43 | width: 80px; 44 | padding: 5px 0; 45 | text-align: center; 46 | border-radius: 4px; 47 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); 48 | } 49 | 50 | /* Chrome & Safari */ 51 | input[type="range"]::-webkit-slider-runnable-track { 52 | background: purple; 53 | border-radius: 4px; 54 | width: 100%; 55 | height: 10px; 56 | cursor: pointer; 57 | } 58 | 59 | input[type="range"]::-webkit-slider-thumb { 60 | -webkit-appearance: none; 61 | height: 24px; 62 | width: 24px; 63 | background: #fff; 64 | border-radius: 50%; 65 | border: 1px solid purple; 66 | margin-top: -7px; 67 | cursor: pointer; 68 | } 69 | 70 | /* Firefox */ 71 | input[type="range"]::-moz-range-track { 72 | background: purple; 73 | border-radius: 4px; 74 | width: 100%; 75 | height: 13px; 76 | cursor: pointer; 77 | } 78 | 79 | input[type="range"]::-moz-range-thumb { 80 | -webkit-appearance: none; 81 | height: 24px; 82 | width: 24px; 83 | background: #fff; 84 | border-radius: 50%; 85 | border: 1px solid purple; 86 | margin-top: -7px; 87 | cursor: pointer; 88 | } 89 | 90 | /* IE */ 91 | input[type="range"]::-ms-track { 92 | background: purple; 93 | border-radius: 4px; 94 | width: 100%; 95 | height: 13px; 96 | cursor: pointer; 97 | } 98 | 99 | input[type="range"]::-ms-thumb { 100 | -webkit-appearance: none; 101 | height: 24px; 102 | width: 24px; 103 | background: #fff; 104 | border-radius: 50%; 105 | border: 1px solid purple; 106 | margin-top: -7px; 107 | cursor: pointer; 108 | } 109 | -------------------------------------------------------------------------------- /045-netflix-mobile-navigation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Netflix Mobile Navigation 21 | 22 | 23 | 24 | 27 | 28 | 31 | 32 |

Mobile Navigation

33 | 34 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /045-netflix-mobile-navigation/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/045-netflix-mobile-navigation/output.gif -------------------------------------------------------------------------------- /045-netflix-mobile-navigation/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/045-netflix-mobile-navigation/output.png -------------------------------------------------------------------------------- /045-netflix-mobile-navigation/script.js: -------------------------------------------------------------------------------- 1 | const open_btn = document.querySelector(".open-btn"); 2 | const close_btn = document.querySelector(".close-btn"); 3 | const nav = document.querySelectorAll(".nav"); 4 | 5 | open_btn.addEventListener("click", () => { 6 | nav.forEach((nav_el) => nav_el.classList.add("visible")); 7 | }); 8 | 9 | close_btn.addEventListener("click", () => { 10 | nav.forEach((nav_el) => nav_el.classList.remove("visible")); 11 | }); 12 | -------------------------------------------------------------------------------- /045-netflix-mobile-navigation/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Muli&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Muli", sans-serif; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | } 15 | 16 | .text { 17 | text-transform: uppercase; 18 | } 19 | 20 | .logo { 21 | width: 200px; 22 | } 23 | 24 | .nav-btn { 25 | border: none; 26 | background-color: transparent; 27 | cursor: pointer; 28 | font-size: 20px; 29 | } 30 | 31 | .open-btn { 32 | position: fixed; 33 | top: 10px; 34 | left: 10px; 35 | } 36 | 37 | .nav { 38 | position: fixed; 39 | top: 0; 40 | left: 0; 41 | height: 100vh; 42 | transform: translateX(-100%); 43 | transition: transform 0.3s ease-in-out; 44 | } 45 | 46 | .nav.visible { 47 | transform: translateX(0); 48 | } 49 | 50 | .nav-black { 51 | background-color: rgb(34, 31, 31); 52 | width: 60%; 53 | max-width: 480px; 54 | min-width: 320px; 55 | transition-delay: 0.4s; 56 | } 57 | 58 | .nav-black.visible { 59 | transition-delay: 0s; 60 | } 61 | 62 | .nav-red { 63 | background-color: rgb(229, 9, 20); 64 | width: 95%; 65 | transition-delay: 0.2s; 66 | } 67 | 68 | .nav-red.visible { 69 | transition-delay: 0.2s; 70 | } 71 | 72 | .nav-white { 73 | background-color: #fff; 74 | width: 95%; 75 | padding: 40px; 76 | position: relative; 77 | transition-delay: 0s; 78 | } 79 | 80 | .nav-white.visible { 81 | transition-delay: 0.4s; 82 | } 83 | 84 | .close-btn { 85 | opacity: 0.3; 86 | position: absolute; 87 | top: 40px; 88 | right: 30px; 89 | } 90 | 91 | .list { 92 | list-style-type: none; 93 | padding: 0; 94 | } 95 | 96 | .list li { 97 | margin: 20px 0; 98 | } 99 | 100 | .list li a { 101 | color: rgb(34, 31, 31); 102 | font-size: 14px; 103 | text-decoration: none; 104 | text-transform: uppercase; 105 | } 106 | 107 | .list ul { 108 | list-style-type: none; 109 | padding-left: 20px; 110 | } 111 | -------------------------------------------------------------------------------- /046-quiz-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Quiz App 21 | 22 | 23 | 24 |
25 |
26 |

Question text

27 | 48 |
49 | 50 |
51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /046-quiz-app/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/046-quiz-app/output.gif -------------------------------------------------------------------------------- /046-quiz-app/script.js: -------------------------------------------------------------------------------- 1 | const quizData = [ 2 | { 3 | question: "Which language runs in a web browser?", 4 | a: "Java", 5 | b: "C", 6 | c: "Python", 7 | d: "JavaScript", 8 | correct: "d", 9 | }, 10 | { 11 | question: "What does CSS stand for?", 12 | a: "Central Style Sheets", 13 | b: "Cascading Style Sheets", 14 | c: "Cascading Simple Sheets", 15 | d: "Cars SUVs Sailboats", 16 | correct: "b", 17 | }, 18 | { 19 | question: "What does HTML stand for?", 20 | a: "Hypertext Markup Language", 21 | b: "Hypertext Markdown Language", 22 | c: "Hyperloop Machine Language", 23 | d: "Helicopters Terminals Motorboats Lamborginis", 24 | correct: "a", 25 | }, 26 | { 27 | question: "What year was JavaScript launched?", 28 | a: "1996", 29 | b: "1995", 30 | c: "1994", 31 | d: "none of the above", 32 | correct: "b", 33 | }, 34 | ]; 35 | 36 | const quiz = document.getElementById("quiz"); 37 | const answerEls = document.querySelectorAll(".answer"); 38 | const questionEl = document.getElementById("question"); 39 | const a_text = document.getElementById("a_text"); 40 | const b_text = document.getElementById("b_text"); 41 | const c_text = document.getElementById("c_text"); 42 | const d_text = document.getElementById("d_text"); 43 | const submitBtn = document.getElementById("submit"); 44 | 45 | let currentQuiz = 0; 46 | let score = 0; 47 | 48 | loadQuiz(); 49 | 50 | function loadQuiz() { 51 | deselectAnswers(); 52 | 53 | const currentQuizData = quizData[currentQuiz]; 54 | 55 | questionEl.innerText = currentQuizData.question; 56 | a_text.innerText = currentQuizData.a; 57 | b_text.innerText = currentQuizData.b; 58 | c_text.innerText = currentQuizData.c; 59 | d_text.innerText = currentQuizData.d; 60 | } 61 | 62 | function deselectAnswers() { 63 | answerEls.forEach((answerEl) => (answerEl.checked = false)); 64 | } 65 | 66 | function getSelected() { 67 | let answer; 68 | 69 | answerEls.forEach((answerEl) => { 70 | if (answerEl.checked) { 71 | answer = answerEl.id; 72 | } 73 | }); 74 | 75 | return answer; 76 | } 77 | 78 | submitBtn.addEventListener("click", () => { 79 | const answer = getSelected(); 80 | 81 | if (answer) { 82 | if (answer === quizData[currentQuiz].correct) { 83 | score++; 84 | } 85 | 86 | currentQuiz++; 87 | 88 | if (currentQuiz < quizData.length) { 89 | loadQuiz(); 90 | } else { 91 | quiz.innerHTML = ` 92 |

You answered ${score}/${quizData.length} questions correctly

93 | 94 | 95 | `; 96 | } 97 | } 98 | }); 99 | -------------------------------------------------------------------------------- /046-quiz-app/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #b8c6db; 9 | background-image: linear-gradient(315deg, #b8c6db 0%, #f5f7fa 100%); 10 | font-family: "Poppins", sans-serif; 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | } 18 | 19 | .quiz-container { 20 | background-color: #fff; 21 | border-radius: 10px; 22 | box-shadow: 0 0 10px 2px rgba(100, 100, 100, 0.1); 23 | width: 600px; 24 | overflow: hidden; 25 | } 26 | 27 | .quiz-header { 28 | padding: 4rem; 29 | } 30 | 31 | h2 { 32 | padding: 1rem; 33 | text-align: center; 34 | margin: 0; 35 | } 36 | 37 | ul { 38 | list-style-type: none; 39 | padding: 0; 40 | } 41 | 42 | ul li { 43 | font-size: 1.2rem; 44 | margin: 1rem 0; 45 | } 46 | 47 | ul li label { 48 | cursor: pointer; 49 | } 50 | 51 | button { 52 | background-color: #8e44ad; 53 | color: #fff; 54 | border: none; 55 | display: block; 56 | width: 100%; 57 | cursor: pointer; 58 | font-size: 1.1rem; 59 | font-family: inherit; 60 | padding: 1.3rem; 61 | } 62 | 63 | button:hover { 64 | background-color: #732d91; 65 | } 66 | 67 | button:focus { 68 | outline: none; 69 | background-color: #5e3370; 70 | } 71 | -------------------------------------------------------------------------------- /047-testimonial-box-switcher/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Testimonial Box 21 | 22 | 23 | 24 |
25 |
26 |
27 |
28 |

29 | I've worked with literally hundreds of HTML/CSS developers and I have to 30 | say the top spot goes to this guy. This guy is an amazing developer. He 31 | stresses on good, clean code and pays heed to the details. I love 32 | developers who respect each and every aspect of a throughly thought out 33 | design and do their best to put it in code. He goes over and beyond and 34 | transforms ART into PIXELS - without a glitch, every time. 35 |

36 |
37 | user 38 |
39 |

Miyah Myles

40 |

Marketing

41 |
42 |
43 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /047-testimonial-box-switcher/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/047-testimonial-box-switcher/output.gif -------------------------------------------------------------------------------- /047-testimonial-box-switcher/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Montserrat'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #f4f4f4; 9 | font-family: 'Montserrat', sans-serif; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | overflow: hidden; 16 | margin: 0; 17 | padding: 10px; 18 | } 19 | 20 | .testimonial-container { 21 | background-color: #476ce4; 22 | color: #fff; 23 | border-radius: 15px; 24 | margin: 20px auto; 25 | padding: 50px 80px; 26 | max-width: 768px; 27 | position: relative; 28 | } 29 | 30 | .fa-quote { 31 | color: rgba(255, 255, 255, 0.3); 32 | font-size: 28px; 33 | position: absolute; 34 | top: 70px; 35 | } 36 | 37 | .fa-quote-right { 38 | left: 40px; 39 | } 40 | 41 | .fa-quote-left { 42 | right: 40px; 43 | } 44 | 45 | .testimonial { 46 | line-height: 28px; 47 | text-align: justify; 48 | } 49 | 50 | .user { 51 | display: flex; 52 | align-items: center; 53 | justify-content: center; 54 | } 55 | 56 | .user .user-image { 57 | border-radius: 50%; 58 | height: 75px; 59 | width: 75px; 60 | object-fit: cover; 61 | } 62 | 63 | .user .user-details { 64 | margin-left: 10px; 65 | } 66 | 67 | .user .username { 68 | margin: 0; 69 | } 70 | 71 | .user .role { 72 | font-weight: normal; 73 | margin: 10px 0; 74 | } 75 | 76 | .progress-bar { 77 | background-color: #fff; 78 | height: 4px; 79 | width: 100%; 80 | animation: grow 10s linear infinite; 81 | transform-origin: left; 82 | } 83 | 84 | @keyframes grow { 85 | 0% { 86 | transform: scaleX(0); 87 | } 88 | } 89 | 90 | @media (max-width: 768px) { 91 | .testimonial-container { 92 | padding: 20px 30px; 93 | } 94 | 95 | .fa-quote { 96 | display: none; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /048-random-image-generator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Random Image Feed 21 | 22 | 23 | 24 |

Random Image Feed

25 |
26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /048-random-image-generator/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/048-random-image-generator/output.png -------------------------------------------------------------------------------- /048-random-image-generator/script.js: -------------------------------------------------------------------------------- 1 | const container = document.querySelector(".container"); 2 | const unsplashURL = "https://source.unsplash.com/random/"; 3 | const rows = 5; 4 | 5 | for (let i = 0; i < rows * 3; i++) { 6 | const img = document.createElement("img"); 7 | img.src = `${unsplashURL}${getRandomSize()}`; 8 | container.appendChild(img); 9 | } 10 | 11 | function getRandomSize() { 12 | return `${getRandomNr()}x${getRandomNr()}`; 13 | } 14 | 15 | function getRandomNr() { 16 | return Math.floor(Math.random() * 10) + 300; 17 | } 18 | -------------------------------------------------------------------------------- /048-random-image-generator/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Roboto", sans-serif; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: center; 13 | min-height: 100vh; 14 | margin: 0; 15 | } 16 | 17 | .title { 18 | margin: 10px 0 0; 19 | text-align: center; 20 | } 21 | 22 | .container { 23 | display: flex; 24 | align-items: center; 25 | justify-content: center; 26 | flex-wrap: wrap; 27 | max-width: 1000px; 28 | } 29 | 30 | .container img { 31 | object-fit: cover; 32 | margin: 10px; 33 | height: 300px; 34 | width: 300px; 35 | max-width: 100%; 36 | } 37 | -------------------------------------------------------------------------------- /049-todo-list/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Todo List 21 | 22 | 23 | 24 |

todos

25 |
26 | 27 | 28 | 29 |
30 | Left click to toggle completed.
Right click to delete todo
31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /049-todo-list/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/049-todo-list/output.gif -------------------------------------------------------------------------------- /049-todo-list/script.js: -------------------------------------------------------------------------------- 1 | const form = document.getElementById("form"); 2 | const input = document.getElementById("input"); 3 | const todosUL = document.getElementById("todos"); 4 | 5 | const todos = JSON.parse(localStorage.getItem("todos")); 6 | 7 | if (todos) { 8 | todos.forEach((todo) => addTodo(todo)); 9 | } 10 | 11 | form.addEventListener("submit", (e) => { 12 | e.preventDefault(); 13 | 14 | addTodo(); 15 | }); 16 | 17 | function addTodo(todo) { 18 | let todoText = input.value; 19 | 20 | if (todo) { 21 | todoText = todo.text; 22 | } 23 | 24 | if (todoText) { 25 | const todoEl = document.createElement("li"); 26 | if (todo && todo.completed) { 27 | todoEl.classList.add("completed"); 28 | } 29 | 30 | todoEl.innerText = todoText; 31 | 32 | todoEl.addEventListener("click", () => { 33 | todoEl.classList.toggle("completed"); 34 | updateLS(); 35 | }); 36 | 37 | todoEl.addEventListener("contextmenu", (e) => { 38 | e.preventDefault(); 39 | 40 | todoEl.remove(); 41 | updateLS(); 42 | }); 43 | 44 | todosUL.appendChild(todoEl); 45 | 46 | input.value = ""; 47 | 48 | updateLS(); 49 | } 50 | } 51 | 52 | function updateLS() { 53 | todosEl = document.querySelectorAll("li"); 54 | 55 | const todos = []; 56 | 57 | todosEl.forEach((todoEl) => { 58 | todos.push({ 59 | text: todoEl.innerText, 60 | completed: todoEl.classList.contains("completed"), 61 | }); 62 | }); 63 | 64 | localStorage.setItem("todos", JSON.stringify(todos)); 65 | } 66 | -------------------------------------------------------------------------------- /049-todo-list/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #f5f5f5; 9 | color: #444; 10 | font-family: "Poppins", sans-serif; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | height: 100vh; 16 | margin: 0; 17 | } 18 | 19 | h1 { 20 | color: rgb(179, 131, 226); 21 | font-size: 10rem; 22 | text-align: center; 23 | opacity: 0.4; 24 | } 25 | 26 | form { 27 | box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); 28 | max-width: 100%; 29 | width: 400px; 30 | } 31 | 32 | .input { 33 | border: none; 34 | color: #444; 35 | font-size: 2rem; 36 | padding: 1rem 2rem; 37 | display: block; 38 | width: 100%; 39 | } 40 | 41 | .input::placeholder { 42 | color: #d5d5d5; 43 | } 44 | 45 | .input:focus { 46 | outline-color: rgb(179, 131, 226); 47 | } 48 | 49 | .todos { 50 | background-color: #fff; 51 | padding: 0; 52 | margin: 0; 53 | list-style-type: none; 54 | } 55 | 56 | .todos li { 57 | border-top: 1px solid #e5e5e5; 58 | cursor: pointer; 59 | font-size: 1.5rem; 60 | padding: 1rem 2rem; 61 | } 62 | 63 | .todos li.completed { 64 | color: #b6b6b6; 65 | text-decoration: line-through; 66 | } 67 | 68 | small { 69 | color: #b5b5b5; 70 | margin-top: 3rem; 71 | text-align: center; 72 | } 73 | -------------------------------------------------------------------------------- /050-insect-catch-game/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | Catch The Insect 21 | 22 | 23 | 24 |
25 |

Catch The Insect

26 | 27 |
28 | 29 |
30 |

What is your "favorite" insect?

31 | 57 |
58 | 59 |
60 |

Time: 00:00

61 |

Score: 0

62 |
63 | Are you annoyed yet?
64 | You are playing an impossible game!! 65 |
66 |
67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /050-insect-catch-game/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshkgd/css-js-projects/0fea7387b50b4c76871520548e4b44dc94aff2f0/050-insect-catch-game/output.gif -------------------------------------------------------------------------------- /050-insect-catch-game/script.js: -------------------------------------------------------------------------------- 1 | const screens = document.querySelectorAll(".screen"); 2 | const choose_insect_btns = document.querySelectorAll(".choose-insect-btn"); 3 | const start_btn = document.getElementById("start-btn"); 4 | const game_container = document.getElementById("game-container"); 5 | const timeEl = document.getElementById("time"); 6 | const scoreEl = document.getElementById("score"); 7 | const message = document.getElementById("message"); 8 | let seconds = 0; 9 | let score = 0; 10 | let selected_insect = {}; 11 | 12 | start_btn.addEventListener("click", () => screens[0].classList.add("up")); 13 | 14 | choose_insect_btns.forEach((btn) => { 15 | btn.addEventListener("click", () => { 16 | const img = btn.querySelector("img"); 17 | const src = img.getAttribute("src"); 18 | const alt = img.getAttribute("alt"); 19 | selected_insect = { src, alt }; 20 | screens[1].classList.add("up"); 21 | setTimeout(createInsect, 1000); 22 | startGame(); 23 | }); 24 | }); 25 | 26 | function startGame() { 27 | setInterval(increaseTime, 1000); 28 | } 29 | 30 | function increaseTime() { 31 | let m = Math.floor(seconds / 60); 32 | let s = seconds % 60; 33 | m = m < 10 ? `0${m}` : m; 34 | s = s < 10 ? `0${s}` : s; 35 | timeEl.innerHTML = `Time: ${m}:${s}`; 36 | seconds++; 37 | } 38 | 39 | function createInsect() { 40 | const insect = document.createElement("div"); 41 | insect.classList.add("insect"); 42 | const { x, y } = getRandomLocation(); 43 | insect.style.top = `${y}px`; 44 | insect.style.left = `${x}px`; 45 | insect.innerHTML = `${
46 |     selected_insect.alt
47 |   }`; 48 | 49 | insect.addEventListener("click", catchInsect); 50 | 51 | game_container.appendChild(insect); 52 | } 53 | 54 | function getRandomLocation() { 55 | const width = window.innerWidth; 56 | const height = window.innerHeight; 57 | const x = Math.random() * (width - 200) + 100; 58 | const y = Math.random() * (height - 200) + 100; 59 | return { x, y }; 60 | } 61 | 62 | function catchInsect() { 63 | increaseScore(); 64 | this.classList.add("caught"); 65 | setTimeout(() => this.remove(), 2000); 66 | addInsects(); 67 | } 68 | 69 | function addInsects() { 70 | setTimeout(createInsect, 1000); 71 | setTimeout(createInsect, 1500); 72 | } 73 | 74 | function increaseScore() { 75 | score++; 76 | if (score > 19) { 77 | message.classList.add("visible"); 78 | } 79 | scoreEl.innerHTML = `Score: ${score}`; 80 | } 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # html-css-js-only-projects 2 | --------------------------------------------------------------------------------