本文是筆者寫CSS時經常使用的套路。不論效果再怎麼華麗,萬變不離其宗。javascript
//HTML代碼
<div class="loading">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
複製代碼
/*css代碼*/
body {
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
background: #222;
}
.loading { $colors: #7ef9ff, #89cff0, #4682b4, #0f52ba, #000080; display: flex; animation-delay: 1s; .dot { position: relative; width: 2em; height: 2em; margin: 0.8em; border-radius: 50%; &::before { position: absolute; content: ""; width: 100%; height: 100%; background: inherit; border-radius: inherit; animation: wave 2s ease-out infinite; } @for $i from 1 through 5 { &:nth-child(#{$i}) { background: nth($colors, $i); &::before { animation-delay: $i * 0.2s; } } } } } @keyframes wave { 50%, 75% { transform: scale(2.5); } 80%, 100% { opacity: 0; } } 複製代碼
//HTML代碼
<div class="reveal">sword art online</div>
複製代碼
/*css代碼*/
@import url("https://fonts.googleapis.com/css?family=Raleway:400,400i,700");
body { display: flex; height: 100vh; justify-content: center; align-items: center; text-align: center; background: #222; } .reveal { position: relative; display: flex; color: #6ee1f5; font-size: 2em; font-family: Raleway, sans-serif; letter-spacing: 3px; text-transform: uppercase; white-space: pre; span { opacity: 0; transform: scale(0); animation: fadeIn 2.4s forwards; } &::before, &::after { position: absolute; content: ""; top: 0; bottom: 0; width: 2px; height: 100%; background: white; opacity: 0; transform: scale(0); } &::before { left: 50%; animation: slideLeft 1.5s cubic-bezier(0.7, -0.6, 0.3, 1.5) forwards; } &::after { right: 50%; animation: slideRight 1.5s cubic-bezier(0.7, -0.6, 0.3, 1.5) forwards; } } @keyframes fadeIn { to { opacity: 1; transform: scale(1); } } @keyframes slideLeft { to { left: -6%; opacity: 1; transform: scale(0.9); } } @keyframes slideRight { to { right: -6%; opacity: 1; transform: scale(0.9); } } 複製代碼
//js代碼
let duration = 0.8;
let delay = 0.3;
let revealText = document.querySelector(".reveal");
let letters = revealText.textContent.split("");
revealText.textContent = "";
let middle = letters.filter(e => e !== " ").length / 2;
letters.forEach((letter, i) => {
let span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${delay + Math.abs(i - middle) * 0.1}s`;
revealText.append(span);
});
複製代碼
//HTML代碼
<button data-text="Start" class="btn btn-primary btn-ghost btn-border-stroke btn-text-float-up" >
<div class="btn-borders">
<div class="border-top"></div>
<div class="border-right"></div>
<div class="border-bottom"></div>
<div class="border-left"></div>
</div>
<span class="btn-text">Start</span>
</button>
複製代碼
/*css代碼*/
@import url(https://fonts.googleapis.com/css?family=Lato);
body { display: flex; height: 100vh; justify-content: center; align-items: center; text-align: center; background: #1A1E23; } .btn { --hue: 190; --ease-in-duration: 0.25s; --ease-in-exponential: cubic-bezier(0.95, 0.05, 0.795, 0.035); --ease-out-duration: 0.65s; --ease-out-delay: var(--ease-in-duration); --ease-out-exponential: cubic-bezier(0.19, 1, 0.22, 1); position: relative; padding: 1rem 3rem; font-size: 1rem; line-height: 1.5; color: white; text-decoration: none; background-color: hsl(var(--hue), 100%, 41%); border: 1px solid hsl(var(--hue), 100%, 41%); outline: transparent; overflow: hidden; cursor: pointer; user-select: none; white-space: nowrap; transition: 0.25s; &:hover { background: hsl(var(--hue), 100%, 31%); } &-primary { --hue: 171; } &-ghost { color: hsl(var(--hue), 100%, 41%); background-color: transparent; border-color: hsl(var(--hue), 100%, 41%); &:hover { color: white; } } &-border-stroke { border-color: hsla(var(--hue), 100%, 41%, 0.35); .btn-borders { position: absolute; top: 0; left: 0; width: 100%; height: 100%; .border-top { position: absolute; top: 0; width: 100%; height: 1px; background: hsl(var(--hue), 100%, 41%); transform: scaleX(0); transform-origin: left; } .border-right { position: absolute; right: 0; width: 1px; height: 100%; background: hsl(var(--hue), 100%, 41%); transform: scaleY(0); transform-origin: bottom; } .border-bottom { position: absolute; bottom: 0; width: 100%; height: 1px; background: hsl(var(--hue), 100%, 41%); transform: scaleX(0); transform-origin: left; } .border-left { position: absolute; left: 0; width: 1px; height: 100%; background: hsl(var(--hue), 100%, 41%); transform: scaleY(0); transform-origin: bottom; } // when unhover, ease-out left, bottom; ease-in right, top .border-left { transition: var(--ease-out-duration) var(--ease-out-delay) var(--ease-out-exponential); } .border-bottom { transition: var(--ease-out-duration) var(--ease-out-delay) var(--ease-out-exponential); } .border-right { transition: var(--ease-in-duration) var(--ease-in-exponential); } .border-top { transition: var(--ease-in-duration) var(--ease-in-exponential); } } &:hover { color: hsl(var(--hue), 100%, 41%); background: transparent; .border-top, .border-bottom { transform: scaleX(1); } .border-left, .border-right { transform: scaleY(1); } // when hover, ease-in left, bottom; ease-out right, top .border-left { transition: var(--ease-in-duration) var(--ease-in-exponential); } .border-bottom { transition: var(--ease-in-duration) var(--ease-in-exponential); } .border-right { transition: var(--ease-out-duration) var(--ease-out-delay) var(--ease-out-exponential); } .border-top { transition: var(--ease-out-duration) var(--ease-out-delay) var(--ease-out-exponential); } } } &-text-float-up { &::after { position: absolute; content: attr(data-text); top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; opacity: 0; transform: translateY(35%); transition: 0.25s ease-out; } // when hover, ease-in top-text; ease-out bottom-text .btn-text { display: block; transition: 0.75s 0.1s var(--ease-out-exponential); } &:hover { // when hover, ease-in bottom-text; ease-out top-text .btn-text { opacity: 0; transform: translateY(-25%); transition: 0.25s ease-out; } &::after { opacity: 1; transform: translateY(0); transition: 0.75s 0.1s var(--ease-out-exponential); } } } } 複製代碼
//HTML代碼
<ul class="float-text-menu">
<li><a href="#" data-text="Home">Home</a></li>
<li><a href="#" data-text="Archives">Archives</a></li>
<li><a href="#" data-text="Tags">Tags</a></li>
<li><a href="#" data-text="Categories">Categories</a></li>
<li><a href="#" data-text="About">About</a></li>
</ul>
複製代碼
/*css代碼*/
@import url(https://fonts.googleapis.com/css?family=Lato);
body { display: flex; justify-content: center; align-items: center; height: 100vh; background: #1A1E23; } .float-text-menu { display: flex; flex-direction: column; list-style-type: none; li { a { display: flex; padding: 6px; color: white; font-family: Lato, sans-serif; text-decoration: none; overflow: hidden; span { position: relative; transition: 0.3s; &::before { position: absolute; content: attr(data-text); transform: translateY(130%); } } &:hover { span { transform: translateY(-130%); } } } } } 複製代碼
//js代碼
let floatTextMenuLinks = document.querySelectorAll(".float-text-menu li a");
floatTextMenuLinks.forEach(link => {
let letters = link.textContent.split("");
link.textContent = "";
letters.forEach((letter, i) => {
let span = document.createElement("span");
span.textContent = letter;
span.style.transitionDelay = `${i / 20}s`; span.dataset.text = letter; link.append(span); }); }); 複製代碼
//HTML代碼
<ul class="pagination">
<li class="page-prev">
<a class="prev" href="#"><svg t="1580195949197" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4493" width="20" height="20"><path d="M906.78272 588.78976c-0.02048 8.4992-6.88128 15.36-15.38048 15.37024l-443.6992-0.01024 75.70432 191.68256c2.51904 6.42048 0.48128 13.76256-5.03808 17.90976-5.51936 4.16768-13.13792 4.1472-18.61632-0.09216l-376.5248-289.47456c-3.77856-2.89792-6.00064-7.41376-6.00064-12.16512 0-4.78208 2.22208-9.27744 6.00064-12.1856l376.5248-289.47456c2.7648-2.11968 6.06208-3.19488 9.37984-3.19488 3.23584 0 6.5024 1.03424 9.23648 3.10272 5.51936 4.1472 7.5776 11.48928 5.03808 17.90976L447.68256 419.84l443.71968-0.01024c8.4992 0.01024 15.36 6.88128 15.36 15.36L906.78272 588.78976z" p-id="4494" fill="#777777"></path></svg></a>
</li>
<li class="page-number active"><a href="#">1</a></li>
<li class="page-number"><a href="#">2</a></li>
<li class="page-number"><a href="#">3</a></li>
<li class="page-number"><a href="#">4</a></li>
<li class="page-number"><a href="#">5</a></li>
<li class="page-number"><a href="#">6</a></li>
<li class="page-next">
<a class="next" href="#"><svg t="1580195920917" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4995" width="20" height="20"><path d="M906.77248 512c0 4.77184-2.21184 9.2672-5.9904 12.17536l-376.5248 289.4848c-2.7648 2.11968-6.06208 3.18464-9.3696 3.18464-3.25632 0-6.5024-1.03424-9.24672-3.09248-5.50912-4.15744-7.5776-11.48928-5.03808-17.90976l75.71456-191.67232L132.58752 604.17024c-8.48896 0-15.36-6.88128-15.36-15.36l0-153.6c0-8.48896 6.87104-15.36 15.36-15.36l443.72992 0-75.71456-191.68256c-2.53952-6.42048-0.47104-13.75232 5.04832-17.90976 5.50912-4.15744 13.12768-4.13696 18.60608 0.09216l376.5248 289.4848C904.56064 502.7328 906.77248 507.22816 906.77248 512z" p-id="4996" fill="#777777"></path></svg></a>
</li>
</ul>
複製代碼
/*css代碼*/
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #ECEFFC;
}
.pagination { --active-index: 0; display: flex; padding: 10px 20px; background: white; border-radius: 50px; box-shadow: 0 0.3px 0.6px rgba(0, 0, 0, 0.056), 0 0.7px 1.3px rgba(0, 0, 0, 0.081), 0 1.3px 2.5px rgba(0, 0, 0, 0.1), 0 2.2px 4.5px rgba(0, 0, 0, 0.119), 0 4.2px 8.4px rgba(0, 0, 0, 0.144), 0 10px 20px rgba(0, 0, 0, 0.2) ; list-style-type: none; li { margin: 0 5px; &.page-number { width: 50px; height: 50px; line-height: 50px; text-align: center; &:hover a { color: white; background: #777; } &.active a { color: white; background: #333; } } &.page-prev, &.page-next { font-weight: 700; } &.page-prev { margin-right: 20px; } &.page-next { margin-left: 20px; } a { display: block; line-height: 50px; font-size: 20px; font-weight: 600; text-decoration: none; color: #777; border-radius: 50%; transition: 0.3s; &.prev:hover path, &.next:hover path { fill: darken(#777, 50%); } } } } 複製代碼
//js代碼
let prevLink = document.querySelector(".prev");
let nextLink = document.querySelector(".next");
let pagination = document.querySelector(".pagination");
let pageNumberLinks = document.querySelectorAll(".page-number a");
let maxPageIndex = pageNumberLinks.length - 1;
pageNumberLinks.forEach((pageNumberLink, activeIndex) => {
pageNumberLink.addEventListener("click", () => {
pageNumberLinks.forEach(pageNumberLink =>
pageNumberLink.parentElement.classList.remove("active")
);
pageNumberLink.parentElement.classList.add("active");
(pagination as HTMLElement).style.setProperty(
"--active-index",
`${activeIndex}`
);
});
});
prevLink.addEventListener("click", () => {
pageNumberLinks.forEach(pageNumberLink =>
pageNumberLink.parentElement.classList.remove("active")
);
let activeIndex = Number(
(pagination as HTMLElement).style.getPropertyValue("--active-index")
);
activeIndex = activeIndex > 0 ? activeIndex - 1 : 0;
pageNumberLinks[activeIndex].parentElement.classList.add("active");
(pagination as HTMLElement).style.setProperty(
"--active-index",
`${activeIndex}`
);
});
nextLink.addEventListener("click", () => {
pageNumberLinks.forEach(pageNumberLink =>
pageNumberLink.parentElement.classList.remove("active")
);
let activeIndex = Number(
(pagination as HTMLElement).style.getPropertyValue("--active-index")
);
activeIndex = activeIndex < maxPageIndex ? activeIndex + 1 : maxPageIndex;
pageNumberLinks[activeIndex].parentElement.classList.add("active");
(pagination as HTMLElement).style.setProperty(
"--active-index",
`${activeIndex}`
);
});
複製代碼
//HTML代碼
<div class="loading">Loading</div>
複製代碼
/*css代碼*/
@import url("https://fonts.googleapis.com/css?family=Baloo+Bhaijaan&display=swap");
@function float-text-3d($shadow-color: #bbb, $depth: 10, $floating: false) { $shadows: (); // When dropped, it will shrink like a spring. When floating, it grows into its shape. @for $i from 1 to $depth { @if ($floating == false and $i > $depth / 2) { $shadow-color: transparent; } $shadows: append($shadows, 0 ($i * 1px) $shadow-color, comma); } // When dropped, the shadow reveals. When floating, the shadow fades. @if ($floating == false) { $shadows: append($shadows, 0 10px 10px rgba(0, 0, 0, 0.4), comma); } @else { $shadows: append($shadows, 0 50px 25px rgba(0, 0, 0, 0.2), comma); } @return $shadows; } body { display: flex; height: 100vh; justify-content: center; align-items: center; text-align: center; background: #2980b9; } .loading { display: flex; color: white; font-size: 5em; font-family: "Baloo Bhaijaan", cursive; text-transform: uppercase; span { text-shadow: float-text-3d($floating: false); transform: translateY(20px); animation: bounce 0.3s ease infinite alternate; } } @keyframes bounce { to { text-shadow: float-text-3d($floating: true); transform: translateY(-20px); } } 複製代碼
//js代碼
let loading = document.querySelector(".loading");
let letters = loading.textContent.split("");
loading.textContent = "";
letters.forEach((letter, i) => {
let span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${i / 10}s`; loading.append(span); }); 複製代碼
//HTML代碼
<dialog id="confirm-modal" class="modal">
<div class="modal-content">
<h2 class="modal-title">Are you sure?</h2>
<p class="modal-description">
You can't undo this action.
</p>
<div class="modal-options">
<button class="btn btn-round btn-fill btn-fill-left option confirm" data-text="Yes" onclick="document.querySelector('#confirm-modal').close()" ></button>
<button class="btn btn-round btn-fill btn-fill-right option cancel" data-text="No" onclick="document.querySelector('#confirm-modal').close()" ></button>
</div>
</div>
</dialog>
<form action="javascript:void(0);">
<button class="btn btn-danger" onclick="document.querySelector('#confirm-modal').showModal()" >
Delete history
</button>
</form>
複製代碼
/*css代碼*/
@import url(https://fonts.googleapis.com/css?family=Lato);
:root { --primary-color: hsl(171, 100%, 41%); --success-color: hsl(141, 53%, 53%); --danger-color: hsl(348, 86%, 61%); } body { display: flex; height: 100vh; justify-content: center; align-items: center; font-family: Lato, sans-serif; background: #ECEFFC; } .btn { position: relative; padding: 0.375rem 0.75rem; font-size: 1rem; line-height: 1.5; color: hsl(0, 0%, 13%); text-decoration: none; background-color: white; border: transparent; border-radius: 3px; outline: transparent; cursor: pointer; user-select: none; white-space: nowrap; transition: 0.25s; &-danger { color: white; background-color: var(--danger-color); &:hover { background-color: hsl(348, 86%, 53%); } } &-round { border-radius: 30px; } &-fill { overflow: hidden; &-left { &::before { transform: translateX(100%); } } &-right { &::before { transform: translateX(-100%); } } &::before { position: absolute; content: ""; top: 0px; left: 0px; width: 100%; height: 100%; border-radius: inherit; transition: 0.4s cubic-bezier(0.75, 0, 0.25, 1); } &::after { position: relative; content: attr(data-text); transition: 0.4s ease; } &:hover::before { transform: translateX(0); } &:hover::after { color: white !important; } } } .modal { position: fixed; top: 0; left: 0; bottom: 0; right: 0; z-index: 999; color: white; background-image: linear-gradient(to right, #0acffe 0%, #495aff 100%); border: transparent; border-radius: 12px; box-shadow: 0 2.8px 2.2px rgba(0, 0, 0, 0.02), 0 6.7px 5.3px rgba(0, 0, 0, 0.028), 0 12.5px 10px rgba(0, 0, 0, 0.035), 0 22.3px 17.9px rgba(0, 0, 0, 0.042), 0 41.8px 33.4px rgba(0, 0, 0, 0.05), 0 100px 80px rgba(0, 0, 0, 0.07); animation: show-modal 0.5s ease forwards; &::backdrop { background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(3px); } .model-icon { margin-bottom: 1.25rem; opacity: 0; animation: show-modal-icon 0.5s ease 0.2s forwards; } .modal-content { display: flex; flex-direction: column; align-items: center; width: 300px; padding: 1em; .modal-title { margin-top: 0; margin-bottom: 1.2rem; opacity: 0; animation: show-modal-text 0.5s ease 0.35s forwards; } .modal-description { margin: 0; opacity: 0; animation: show-modal-text 1s ease 0.5s forwards; } .modal-options { margin-top: 1rem; display: flex; justify-content: space-around; .option { padding: 0 2em; margin: 0.3em; font-size: 20px; font-weight: 700; line-height: 2; } .confirm { opacity: 0; animation: show-modal-option 0.5s ease 0.65s forwards; &::before { background: var(--success-color); } &::after { color: var(--success-color); } } .cancel { opacity: 0; animation: show-modal-option 0.5s ease 0.8s forwards; &::before { background: var(--danger-color); } &::after { color: var(--danger-color); } } } } } @keyframes show-modal { from { transform: scale(0.8); } 50% { transform: scale(1.1); opacity: 1; } to { transform: scale(1); opacity: 1; } } @keyframes show-modal-icon { from { transform: scale(0.4); } 50% { transform: scale(1.2); opacity: 1; } to { transform: scale(1); opacity: 1; } } @keyframes show-modal-text { from { transform: scale(0.6); } 50% { transform: scale(1.2); opacity: 1; } to { transform: scale(1); opacity: 1; } } @keyframes show-modal-option { from { transform: scale(0.4); } 50% { transform: scale(1.2); opacity: 1; } to { transform: scale(1); opacity: 1; } } 複製代碼
//HTML代碼
<button class="btn btn-pink btn-bubbles">Click Me</button>
複製代碼
/*css代碼*/
@import url(https://fonts.googleapis.com/css?family=Lato);
body { display: flex; height: 100vh; justify-content: center; align-items: center; background: #ECEFFC; } @function sample($list) { @return nth($list, random(length($list))); } @function bubbles($color, $count: 16) { $bubbles: (); // define your own bubbles here! $bubble-types: ( radial-gradient(circle, $color 20%, transparent 20%), radial-gradient(circle, transparent 20%, $color 20%, transparent 30%) ); @for $i from 1 through $count { $bubbles: append($bubbles, sample($bubble-types), comma); } @return $bubbles; } @function random_range($min, $max) { $rand: random(); $random_range: $min + floor($rand * (($max - $min) + 1)); @return $random_range; } @function random_sizes($count: 16) { $sizes: (); @for $i from 1 through $count { $sizes: append( $sizes, (random_range(10, 20) * 1%) (random_range(10, 20) * 1%), comma ); } @return $sizes; } .btn { --hue: 190; --btn-bg-color: hsl(var(--hue), 100%, 50%); --btn-bg-color-darker: hsl(var(--hue), 100%, 45%); position: relative; padding: 0.75rem 1.5rem; margin: 1rem; font-size: 1rem; font-family: Lato, sans-serif; line-height: 1.5; color: white; text-decoration: none; background-color: var(--btn-bg-color); border: 1px solid var(--btn-bg-color); border-radius: 4px; box-shadow: 0 0.1px 0.7px rgba(233, 30, 99, 0.141), 0 0.1px 1.7px rgba(233, 30, 99, 0.202), 0 0.3px 3.1px rgba(233, 30, 99, 0.25), 0 0.4px 5.6px rgba(233, 30, 99, 0.298), 0 0.8px 10.4px rgba(233, 30, 99, 0.359), 0 2px 25px rgba(233, 30, 99, 0.5) ; outline: transparent; overflow: hidden; cursor: pointer; user-select: none; white-space: nowrap; transition: 0.25s; &-pink { --hue: 330; } &-bubbles { overflow: visible; transition: transform ease-in 0.1s, background-color ease-in 0.1s, box-shadow ease-in 0.25s; &::before { position: absolute; content: ""; left: -2em; right: -2em; top: -2em; bottom: -2em; transition: ease-in-out 0.5s; background-repeat: no-repeat; background-image: bubbles(var(--btn-bg-color)); background-size: random_sizes(); background-position: 18% 40%, 20% 31%, 30% 30%, 40% 30%, 50% 30%, 57% 30%, 65% 30%, 80% 32%, 15% 60%, 83% 60%, 18% 70%, 25% 70%, 41% 70%, 50% 70%, 64% 70%, 80% 71%; animation: bubbles ease-in-out 0.75s forwards; } &:active { transform: scale(0.95); background: var(--btn-bg-color-darker); &::before { // when the clicked mouse is up, trigger the animation. animation: none; background-size: 0; } } } } @keyframes bubbles { 0% { background-position: 18% 40%, 20% 31%, 30% 30%, 40% 30%, 50% 30%, 57% 30%, 65% 30%, 80% 32%, 15% 60%, 83% 60%, 18% 70%, 25% 70%, 41% 70%, 50% 70%, 64% 70%, 80% 71%; } 50% { background-position: 10% 44%, 0% 20%, 15% 5%, 30% 0%, 42% 0%, 62% -2%, 75% 0%, 95% -2%, 0% 80%, 95% 55%, 7% 100%, 24% 100%, 41% 100%, 55% 95%, 68% 96%, 95% 100%; } 100% { background-position: 5% 44%, -5% 20%, 7% 5%, 23% 0%, 37% 0, 58% -2%, 80% 0%, 100% -2%, -5% 80%, 100% 55%, 2% 100%, 23% 100%, 42% 100%, 60% 95%, 70% 96%, 100% 100%; background-size: 0% 0%; } } 複製代碼
恭喜你將本文讀完了。不管是過了一場視覺盛宴也好,仍是學到了很多東西也好,仍是直接從書籤那導航到這裏也好(笑),CSS的力量始終超乎你的想象。只要勇於創做,你就是這個世界的神。css
聲明:文章著做權歸做者全部,若有侵權,請聯繫小編刪除。java
」
本文使用 mdnice 排版web