这么炫酷的 3D Menu 效果,真的不来看看?

我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!

最近在研究 CSS3 中关于 3D 方面的属性,越发的觉得 CSS3 是真的好玩,虽然目前主要的工作是 2B 的业务,但是却并不妨碍我有一颗 2C 的心,刚好最近学到了一个比较炫酷的 3D 菜单案例,今天我们就一起来好好把玩一下,废话不多说,咱们开整!

CSS3 - 3D Menu

首先我们先来看一下一般的 Menu 是什么样的,然后再来对比一下咱们即将要盘的 3D Menu 是什么样的,先来看两张图,如下:

image.png

就拿掘金来举例,图中画出来的就是 Menu ,也就是网站的菜单,大部分网站的菜单跟掘金都是差不多的,下面咱们在一起来看一下 3D 的菜单是什么样的,如图:

111.gif

通过两张图片可以明显的看出,3D Menu 与普通 Menu 的展示和交互完全不同,下面我们就来一步步解刨一下这个效果。

基础搭建

要实现上述的 3D 效果,我们需要先来搭建一下相关的 HTML,其实也很简单,代码如下:

<ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Price</a></li>
    <li><a href="#">Our Team</a></li>
    <li><a href="#">Contact</a></li>
</ul>
复制代码

页面中只需要通过 ullia 等标签即可搭建基础的架子,有了基础的标签,我们需要先来初始化一下相关的样式,因为每个浏览器在不同的标签上都会添加一些默认的样式,因此我们需要将这些默认的样式都去掉,这里我使用的是 less,通过编译后,最后还是会转换为 css。我们先来看一下初始化的样式,如下:

* {
    margin: 0; 
    padding: 0;
    box-sizing: border-box;
    font-size: sans-serif;
}
复制代码

在初始化的时候,通过 * 这个通配符找到页面中所有的标签,但实际上这样是不太好的方式,这里只是图个简便,所以使用通配符来选择所有标签,实际开发中我们会将需要的标签选取出来,然后再去除它们的默认样式。

在上述默认样式中,通过通配符选择所有的标签后,将这些标签的 marginpadding 都设置为 0,因为浏览器默认有一个 8px 的边距会影响到我们,因此这里将默认的样式去除,然后设置所有标签的 盒模型怪异盒模型,对于盒模型不了解的童靴可以到掘金中搜索一下,有很多文章进行讲解,这里就不做过多的介绍。

设置完初始样式后,我们需要给 body 添加相关的样式,因为这里是做这个 3D Menu 的效果,因此才需要在 body 上设置相关的样式,实际开发中就需要根据相关的需求来了,具体的代码如下:

body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: #424345;
}
复制代码

我们在 body 中设置 display 的属性为 flex ,将 body 设置为一个盒子,然后将 body 中所有的元素都设置为上下左右居中对象,并给 body 一个最小的高度,也就是浏览器的高度,最后添加一个背景色。

基础的内容都准备好后,我们要真正开始编写这个 3D Menu 相关的样式了,因为这个效果是纯 CSS 完成的,因此不设计任何的 JavaScript 代码,大家可以放心食用。

Menu 效果

通过上面的图片我们可以看出,这个 Menu 像一个立体的效果,其实也就解释了 3D 效果简单来说就是一个视觉差,让我们的大脑误以为一个平面的效果是立体的。因此我们可以通过如下代码让我们的 Menu 先“立”起来,代码如下:

ul {
    position: relative;
    transform: skewY(-15deg);

    li {
        position: relative;
        list-style: none;
        width: 200px;
        background: #3e3f46;
        padding: 15px;
        transition: .5s;
        
        a {
            text-decoration: none;
            color: #ccc;
            display: block;
            text-transform: uppercase;
            letter-spacing: .05em;
            transition: .5s;
        }
    }
}
复制代码

上述代码采用 less 编写,因此可以直接进行嵌套编写,如果对 less 不了解的童鞋,也可以直接使用 css 进行编写,效果是一样的,通过上述的代码,我们可以得到如下的效果:

image.png

我们在 ul 标签上设置了一个 transform: skewY(-15deg),这样就让整个 ul 沿着纵坐标倾斜了 15 度,这样看起来还不像一个 3D 的效果,让我们继续来完善一下,代码如下:

ul {
    position: relative;
    transform: skewY(-15deg);

    li {
        // ... other code
        
        &::before {
            content: '';
            position: absolute;
            top: 0;
            left: -40px;
            width: 40px;
            height: 100%;
            background: #35383e;
            transform-origin: right;
            transform: skewY(45deg);
            transition: .5s;
        }

        &::after {
            content: '';
            position: absolute;
            top: -40px;
            left: 0;
            width: 100%;
            height: 40px;
            background: #35383e;
            transform-origin: bottom;
            transform: skewX(45deg);
            transition: .5s;
        }
        
        // ... other code
    }
}
复制代码

