手把手教你实现飞机上的开窗关窗效果

3,529 阅读4分钟

前言

接着上个小飞机的效果,在这个动画的基础上,用CSS实现的一个在飞机上开窗关窗的效果。整个实现过程比较简单,大家可以先看到下面的效果预览部分,十分简单,没有花里胡哨的技巧。话不多说,咱们直接进入主题。

效果预览

最终实现的相关效果如下。

HTML部分

首先我们看到HTML部分,相关代码如下。

  <input type="checkbox" class="toggle">
    <figure class="window">
        <div class="curtain"></div>
        <div class="clouds">
            <span></span>
            <span></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
    </figure>

首先创建一个隐藏的复选框输入元素,用作交互触发器,通过CSS的:checked伪类实现状态切换。然后使用<figure>语义化标签作为窗户的主要容器,作为窗帘和云朵背景的父元素,通常通过CSS设置窗户的边框、阴影和整体样式,curtain代表窗户的窗帘部分,通过CSS实现窗帘的样式和动画效果。最后创建了多个<span>元素,每个代表一朵云。

CSS部分

首先我们看到类名toggle的样式,相关代码如下。

.toggle {
    position: absolute;
    filter: opacity(0);
    width: 25em;
    height: 35em;
    font-size: var(--font-size);
    cursor: pointer;
    z-index: 3;
}

这里定义了一个隐藏但可点击的切换开关元素。通过视觉隐藏 (filter: opacity(0)),使用滤镜将元素透明度设为0(完全透明),比opacity: 0visibility: hidden更好的选择,因为它可以保持元素完全可点击和可聚焦,不影响布局(元素仍占据空间),不会阻止鼠标事件。

配合CSS选择器如:checked,可以实现复杂的交互效果而无需JavaScript。

然后是窗户和窗帘的CSS部分,相关代码如下。

.toggle:checked ~ .window .curtain {
    top: -90%;
}
.window .curtain::before {
    content: '';
    position: absolute;
    width: 40%;
    height: 0.8em;
    background-color: #808080;
    left: 30%;
    bottom: 1.6em;
    border-radius: 0.4em;
}
.window .curtain::after {
    content: '';
    position: absolute;
    width: 1.6em;
    height: 0.8em;
    bottom: 1.6em;
    background-image: radial-gradient(orange, orangered);
    left: calc((100% - 1.6em) / 2);
    border-radius: 0.4em;
}
.toggle:checked ~ .window .curtain::after {
    background-image: radial-gradient(lightgreen, limegreen);
}

这里实现了窗帘的交互效果和样式细节。首先是窗帘开合动画控制,当复选框被选中时,将窗帘向上移动90%的高度,:checked是匹配被选中的复选框,~是通用兄弟选择器,选择.toggle之后的所有.window元素,最终选择.toggle之后.window内的.curtain元素。

所以最终的动画效果是当隐藏的复选框被点击时,窗帘会移动到顶部-90%的位置,实现"打开"效果。

当复选框被选中时,将把手颜色变为绿色渐变,当窗帘打开时,把手颜色从橙红色变为绿色,提供视觉反馈,表示状态已改变。

这里展示了如何通过纯CSS创建具有状态反馈的交互式组件,利用CSS的:checked伪类实现交互,使用::before::after添加装饰元素,无需额外HTML,通过颜色变化提供状态指示。

最后是窗外的云的CSS样式,相关代码如下。

.window .clouds {
    position: relative;
    width: 20em;
    height: 30em;
    background-color: deepskyblue;
    left: calc((100% - 20em) / 2);
    top: calc((100% - 30em) / 2);
    border-radius: 7em;
    box-shadow: 0 0 0 0.4em #808080;
    overflow: hidden;
}
.clouds span {
    position: absolute;
    width: 10em;
    height: 4em;
    background-color: white;
    top: 20%;
    border-radius: 4em;
    animation: move 4s linear infinite;
}
@keyframes move {
    from {left: -150%;}
    to {left: 150%;}
}

这里创建了一个天空背景和飘动的云朵动画效果:

精确定位

  • 使用calc()函数实现天空区域的完美居中
  • left: calc((100% - 20em) / 2) 水平居中
  • top: calc((100% - 30em) / 2) 垂直居中

云朵形状

  • 通过border-radius: 4em创建椭圆形云朵
  • 高度(4em)是宽度(10em)的40%,形成扁平椭圆形状

动画设计

  • 使用linear线性动画确保匀速移动
  • infinite无限循环创造持续飘动效果
  • 从-150%到150%确保云朵完全穿过可见区域

视觉层次

  • 天蓝色背景与白色云朵形成鲜明对比
  • 灰色边框定义天空区域边界
  • overflow: hidden确保动画元素不会破坏布局

这里创建了一个视觉上吸引人的天空背景,云朵从左侧进入,横穿天空区域,然后从右侧离开,形成连续循环的飘动效果。

总结

以上就是整个效果的实现过程了,代码简单易懂。另外,感兴趣的小伙伴们还可以在现有基础上发散思维,比如增加点其他效果,或者更改颜色等等。关于该效果如果大家有更好的想法欢迎在评论区分享,互相学习。最后,完整代码在码上掘金里可以查看,如果有什么问题大家在评论区里讨论~