├── .DS_Store
├── .gitignore
├── Counter Up
├── Counter Up.zip
├── app.js
├── index.html
└── style.css
├── Create Modal
├── Create Modal.zip
├── app.js
├── index.html
└── style.css
├── Create Range Slider
├── Create Range Slider.zip
├── app.js
├── index.html
└── style.css
├── Custom Video Player
├── Custom Video Player.zip
├── app.js
├── index.html
└── style.css
├── Dark And Light Mode
├── Dark And Light Mode.zip
├── app.js
├── index.html
└── style.css
├── Detect Pressed Key
├── Detect Pressed Key.zip
├── app.js
├── index.html
└── style.css
├── Drag And Drop
├── Drag And Drop.zip
├── app.js
├── bg.jpeg
├── index.html
└── style.css
├── Drawing App
├── Drawing App.zip
├── app.js
├── index.html
└── style.css
├── Filter Elements
├── Filter Elements.zip
├── app.js
├── dessert1.jpg
├── drinks1.jpg
├── drinks2.jpg
├── drinks3.jpg
├── index.html
├── meat1.jpg
├── meat2.jpg
├── salad1.jpg
├── salad2.jpg
└── style.css
├── Hover Board
├── Hover Board.zip
├── app.js
├── index.html
└── style.css
├── Image Gallery
├── Image Gallery.zip
├── app.js
├── img1.jpeg
├── img2.jpeg
├── img3.jpeg
├── img4.jpeg
├── img5.jpeg
├── img6.jpeg
├── img7.jpeg
├── img8.jpeg
├── index.html
└── style.css
├── Live Product Filter
├── Live Product Filter.zip
├── app.js
├── index.html
└── style.css
├── Play Piano
├── E.mp3
├── I.mp3
├── O.mp3
├── P.mp3
├── Play Piano.zip
├── Q.mp3
├── R.mp3
├── T.mp3
├── U.mp3
├── W.mp3
├── Y.mp3
├── app.js
├── index.html
└── style.css
├── Preview Image
├── Preview Image.zip
├── app.js
├── index.html
└── style.css
├── Product Card
├── Nike Zoom KD 12.png
├── Product Card.zip
├── index.html
└── style.css
├── Profile Card
├── Cuong.jpg
├── Profile Card.zip
├── aNam.jpg
├── aThai.jpg
├── index.html
└── style.css
├── README.md
├── Register Form Validator
├── Register Form Validator.zip
├── app.js
├── index.html
└── style.css
├── Search Box
├── Search Box.zip
├── app.js
├── index.html
└── style.css
├── Search Tags
├── Search Tags.zip
├── app.js
├── index.html
└── style.css
├── Show On Scroll
├── Show On Scroll.zip
├── app.js
├── index.html
└── style.css
├── Simple Carousel
├── Simple Carousel.zip
├── app.js
├── index.html
└── style.css
├── Skeleton Loading Effect
├── Skeleton Loading Effect.zip
├── app.js
├── index.html
└── style.css
├── Slideshow
├── Slideshow.zip
├── app.js
├── img1.jpeg
├── img2.jpeg
├── img3.jpeg
├── img4.jpeg
├── img5.jpeg
├── img6.jpeg
├── img7.jpeg
├── img8.jpeg
├── img9.jpeg
├── index.html
└── style.css
├── Toast Notification
├── Toast Notification.zip
├── app.js
├── index.html
└── style.css
├── Todo List
├── Todo List.zip
├── app.js
├── index.html
└── style.css
├── Tooltip
├── Tooltip.zip
├── index.html
└── style.css
├── Typing Animation Effect
├── Typing Animation Effect.zip
├── index.html
└── style.css
├── Vaidator Password
├── Vaidator Password.zip
├── app.js
├── index.html
└── style.css
├── Weather App
├── Weather App.zip
├── app.js
├── cold.png
├── cool.jpeg
├── hot.png
├── index.html
├── style.css
└── warm.jpeg
└── Zoom Image
├── Zoom Image.zip
├── app.js
├── bike1.jpg
├── bike2.jpg
├── index.html
└── style.css
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/namndwebdev/html-css-js-thuc-chien/9d0b782a324fa5801e4c39dd73ce31cca3f0d27b/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | 30.md
--------------------------------------------------------------------------------
/Counter Up/Counter Up.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/namndwebdev/html-css-js-thuc-chien/9d0b782a324fa5801e4c39dd73ce31cca3f0d27b/Counter Up/Counter Up.zip
--------------------------------------------------------------------------------
/Counter Up/app.js:
--------------------------------------------------------------------------------
1 | const face = document.querySelector('.counter.face h2')
2 | const youtube = document.querySelector('.counter.youtube h2')
3 | const tiktok = document.querySelector('.counter.tiktok h2')
4 |
5 | function counterUp(el, to) {
6 | let speed = 200
7 | let from = 0
8 | let step = to / speed
9 | const counter = setInterval(function () {
10 | from += step
11 | if (from > to) {
12 | clearInterval(counter)
13 | el.innerText = to
14 | } else {
15 | el.innerText = Math.ceil(from)
16 | }
17 | }, 1)
18 | }
19 |
20 | counterUp(face, 3300)
21 | counterUp(youtube, 1000)
22 | counterUp(tiktok, 9900)
23 |
--------------------------------------------------------------------------------
/Counter Up/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
15 |
16 |
17 |
18 |
Nike Zoom KD 12
19 |
$99
20 |
21 |
Size:
22 | 6
23 | 7
24 | 8
25 | 9
26 |
27 |
28 |
Color:
29 |
30 |
31 |
32 |
33 |
34 | Buy now
35 | Add cart
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Product Card/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
2 |
3 | :root {
4 | --primary-color: #4daf54;
5 | }
6 |
7 | * {
8 | padding: 0;
9 | margin: 0;
10 | box-sizing: border-box;
11 | }
12 |
13 | body {
14 | font-family: 'Poppins', sans-serif;
15 | height: 100vh;
16 | background-image: linear-gradient(to right, #4daf54, #3d8880);
17 | overflow: hidden;
18 | }
19 |
20 | .card {
21 | margin: 120px auto;
22 | width: 320px;
23 | height: 400px;
24 | background-color: #272d40;
25 | border-radius: 15px;
26 | padding: 40px 20px;
27 | color: white;
28 | position: relative;
29 | }
30 |
31 | .card__img {
32 | width: 90%;
33 | transition: 0.5s;
34 | }
35 |
36 | img {
37 | width: 100%;
38 | height: 100%;
39 | object-fit: cover;
40 | object-position: center;
41 | }
42 |
43 | .card:hover .card__img {
44 | transform: translateY(-90px) rotate(-20deg);
45 | }
46 |
47 | .card__title {
48 | color: var(--primary-color);
49 | transition: 0.5s;
50 | text-align: center;
51 | }
52 |
53 | .card__price {
54 | font-weight: 600;
55 | font-size: 26px;
56 | transition: 0.5s;
57 | text-align: center;
58 | }
59 |
60 | .card:hover .card__title {
61 | transform: translate(-40px, -72px);
62 | }
63 |
64 | .card:hover .card__price {
65 | transform: translate(-112px, -72px);
66 | }
67 |
68 | .card__size,
69 | .card__color,
70 | .card__action {
71 | opacity: 0;
72 | visibility: hidden;
73 | transition: 0.5s;
74 | }
75 |
76 | .card__size {
77 | margin-top: 100px;
78 | }
79 |
80 | .card:hover .card__size {
81 | margin-top: -30px;
82 | }
83 |
84 | .card:hover .card__size,
85 | .card:hover .card__color,
86 | .card:hover .card__action {
87 | transition-delay: 0.2s;
88 | opacity: 1;
89 | visibility: visible;
90 | }
91 |
92 | .card__size,
93 | .card__color {
94 | display: flex;
95 | align-items: center;
96 | margin-bottom: 15px;
97 | }
98 |
99 | .card__size h3,
100 | .card__color h3 {
101 | font-weight: unset;
102 | margin-right: 12px;
103 | }
104 |
105 | .card__size span {
106 | padding: 2px 10px;
107 | background-color: #dadada;
108 | margin: 0 5px;
109 | border-radius: 5px;
110 | color: #272d40;
111 | cursor: pointer;
112 | }
113 |
114 | .card__color span {
115 | width: 20px;
116 | height: 20px;
117 | border-radius: 50%;
118 | margin: 0 5px;
119 | cursor: pointer;
120 | }
121 |
122 | .card__color span.green {
123 | background-color: green;
124 | }
125 | .card__color span.red {
126 | background-color: red;
127 | }
128 | .card__color span.black {
129 | background-color: black;
130 | }
131 |
132 | .card__action button {
133 | padding: 10px 20px;
134 | outline: none;
135 | border: none;
136 | background-color: var(--primary-color);
137 | border-radius: 5px;
138 | cursor: pointer;
139 | color: white;
140 | margin-right: 7px;
141 | font-weight: 600;
142 | transition: 0.25s;
143 | }
144 |
145 | .card__action button:hover {
146 | transform: scale(0.9);
147 | }
148 |
149 |
150 | .like, .cart {
151 | font-size: 25px;
152 | position: absolute;
153 | top: 12px;
154 | left: 20px;
155 | cursor: pointer;
156 | z-index: 2;
157 | }
158 |
159 | .cart {
160 | left: unset;
161 | right: 20px;
162 | }
--------------------------------------------------------------------------------
/Profile Card/Cuong.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/namndwebdev/html-css-js-thuc-chien/9d0b782a324fa5801e4c39dd73ce31cca3f0d27b/Profile Card/Cuong.jpg
--------------------------------------------------------------------------------
/Profile Card/Profile Card.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/namndwebdev/html-css-js-thuc-chien/9d0b782a324fa5801e4c39dd73ce31cca3f0d27b/Profile Card/Profile Card.zip
--------------------------------------------------------------------------------
/Profile Card/aNam.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/namndwebdev/html-css-js-thuc-chien/9d0b782a324fa5801e4c39dd73ce31cca3f0d27b/Profile Card/aNam.jpg
--------------------------------------------------------------------------------
/Profile Card/aThai.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/namndwebdev/html-css-js-thuc-chien/9d0b782a324fa5801e4c39dd73ce31cca3f0d27b/Profile Card/aThai.jpg
--------------------------------------------------------------------------------
/Profile Card/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Show On Scroll/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | font-family: sans-serif;
6 | }
7 |
8 | body {
9 | overflow-x: hidden;
10 | }
11 |
12 | .full-height {
13 | height: 100vh;
14 | }
15 |
16 | .left-to-right {
17 | transform: translateX(-150%);
18 | }
19 |
20 | .left-to-right.start {
21 | transition: 0.7s ease-in-out;
22 | transform: translateX(0);
23 | }
24 |
25 | .right-to-left {
26 | transform: translateX(150%);
27 | }
28 |
29 | .right-to-left.start {
30 | transition: 0.7s ease-in-out;
31 | transform: translateX(0);
32 | }
33 |
34 | .zoom {
35 | transform: scale(0);
36 | }
37 |
38 | .zoom.start {
39 | transition: 0.5s ease-in-out;
40 | transform: unset;
41 | }
42 |
43 | #home {
44 | background-image: linear-gradient(to right, #4daf54, #3d8880);
45 | color: white;
46 | display: flex;
47 | align-items: center;
48 | padding-left: 80px;
49 | }
50 |
51 | #home h1 {
52 | font-size: 50px;
53 | margin-bottom: 20px;
54 | }
55 |
56 | #home p {
57 | font-size: 20px;
58 | width: 700px;
59 | transition-delay: 0.2s;
60 | }
61 |
62 | #about {
63 | display: flex;
64 | align-items: center;
65 | justify-content: center;
66 | }
67 |
68 | .box {
69 | background-color: #242628;
70 | width: 500px;
71 | border-radius: 10px;
72 | margin: 0 20px;
73 | padding: 20px;
74 | color: white;
75 | }
76 |
77 | .box h2 {
78 | margin-bottom: 15px;
79 | }
80 |
81 | #team {
82 | background: linear-gradient(180deg, #017c2c 50%, #fff 50%);
83 | display: flex;
84 | align-items: center;
85 | justify-content: center;
86 | }
87 |
88 | #team .person {
89 | width: 200px;
90 | padding: 20px;
91 | margin: 0 25px;
92 | background-color: #fff;
93 | box-shadow: 0 0 5px #2e363a;
94 | border-radius: 10px;
95 | }
96 |
97 | .person h3 {
98 | color: #017c2c;
99 | font-size: 22px;
100 | margin-bottom: 20px;
101 | }
102 |
--------------------------------------------------------------------------------
/Simple Carousel/Simple Carousel.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/namndwebdev/html-css-js-thuc-chien/9d0b782a324fa5801e4c39dd73ce31cca3f0d27b/Simple Carousel/Simple Carousel.zip
--------------------------------------------------------------------------------
/Simple Carousel/app.js:
--------------------------------------------------------------------------------
1 | const wrapper = document.querySelector('.wrapper')
2 | let isMouseDown = false
3 | let startX, scrollLeft
4 |
5 | wrapper.addEventListener('mousedown', (e) => {
6 | isMouseDown = true
7 | startX = e.pageX - wrapper.offsetLeft
8 | scrollLeft = wrapper.scrollLeft
9 | })
10 |
11 | wrapper.addEventListener('mouseleave', () => {
12 | isMouseDown = false
13 | })
14 |
15 | wrapper.addEventListener('mouseup', () => {
16 | isMouseDown = false
17 | })
18 |
19 | wrapper.addEventListener('mousemove', (e) => {
20 | if (!isMouseDown) return
21 |
22 | const x = e.pageX - wrapper.offsetLeft
23 | // 3 là tốc độ scroll
24 | const walk = (x - startX) * 3
25 | wrapper.scrollLeft = scrollLeft - walk
26 | })
27 |
--------------------------------------------------------------------------------
/Simple Carousel/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
Nodemy - Thực Chiến - Sáng Tạo
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Typing Animation Effect/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0px;
3 | padding: 0px;
4 | height: 100vh;
5 | display: flex;
6 | background-color: #060802;
7 | }
8 |
9 | .text-typing {
10 | margin: 200px auto;
11 | font-family: monospace;
12 | }
13 |
14 | .text-typing p {
15 | color: #96ee1c;
16 | font-weight: 700;
17 | font-size: 70px;
18 | white-space: nowrap;
19 | overflow: hidden;
20 | animation: typing 10s steps(30) infinite, blink 1s infinite;
21 | text-shadow: 0 0 100px #96ee1c;
22 | }
23 |
24 | @keyframes typing {
25 | 0%,
26 | 100% {
27 | width: 0%;
28 | }
29 | 70%,
30 | 90% {
31 | width: 100%;
32 | }
33 | }
34 |
35 | @keyframes blink {
36 | 0%,
37 | 100% {
38 | border-right: 10px solid transparent;
39 | }
40 | 50% {
41 | border-right: 10px solid #96ee1c;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Vaidator Password/Vaidator Password.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/namndwebdev/html-css-js-thuc-chien/9d0b782a324fa5801e4c39dd73ce31cca3f0d27b/Vaidator Password/Vaidator Password.zip
--------------------------------------------------------------------------------
/Vaidator Password/app.js:
--------------------------------------------------------------------------------
1 | const form = document.querySelector('form')
2 | const input = document.querySelector('form input')
3 | const eye = document.querySelector('.form-eye')
4 |
5 | eye.addEventListener('click', (e) => {
6 | e.target.classList.toggle('show')
7 |
8 | input.type == 'password' ? (input.type = 'text') : (input.type = 'password')
9 | })
10 |
11 | input.addEventListener('input', (e) => {
12 | const value = e.target.value
13 |
14 | const lowercase = document.querySelector('.lowercase').classList
15 | const uppercase = document.querySelector('.uppercase').classList
16 | const number = document.querySelector('.number').classList
17 | const symbol = document.querySelector('.symbol').classList
18 | const characters = document.querySelector('.characters').classList
19 |
20 | // validator
21 | value.search(/[a-z]/) >= 0
22 | ? lowercase.add('valid')
23 | : lowercase.remove('valid')
24 |
25 | value.search(/[A-Z]/) >= 0
26 | ? uppercase.add('valid')
27 | : uppercase.remove('valid')
28 |
29 | value.search(/[0-9]/) >= 0
30 | ? number.add('valid')
31 | : number.remove('valid')
32 |
33 | value.search(/\W/) >= 0
34 | ? symbol.add('valid')
35 | : symbol.remove('valid')
36 |
37 | value.length >= 8
38 | ? characters.add('valid')
39 | : characters.remove('valid')
40 | })
41 |
--------------------------------------------------------------------------------
/Vaidator Password/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |