Xin chào tất cả các bạn, mình là Trung Quân aka trungquandev như mọi lần :D. Hôm nay mình sẽ hướng dẫn các bạn làm một thứ khá thú vị, cụ thể là làm cái hiệu ứng cho kiểu Thẻ Bài Magic – Magic Card bằng HTML, CSS và thêm chút Javascript nhé.
“Bài này nằm trong loạt bài Tổng hợp kiến thức hữu ích cho lập trình viên trên trang blog chính thức trungquandev.com“
Những nội dung có trong bài:
- Link hướng dẫn và show demo trên kênh YouTube: Trungquandev Official chính chủ của mình nha.
- Code luôn thôi chứ không có nhiều lý thuyết gì ở đây cả nhé 😀
1. Link hướng dẫn và show demo trên kênh YouTube: Trungquandev Official
2. Triển khai code
– Lưu ý quan trọng nè: phần code dưới đây mình sẽ chia ra dạng các file code để các bạn có thể copy paste về máy rồi chạy là xong ngay nhé.
– Riêng phần giải thích và hướng dẫn code chi tiết thì mình có giải thích luôn trong video trên YouTube rồi nên mình sẽ không viết lại để tránh dài nội dung của bài viết nha.
– Các bạn xem video và đồng thời đăng ký kênh ủng hộ mình nha ^^
– Link: Tạo hiệu ứng Thẻ bài Magic với HTML • CSS • JS thuần
Cấu trúc thư mục dự án của chúng ta sẽ trông như sau (chỉ đơn giản 3 files thôi):
magicCard
index.html
magicCard.css
magicCard.js
Đầu tiên là file index.html, các bạn copy pase đoạn code sau vào nhé:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" href="https://trungquandev.com/wp-content/uploads/2020/08/logo-trungquandev-white-bg.jpg" sizes="16x16"> <title>Magic Card by Trungquandev</title> <link rel="stylesheet" href="magicCard.css"> <script src="magicCard.js" async></script> </head> <body> <div class="magic-card"> <!-- Magic Card --> </div> <div class="customizing"> <span class="general-type clear-bg" onclick="toggleRawBg()">Raw Background?</span> <span class="general-type fire" onclick="customType('magic-card-fire')">Fire</span> <span class="general-type water" onclick="customType('magic-card-water')">Water</span> <span class="general-type wood" onclick="customType('magic-card-wood')">Wood</span> <span class="general-type earth" onclick="customType('magic-card-earth')">Earth</span> <span class="general-type metal" onclick="customType('magic-card-metal')">Metal</span> </div> <div class="trungquandev-author"> <div class="sub-content"> <div>Thank you!</div> <div>Blog: <a href="https://trungquandev.com" target="_blank" rel="noopener noreferrer">https://trungquandev.com</a></div> <div>CV: <a href="https://cv.trungquandev.com" target="_blank" rel="noopener noreferrer">https://cv.trungquandev.com</a></div> <div>YouTube: <a href="https://www.youtube.com/c/TrungquandevOfficial" target="_blank" rel="noopener noreferrer">Trungquandev Official</a></div> <div>Credit to the idea from: <a href="https://codepen.io/gayane-gasparyan/pen/jOmaBQK" target="_blank" rel="noopener noreferrer">https://codepen.io/gayane-gasparyan/pen/jOmaBQK</a></div> </div> </div> </body> </html>
Tiếp theo là file magicCard.css
body { margin: 0; padding: 0; min-height: 100vh; background: #212534; display: flex; justify-content: center; align-items: center; flex-direction: column; padding-top: 2rem; padding-bottom: 2rem; box-sizing: border-box; } /* Customize type and color */ .customizing { margin-top: 80px; color: white; display: flex; gap: 12px; } .customizing>span.general-type { font-size: 1.2rem; cursor: pointer; padding: 4px 12px; border: 1px solid #636e72; border-radius: 4px; } .customizing>span.general-type:hover { border-color: #f7f1e3; } .customizing>span.clear-bg { color: #636e72; } .customizing>span.fire { color: #d63031; } .customizing>span.water { color: #3c67e3; } .customizing>span.wood { color: #00b894; } .customizing>span.earth { color: #cc8e35; } .customizing>span.metal { color: #b2bec3; } /* My information and credit resources */ .trungquandev-author { margin-top: 40px; color: white; } .sub-content { font-size: 1.2rem; text-align: center; line-height: 1.6rem; } .sub-content a { color: inherit; text-decoration: none; color: #1dd1a1; } .sub-content a:hover { color: #55efc8; } /* Có thể hiểu đơn giản đây là một dạng khai báo biến nâng cao trong CSS, chưa support hết các trình duyệt */ /* https://developer.mozilla.org/en-US/docs/Web/CSS/@property */ @property --rotate { syntax: "<angle>"; initial-value: 0deg; inherits: false; } @keyframes spin { 0% { --rotate: 0deg; } 100% { --rotate: 360deg; } } /* Magic Card */ .magic-card { background: #191c29; width: 300px; height: 450px; padding: 3px; position: relative; border-radius: 6px; justify-content: center; align-items: center; text-align: center; display: flex; font-size: 1.5em; cursor: pointer; font-family: cursive; } .magic-card::before { content: ""; width: 106%; height: 104%; top: -2%; left: -3%; border-radius: 8px; position: absolute; z-index: -1; animation: spin 1.5s linear infinite; background-image: linear-gradient(var(--rotate), #81ecec, #00b894 48%); } .magic-card::after { position: absolute; content: ""; top: calc(450px / 6); left: 0; right: 0; z-index: -1; height: 100%; width: 100%; margin: 0 auto; opacity: 1; transition: opacity .5s; transform: scale(0.8); filter: blur(calc(450px / 6)); animation: spin 1.5s linear infinite; background-image: linear-gradient(var(--rotate), #81ecec, #00b894 48%); } .magic-card-raw { background: none; } .magic-card-fire::before, .magic-card-fire::after { background-image: linear-gradient(var(--rotate), #ff6b81, #d63031 48%); } .magic-card-water::before, .magic-card-water::after { background-image: linear-gradient(var(--rotate), #5ddcff, #3c67e3 48%); } .magic-card-wood::before, .magic-card-wood::after { background-image: linear-gradient(var(--rotate), #81ecec, #00b894 48%); } .magic-card-earth::before, .magic-card-earth::after { background-image: linear-gradient(var(--rotate), #ffda79, #cc8e35 48%); } .magic-card-metal::before, .magic-card-metal::after { background-image: linear-gradient(var(--rotate), #dfe6e9, #636e72 48%); }
Cuối cùng là file magicCard.js (dùng để xử lý thay đổi màu sắc của các thẻ bài cũng như bỏ màu nền)
/** * Created by trungquandev.com's author on 14/08/2020. (DD/MM/YYYY) * magicCard.js */ const magicCard = document.querySelector('.magic-card') toggleRawBg = () => { if (magicCard.classList.contains('magic-card-raw')) { magicCard.classList.remove('magic-card-raw') } else { magicCard.classList.add('magic-card-raw') } } resetDefault = () => { const isRawMagicCard = magicCard.classList.contains('magic-card-raw') magicCard.setAttribute('class', `magic-card ${isRawMagicCard ? 'magic-card-raw' : ''}`) } customType = (className) => { // Nếu đã tồn tại class rồi thì không làm gì if (magicCard.classList.contains(className)) return // Trả về trạng thái mặc định trước khi thêm class mới resetDefault() magicCard.classList.add(className) }
Kết quả sẽ như demo trong video mình giải thích code trên YouTube rồi nha, nếu bạn nào gặp vấn đề gì thì có thể comment luôn ở video trên kênh, mình sẽ check và support nhé.
(Ngoài lề quen thuộc: Cảnh báo này dành cho bất kể trang nào khác mà có ý định copy bài không phải của các bạn thì hãy tôn trọng người viết bài chân chính, tuyệt đối không được xào nấu, chỉnh sửa linh tinh bài viết của mình cụ thể là không được xóa những liên kết (link) cũng như tự ý xóa các câu thoại của mình trong toàn bộ bài viết rồi post lại lên trang của các bạn như kiểu đây là bài của các bạn vậy, nếu tham khảo thì hãy để lại liên kết nguồn rõ ràng từ trang trungquandev, mình sẽ thường xuyên dùng tool để check, và nếu phát hiện ra thì cứ đơn giản là chắc chắn sẽ ăn report DMCA nhé.)
4. Chia sẻ full toàn bộ Source Code của bài hôm nay trên Github
Vậy là kết thúc bài hôm nay mình đã hướng dẫn các bạn làm một chiếc hiệu ứng thẻ bài Magic trông cũng khá ổn áp như kiểu trong vài game đơn giản rồi nhé 😀
Mình có để full source code của bài hôm nay ở repo này (Thư mục số 7) cho các bạn tham khảo giống như mọi lần, các bạn có thể clone về và làm theo các bước hướng dẫn mà mình có để trong file README nhé, chỉ có vài bước khá dễ dàng thôi.
https://github.com/trungquandev/trungquandev-public-utilities-algorithms
Và nếu thấy bài viết cũng như video bổ ích, hãy ủng hộ mình bằng cách Đăng ký kênh Youtube Trungquandev Official để mình có động lực tiếp tục viết những bài viết hay cũng như ra thêm nhiều video chất lượng hơn nữa nha, cảm ơn các bạn nhiều !!!
https://www.youtube.com/c/TrungquandevOfficial
Cảm ơn các bạn đã dành thời gian đọc bài viết.
Xin chào và hẹn gặp lại các bạn ở những bài viết tiếp theo.
Best Regards – 💻 Trungquandev Official ❤
Tham khảo kiến thức, ý tưởng:
https://developer.mozilla.org/en-US/docs/Web/CSS/@property
https://codepen.io/gayane-gasparyan/pen/jOmaBQK
“Thanks for awesome knowledges.”
“ From author: trungquandev ”