发布于 2026-01-06 2 阅读
0

CSS 日夜切换(仅 CSS/HTML)[第二部分] 结果

CSS 日夜切换(仅限 CSS/HTML)[第二部分]

结果

现在让我们通过添加月亮、昼夜过渡效果以及一些闪烁的星星作为奖励,来完成我们漂亮的昼夜切换的夜间状态。

阅读全文或在 YouTube 上观看我的编程演示:

结果

关灯

那么,我们先从关灯开始,这意味着一旦开关被取消选中,背景颜色和边框颜色就会褪成较深的蓝色调。

input.day-night-switch {
  // unchecked styles
  + label.day-night-switch {
    border-color: #2a4569;
    background-color: #223349;
  }
}
Enter fullscreen mode Exit fullscreen mode

由于夜晚一切事物看起来都会变暗(谁能想到呢……),因此,一旦取消选中复选框,山脉也会从较浅的灰色变为较深的灰色。

input.day-night-switch {
  // unchecked styles
  + label.day-night-switch {
    > .mountains {
      > * {
        background-color: #878787;
        border-color: #5c5c5c;
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

日落

首先,我们来定义太阳和月亮落山时应该移动到的位置。在这种情况下,太阳和月亮将向下移动到下方边缘高度的25%,也就是整个开关高度的1.25倍。

input.day-night-switch {
  --shift: calc(var(--height) * 1.25);
}
Enter fullscreen mode Exit fullscreen mode

现在,为了模拟日落效果,我们只需top在取消选中复选框后立即更新该属性的值。此外,我们还会缩小其尺寸,以0增强日落效果。

input.day-night-switch {
  // unchecked styles
  + label.day-night-switch {
    > .celestial {
      &.sun {
        transition-delay: 0ms;
        top: var(--shift);
        left: var(--pos-right);
        transform: scale(0);
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

让月亮出来吧!

既然太阳可以升起落下,月亮也有了容身之处。因此,我们不妨div分别设置一个celestial用于太阳和月亮通用样式的类,以及一个moon用于月亮专属样式的类……

label(for="day-night").day-night-switch
  ...
  div.celestial.moon
Enter fullscreen mode Exit fullscreen mode

……其中最重要的是月亮的颜色:

label.day-night-switch {
  > .celestial {
    &.moon {
      background-color: #d2cec4;
      border-color: #a9a18f;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

与太阳类似,月亮的坐标也会被设定为它在白天(已勾选)和夜晚(未勾选)应该在的位置:

input.day-night-switch {
  // checked styles
  &:checked {
    + label.day-night-switch {
      > .celestial {
        &.moon {
          transition-delay: 0ms;
          left: var(--pos-left);
          top: var(--shift);
          transform: scale(0);
        }
      }
    }
  }
}

input.day-night-switch {
  // unchecked styles
  + label.day-night-switch {
    > .celestial {
      &.moon {
        transition-delay: var(--transition-duration);
        top: var(--padding);
        left: var(--pos-left);
        overflow: hidden;
        transform: scale(1);
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

陨石坑!

然而,这轮月亮看起来仍然有点暗淡无光,不太像月亮。为了解决这个问题,我们来添加一些陨石坑:

label(for="day-night").day-night-switch
  ...
  div.celestial.moon
    div.craters
      div.crater
      div.crater
      div.crater
      div.crater
      div.crater
Enter fullscreen mode Exit fullscreen mode

与云层非常相似,陨石坑相对于--switch-size月球内部的位置也相同。每个陨石坑最终都只是一条div穿过月球的圆形路径border-radius: 50%

每个陨石坑的边界宽度都设置为略小于月球边界宽度的值。但它绝不能小于 65% 1px,这是通过使用一个max(...)函数来实现的,该函数始终返回传递给它的所有值中的最大值。因此,65% 的值--border-width绝不能是最小的值1px

label.day-night-switch {
  > .celestial {
    &.moon {
      > .craters {
        > .crater {
          background-color: #d2cec4;
          border-color: #a9a18f;
          border-width: calc(max(var(--border-width) * 0.65, 1px));
          border-style: solid;
          position: absolute;

          &:nth-child(1) {
            border-radius: 50%;
            width: calc(var(--switch-size) * 0.15);
            height: calc(var(--switch-size) * 0.15);
            top: calc(var(--switch-size) * 0.7);
            left: calc(var(--switch-size) * 0.4);
          }

          &:nth-child(2) {
            border-radius: 50%;
            width: calc(var(--switch-size) * 0.3);
            height: calc(var(--switch-size) * 0.3);
            top: calc(var(--switch-size) * 0.1);
            left: calc(var(--switch-size) * -0.05);
          }

          &:nth-child(3) {
            border-radius: 50%;
            width: calc(var(--switch-size) * 0.1);
            height: calc(var(--switch-size) * 0.1);
            top: calc(var(--switch-size) * 0.2);
            left: calc(var(--switch-size) * 0.6);
          }

          &:nth-child(4) {
            border-radius: 50%;
            width: calc(var(--switch-size) * 0.1);
            height: calc(var(--switch-size) * 0.1);
            top: calc(var(--switch-size) * 0.3);
            left: calc(var(--switch-size) * 0.25);
          }

          &:nth-child(5) {
            border-radius: 50%;
            width: calc(var(--switch-size) * 0.2);
            height: calc(var(--switch-size) * 0.2);
            top: calc(var(--switch-size) * 0.5);
            left: calc(var(--switch-size) * 0.8);
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

闪耀的星星

最后,让我们添加一些闪烁的星星,让夜空更加清晰。好消息是,.decorationDOM 中已经有一些用于云朵的元素,而这些元素在夜晚并不需要。所以我们只需将它们重新用于星星即可。

input.day-night-switch {
  // unchecked styles
  + label.day-night-switch {
    > .decorations {
      > .decoration {
        position: absolute;
        background-color: white;
        border-radius: 50%;
        width: calc(max(var(--border-width) * 0.75, 2px));
        height: calc(max(var(--border-width) * 0.75, 2px));
        animation: 2s sparkle ease-in-out infinite;
        animation-direction: alternate;

        &:nth-child(1) {
          top: calc(var(--switch-size) * 0.7);
          left: calc(var(--switch-size) * 1.7);
        }
        &:nth-child(2) {
          animation-delay: 300ms;
          animation-duration: 3s;
          top: calc(var(--switch-size) * 0.4);
          left: calc(var(--switch-size) * 1.4);
        }
        &:nth-child(3) {
          animation-delay: 800ms;
          animation-duration: 3.5s;
          top: calc(var(--switch-size) * 0.9);
          left: calc(var(--switch-size) * 2.2);
        }
        &:nth-child(4) {
          animation-delay: 1400ms;
          animation-duration: 2.5s;
          top: calc(var(--switch-size) * 0.3);
          left: calc(var(--switch-size) * 2);
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

闪烁动画本身只会让每颗星星的透明度在 100% 和 25% 之间交替:

@keyframes sparkle {
  0% {
    opacity: 1;
  }

  100% {
    opacity: 0.25;
  }
}

input.day-night-switch {
  // unchecked styles
  + label.day-night-switch {
    > .decorations {
      > .decoration {
        transition: all var(--transition-duration) ease-in-out;
        animation: 2s sparkle ease-in-out infinite;
        animation-direction: alternate;
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

为了让闪光效果更加精彩,我们对每颗星星应用了不同的延迟和持续时间……啊,完成了!

// unchecked styles
  + label.day-night-switch {
    > .decorations {
      > .decoration {

        &:nth-child(2) {
          animation-delay: 300ms;
          animation-duration: 3s;
        }
        &:nth-child(3) {
          animation-delay: 800ms;
          animation-duration: 3.5s;
        }
        &:nth-child(4) {
          animation-delay: 1400ms;
          animation-duration: 2.5s;
        }
      }
    }
Enter fullscreen mode Exit fullscreen mode

这就是制作一个如此精巧的日夜切换开关所需的全部材料。希望你享受制作的过程。

文章来源:https://dev.to/crayoncode/css-day-night-switch-css-html-only-part-2-3ioc