在上述代码中,我们通过给 li 标签的 beforeafter 伪类添加相关的属性,其中最主要的是需要设置伪类元素的旋转点,也就是上述代码中的 transform-origin,在 before 伪类中,我们设置当前伪类的旋转点是右边,因此这个伪类元素会向左边倾斜负 45 度;而在 after 伪类中,设置的旋转点是底部,因此这个伪类的就是向上倾斜 45 度,最终的效果如下图所示:

image.png

这里还有一个点需要注意一下,因为我们给每个 li 设置了一个背景色,而 beforeafter 伪类中也添加了相关的背景色,并且通过定位来将它们的位置指定到 li 的左边和顶部,从而让我们看到这个 Menu “立”起来了。我们都知道定位的元素是有层级的,也就是 z-index,因此我们需要设置每一个 liz-index,那么我们该如何设置呢?

最蠢的办法莫过于给每个 li 都添加一个 z-index,但是这种方法对于代码的维护和整洁度都极其不友好,因此我们有一种更简单的方法,我们可以给每个 li 标签添加一个 style 属性,里面的值也很简单,我们先来改造一下 html,代码如下:

<ul>
    <li style="--i:6;"><a href="#">Home</a></li>
    <li style="--i:5;"><a href="#">About</a></li>
    <li style="--i:4;"><a href="#">Services</a></li>
    <li style="--i:3;"><a href="#">Price</a></li>
    <li style="--i:2;"><a href="#">Our Team</a></li>
    <li style="--i:1;"><a href="#">Contact</a></li>
</ul>
复制代码

我们给每个 listyle 中都添加一个 --i:n 这样的属性,然后配合相关的样式就能自动的设置 li 的层级了,具体的样式修改如下:

li {
    position: relative;
    list-style: none;
    width: 200px;
    background: #3e3f46;
    padding: 15px;
    z-index: var(--i);
    transition: .5s;
}
复制代码

只需要在 li 的样式中添加一行 z-index: var(--i);,整个 li 的层级就会自动根据 style 中设置的 --i:n; 来进行改变,那么这个 var() 到底是个什么东西呢?我们可以看一下 MDN 的介绍:

var() 函数可以代替元素中任何属性中的值的任何部分。var() 函数不能作为属性名、选择器或者其他除了属性值之外的值。(这样做通常会产生无效的语法或者一个没有关联到变量的值。)

具体的详情可以点击这里进行查看。

简单来说,var() 可以代替我们设置的任何值,将我们设置的属性转换为我们需要的值。

现在 3D 的样子已经有了,但是鼠标移入 li 还不能动起来,我们还需要添加相关的 hover 效果,代码如下:

ul {
    position: relative;
    transform: skewY(-15deg);

    li {
        // ... other code
        
        &:hover {
            background: #33a3ee;
            transform: translateX(50px);

            &::before {
                background: #2982b9;
            }

            &::after {
                background: #1f5378;
            }
        }
        
        a {
            text-decoration: none;
            color: #ccc;
            display: block;
            text-transform: uppercase;
            letter-spacing: .05em;
            transition: .5s;

            &:hover {
                    color: #fff;
            }
        }

        &:last-child {
            &::after {
                box-shadow: -100px 100px 20px rgba(0, 0, 0, .25);
            }
        }
    }
}
复制代码

通过给 li 添加 hover 效果,改变 li 的位移,让整个 Menu 看起来像一个立体的 3D 效果,最终的代码实现可以在这里进行查看:

最后

CSS3 中的属性还有很多,通过对 CSS3 的学习和摸索,我们还能实现更多有意思的效果。看到这里,是否已经勾起你对 CSS3 学习的欲望呢?如果你也喜欢这些炫酷的效果,那就快来跟我一起学习吧!

最后,如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,谢谢大家

往期回顾

『 CSS实战』CSS3 实现一些好玩的效果(6)

『 CSS实战』CSS3 实现一些好玩的效果(5)

『 CSS实战』CSS3 实现一些好玩的效果(4)

『 CSS实战』CSS3 实现一些好玩的效果(3)

『 CSS实战』CSS3 实现一些好玩的效果(2)

『 CSS实战』CSS3 实现一些好玩的效果(1)

猜你喜欢

转载自juejin.im/post/7142876546489909285
今日推荐