常用的css特效(一)

1、交错动画

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;
  }
}

2、用JS分割文本

一般我们都是从第一个元素开始交错的。但如果要从中间元素开始交错的话,就要给当前元素的延时各加上一个值,这个值就是中间元素的下标到当前元素的下标的距离(也就是下标之差的绝对值)与步长的乘积,即:delay + Math.abs(i - middle) * step,其中中间元素的下标middle = letters.filter(e => e !== "").length / 2

Ano hi watashitachi mada shiranai no Fushigi no monogatari desu.

@import url("https://fonts.googleapis.com/css?family=Lora:400,400i,700");

body {
  display: flex;
  flex-direction: column;
  height: 100vh;
  justify-content: center;
  align-items: center;
  background-image: linear-gradient(rgba(16, 16, 16, 0.8),
      rgba(16, 16, 16, 0.8)),
    url(https://i.loli.net/2019/10/18/buDT4YS6zUMfHst.jpg);
  background-size: cover;
}

p {
  margin: 0 9em;
  font-size: 2em;
  font-weight: 600;
}

.landIn {
  display: flex;
  flex-wrap: wrap;
  line-height: 1.8;
  color: white;
  font-family: Lora, serif;
  white-space: pre;

  span {
    animation: landIn 0.8s ease-out both;
  }
}

@keyframes landIn {
  from {
    opacity: 0;
    transform: translateY(-20%);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}
let landInTexts = document.querySelectorAll(".landIn");
landInTexts.forEach(landInText => {
  let letters = landInText.textContent.split("");
  landInText.textContent = "";
  letters.forEach((letter, i) => {
    let span = document.createElement("span");
    span.textContent = letter;
    span.style.animationDelay = `${i * 0.05}s`;
    landInText.append(span);
  });
});

sword art online
@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);
  }
}
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);
});

3、随机粒子动画

常用的css特效(一)_第1张图片

200 个 snow!!!
body {
  height: 100vh;
  background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
  overflow: hidden;
  filter: drop-shadow(0 0 10px white);
}

@function random_range($min, $max) {
  $rand: random();
  $random_range: $min + floor($rand * (($max - $min) + 1));
  @return $random_range;
}

.snow {
  $total: 200;
  position: absolute;
  width: 10px;
  height: 10px;
  background: white;
  border-radius: 50%;

  @for $i from 1 through $total {
    $random-x: random(1000000) * 0.0001vw;
    $random-offset: random_range(-100000, 100000) * 0.0001vw;
    $random-x-end: $random-x + $random-offset;
    $random-x-end-yoyo: $random-x + ($random-offset / 2);
    $random-yoyo-time: random_range(30000, 80000) / 100000;
    $random-yoyo-y: $random-yoyo-time * 100vh;
    $random-scale: random(10000) * 0.0001;
    $fall-duration: random_range(10, 30) * 1s;
    $fall-delay: random(30) * -1s;

    &:nth-child(#{$i}) {
      opacity: random(10000) * 0.0001;
      transform: translate($random-x, -10px) scale($random-scale);
      animation: fall-#{$i} $fall-duration $fall-delay linear infinite;
    }

    @keyframes fall-#{$i} {
      #{percentage($random-yoyo-time)} {
        transform: translate($random-x-end, $random-yoyo-y) scale($random-scale);
      }
      
      to {
        transform: translate($random-x-end-yoyo, 100vh) scale($random-scale);
      }
    }
  }
}

4、伪类

@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);
      }
    }
  }
}

7、attr()生成文本内容

@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%);
        }
      }
    }
  }
}
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);
  });
});

8、overflow障眼法

@import url(https://fonts.googleapis.com/css?family=Lato);

body {
  display: flex;
  height: 100vh;
  justify-content: center;
  align-items: center;
  background: #1A1E23;
}

.btn {
  --hue: 190;
  position: relative;
  padding: 1rem 3rem;
  font-size: 1rem;
  line-height: 1.5;
  color: white;
  text-decoration: none;
  text-transform: uppercase;
  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: 187;
  }

  &-ghost {
    color: hsl(var(--hue), 100%, 41%);
    background-color: transparent;
    border-color: hsl(var(--hue), 100%, 41%);

    &:hover {
      color: white;
    }
  }

  &-shine {
    color: white;

    &::before {
      position: absolute;
      content: "";
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: linear-gradient(
        120deg,
        transparent,
        hsla(var(--hue), 100%, 41%, 0.5),
        transparent
      );
      transform: translateX(-100%);
      transition: 0.6s;
    }

    &:hover {
      background: transparent;
      box-shadow: 0 0 20px 10px hsla(var(--hue), 100%, 41%, 0.5);
    }

    &:hover::before {
      transform: translateX(100%);
    }
  }
}

9、兄弟选择符定制表单元素

常用的css特效(一)_第2张图片

My Special Todo List
// color scheme: https://coolors.co/e63946-585b57-7b9fa1-264456-0b1420
@import url("https://fonts.googleapis.com/css?family=Lato:400,400i,700");

body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: #1A1E23;
}

.todo-list {
  display: flex;
  flex-direction: column;
  padding: 0 75px 10px 30px;
  background: #162740;
  border: transparent;

  .todo-list__title {
    padding: 3px 6px;
    color: #f1faee;
    background-color: #264456;
  }

  .todo-list__label {
    display: flex;
    align-items: center;
    margin: 40px 0;
    font-size: 24px;
    font-family: Lato, sans-serif;
    color: #f1faee;
    cursor: pointer;

    input[type="checkbox"] {
      opacity: 0;
      appearance: none;

      & + .check {
        position: absolute;
        width: 25px;
        height: 25px;
        border: 2px solid #f1faee;
        transition: 0.2s;
      }

      &:checked + .check {
        width: 25px;
        height: 15px;
        border-top: transparent;
        border-right: transparent;
        transform: rotate(-45deg);
      }

      & ~ span {
        position: relative;
        left: 40px;
        white-space: nowrap;
        transition: 0.5s;

        &::before {
          position: absolute;
          content: "";
          top: 50%;
          left: 0;
          width: 100%;
          height: 1px;
          background: #f1faee;
          transform: scaleX(0);
          transform-origin: right;
          transition: transform 0.5s;
        }
      }

      &:checked ~ span {
        color: #585b57;

        &::before {
          transform: scaleX(1);
          transform-origin: left;
        }
      }
    }
  }
}

11、border-radius


@import url(https://fonts.googleapis.com/css?family=Lato);

@mixin center {
  display: flex;
  justify-content: center;
  align-items: center;
}

body {
  @include center;
  height: 100vh;
  font-family: Lato, sans-serif;
  background: #ECEFFC;
}

.navtab {
  --navtab-width: 600px;
  --navtab-item-width: calc(var(--navtab-width) / 4 - 20px);
  --navtab-overlay-width: calc(var(--navtab-item-width) + 80px);
  --active-index: 0;

  position: relative;
  width: var(--navtab-width);
  height: 150px;
  background: white;
  border: 1em solid white;
  // https://9elements.github.io/fancy-border-radius/full-control.html#15.5.15.15-50.95.50.85-150.600
  border-radius: 5% 5% 15% 15% / 15% 15% 50% 50%;
  overflow: hidden;

  ul {
    @include center;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    list-style-type: none;

    .navtab-item {
      @include center;
      z-index: 2;
      flex-direction: column;
      width: var(--navtab-item-width);
      height: 100%;
      color: #0288d1;
      cursor: pointer;
      transition: 0.5s ease;

      svg {
        transition: 0.5s ease;
      }

      span {
        font-size: 20px;
        user-select: none;
        opacity: 0;
        transition: 0.5s ease;
      }

      &.active {
        width: var(--navtab-overlay-width);

        svg {
          transform: translateY(-10px);
        }

        span {
          opacity: 1;
        }
      }
    }
  }

  &::after {
    position: absolute;
    content: "";
    top: 0;
    left: 0;
    height: 100%;
    width: var(--navtab-overlay-width);
    background: #b3e5fc;
    border-radius: 20px;
    transform: translateX(calc(var(--navtab-item-width) * var(--active-index)));
    transition: 0.5s ease;
  }
}
let navtab = document.querySelector("nav.navtab");
let navtabItems = document.querySelectorAll("li.navtab-item");
navtabItems.forEach((navtabItem, activeIndex) =>
  navtabItem.addEventListener("click", () => {
    navtabItems.forEach(navtabItem => navtabItem.classList.remove("active"));
    navtabItem.classList.add("active");
    (navtab as HTMLElement).style.setProperty(
      "--active-index",
      `${activeIndex}`
    );
  })
);

12、box-shadow


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%);
      }
    }
  }
}
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}`
  );
});

15、发光文本

常用的css特效(一)_第3张图片

Hello World

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Mattis pellentesque id nibh tortor. Suspendisse ultrices gravida dictum fusce ut placerat orci nulla. A lacus vestibulum sed arcu.

@import url("https://fonts.googleapis.com/css?family=Lora:400,400i,700");

body {
  display: flex;
  flex-direction: column;
  height: 100vh;
  justify-content: center;
  align-items: center;
  background-image: linear-gradient(
      rgba(16, 16, 16, 0.8),
      rgba(16, 16, 16, 0.8)
    ),
    url(https://i.loli.net/2019/11/03/RtVq2wxQYySDb8L.jpg);
  background-size: cover;
}

p {
  margin: 0em 5em 4em 5em;
}

h1, p {
  text-align: left;
  line-height: 1.8;
  font-family: Lora, serif;
}

.glowIn {
  color: white;

  span {
    animation: glow-in 0.8s both;
  }
}

@keyframes glow-in {
  from {
    opacity: 0;
  }
  65% {
    opacity: 1;
    text-shadow: 0 0 25px white;
  }
  75% {
    opacity: 1;
  }
  to {
    opacity: 0.7;
  }
}
let glowInTexts = document.querySelectorAll(".glowIn");
glowInTexts.forEach(glowInText => {
  let letters = glowInText.textContent.split("");
  glowInText.textContent = "";
  letters.forEach((letter, i) => {
    let span = document.createElement("span");
    span.textContent = letter;
    span.style.animationDelay = `${i * 0.05}s`;
    glowInText.append(span);
  });
});

16、霓虹文本

常用的css特效(一)_第4张图片

fushigi no monogatari
@import url(https://fonts.googleapis.com/css?family=Pacifico);

body {
  display: flex;
  height: 100vh;
  justify-content: center;
  align-items: center;
  text-align: center;
  background: black;
}

.neon {
  color: #cce7f8;
  font-size: 2.5rem;
  font-family: 'Pacifico', cursive;
  text-transform: uppercase;
  animation: shining 0.1s alternate infinite;
}

@keyframes shining {
  from {
    text-shadow: 0 0 6px rgba(182, 211, 207, 0.9),
      0 0 30px rgba(182, 211, 207, 0.3), 0 0 12px rgba(15, 115, 223, 0.5),
      0 0 21px rgba(15, 115, 223, 0.9), 0 0 34px rgba(15, 115, 223, 0.8),
      0 0 54px rgba(15, 115, 223, 0.9);
  }
  to {
    text-shadow: 0 0 6px rgba(182, 211, 207, 1),
      0 0 30px rgba(182, 211, 207, 0.4), 0 0 12px rgba(15, 115, 223, 0.6),
      0 0 22px rgba(15, 115, 223, 0.8), 0 0 38px rgba(15, 115, 223, 0.9),
      0 0 60px rgba(15, 115, 223, 1);
  }
}

17、伪3D文本

常用的css特效(一)_第5张图片

Loading
@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);
  }
}
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);
});

18、background-clip:text

能将背景裁剪成文字的前景色,常用来和color: transparent配合生成渐变文本

// https://picular.co/bluemoon

@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: #1A1E23;
}

ul {
  display: flex;
  flex-direction: column;
  align-items: start;
  list-style-type: none;

  li {
    padding: 6px 0;

    a {
      --fill-color: #198CE6;
      position: relative;
      display: block;
      padding: 4px 0;
      font: 700 3rem Raleway, sans-serif;
      text-decoration: none;
      text-transform: uppercase;
      -webkit-text-stroke: 2px var(--fill-color);
      background: linear-gradient(var(--fill-color) 0 100%) left / 0 no-repeat;
      color: transparent;
      background-clip: text;
      transition: 0.5s linear;

      &:hover {
        background-size: 100%;
      }
    }
  }
}

19、linear-gradient


  

@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;
  }
}

20、radial-gradient

径向渐变常用于生成圆形背景,上面例子中Snow的背景就是一个椭圆形的径向渐变此外,由于背景可以叠加,我们可以叠加多个不同位置大小的径向渐变来生成圆点群,再加上动画就产生了一种微粒效果,无需多余的div元素。

常用的css特效(一)_第6张图片

@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%;
  }
}

21、conic-gradient

常用的css特效(一)_第7张图片

body {
  display: flex;
  height: 100vh;
  justify-content: center;
  align-items: center;
}

.gauges {
  display: flex;
}

.gauge {
  margin: 1rem;
}

22、backdrop-filter

常用的css特效(一)_第8张图片

sakura

@import url("https://fonts.googleapis.com/css?family=Lato:200");

body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: url(https://i.loli.net/2019/11/17/GAYyzeKsiWjP5qO.jpg);
  background-size: cover;
  background-position: center;
}

.frosted-glass {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 72vw;
  height: 36vh;
  box-shadow: 0 0.3px 0.7px rgba(0, 0, 0, 0.126),
    0 0.9px 1.7px rgba(0, 0, 0, 0.179), 0 1.8px 3.5px rgba(0, 0, 0, 0.224),
    0 3.7px 7.3px rgba(0, 0, 0, 0.277), 0 10px 20px rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(20px);
  transition: 0.5s ease;

  &:hover {
    box-shadow: 0 0.7px 1px rgba(0, 0, 0, 0.157),
      0 1.7px 2.6px rgba(0, 0, 0, 0.224), 0 3.5px 5.3px rgba(0, 0, 0, 0.28),
      0 7.3px 11px rgba(0, 0, 0, 0.346), 0 20px 30px rgba(0, 0, 0, 0.5);
  }

  .title {
    padding-left: 0.375em;
    font-size: 3.6em;
    font-family: Lato, sans-serif;
    font-weight: 200;
    letter-spacing: 0.75em;
    color: white;

    @media (max-width: 640px) {
      font-size: 2em;
    }
  }
}

23、mix-blend-mode


ocean

@font-face {
  font-family: Biko;
  src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/biko-black.woff");
}

body {
  display: flex;
  height: 100vh;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}

video,
h1 {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}

video {
  object-fit: cover;
}

h1 {
  font-size: 20vw;
  font-family: Biko, sans-serif;
  font-weight: 700;
  line-height: 100vh;
  text-transform: uppercase;
  text-align: center;
  background: white;
  mix-blend-mode: screen;
}

24、clip-path

PS里的裁切,可以制作各种不规则形状。如果和动画结合也会相当有意思。

常用的css特效(一)_第9张图片

Contact
alphardex
[email protected]
(+86)13063509980
@import url(https://fonts.googleapis.com/css?family=Lato);

body {
  display: flex;
  height: 100vh;
  justify-content: center;
  align-items: center;
  font-family: Lato, sans-serif;
  background: #ECEFFC;
}

// box-shadow will be effected by clip-path, so use a wrapper + drop-shadow to make shadow.
.shadow {
  filter: drop-shadow(-2px 2px 8px rgba(50, 50, 0, 0.5));
}

.card {
  clip-path: inset(0 0 70% 0);
  transform: translateY(30%);
  transition: 0.5s ease;

  .card-header {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 400px;
    height: 100px;
    font-size: 2em;
    color: white;
    background-color: #2979ff;
    clip-path: inset(0 19% 0 19%);
    transition: 0.5s ease;
  }

  .card-body {
    box-sizing: border-box;
    padding: 1.25em;
    width: 400px;
    height: 225px;
    font-size: 1.5em;
    background: white;
    clip-path: inset(0 19% 0 19%);
    transition: 0.5s ease;

    dl {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      width: 100%;
      height: 100%;
      margin: 0;
    }

    span {
      opacity: 0;
      transform: translateY(100%);
      transition: 0.5s ease-in;

      @for $i from 1 through 3 {
        &:nth-child(#{$i}) {
          transition-delay: $i * 0.1s;
        }
      }

      dt,
      dd {
        display: inline;
        margin: 0;

        svg {
          margin-right: 0.3em;
        }
      }
    }
  }

  &:hover {
    transform: translateY(0);
    clip-path: inset(0 0 0 0);

    .card-header,
    .card-body {
      clip-path: inset(0 0 0 0);
    }

    span {
      opacity: 1;
      transform: translateY(0);
    }
  }
}

27、彩蛋

body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: #fafafa;
}

.shinchou-menu {
  --highlight-text-color: #00ACF0;
  display: flex;
  flex-direction: column;
  list-style-type: none;

  li {
    margin: 6px;

    a {
      position: relative;
      display: inline-flex;
      padding: 6px 2px 6px 2px;
      color: black;
      font-size: 1.6em;
      font-weight: 700;
      line-height: 1; // ensure span is a square
      text-decoration: none;
      overflow: hidden;

      &::before {
        position: absolute;
        content: '';
        top: 0;
        left: 0;
        z-index: -2;
        width: 100%;
        height: 100%;
        background: black;
      }

      &:hover {
        span {
          color: white !important;
          text-shadow: 0 0 10px var(--highlight-text-color);
        }
      }

      span {
        position: relative;
        margin: 0 5px 0 4px;
        transition: 0.3s;

        &.highlight::before {
          position: absolute;
          content: '';
          top: -3px;
          left: -3px;
          bottom: -3px;
          right: -3px;
          z-index: -1;
          background: var(--highlight-text-color);
        }

        &:not(.highlight) {
          color: var(--highlight-text-color);
        }
      }
    }
  }
}
let shinchouMenuLinks = document.querySelectorAll(".shinchou-menu li a");
shinchouMenuLinks.forEach(link => {
  let letters = link.textContent.split("");
  link.textContent = "";
  letters.forEach((letter, i) => {
    let span = document.createElement("span");
    span.textContent = letter;
    if (i < 2) {
      span.className = "highlight";
    }
    span.style.transitionDelay = `${i / 10}s`;
    link.append(span);
  });
});

 

你可能感兴趣的:(css特效)