我试图仅使用CSS实现纸张折叠效果。我在视觉上(几乎)取得了预期的效果,但存在一些重大缺陷;即:
我需要帮助:
我注意到每一对已经连接并且*链接*如果我移除边距并观察它们折叠而不移动,这要归功于变换原点。也许有一种方法可以实现这一点,以链接元素上方和下方的元素。您可以删除负边距并运行它以了解我的意思。
$('#menu-main-toggle').on('click', function() {
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
});

/* Aesthetic Styling Begin */
ul{margin:0;padding:0;list-style-type:none}#menu-main,#menu-main-toggle{width:75%;margin:auto}#menu-main-toggle,.menu-item{background:#e74c3c;border:none}#menu-main .menu-link,#menu-main-toggle{outline:0;display:block;height:50px;padding:12px;color:#fff;border-top:1px dashed #bf2718;box-sizing:border-box;text-decoration:none;text-align:center}
/* Aesthetic Styling End */
#nav-primary .dropdown-toggle.active + .toggleable > .menu-item {
margin: 0;
transform: perspective(320px) rotateX(0deg);
box-shadow: inset 0 0 20px 0 transparent;
}
#menu-main .menu-item {
transition: transform .75s ease-in-out, margin .75s ease-in-out, box-shadow .75s ease-in-out;
}
#menu-main .menu-item.odd {
margin-bottom: -100px;
transform: perspective(320px) rotateX(-90deg);
transform-origin: top;
box-shadow: inset 0 -50px 25px 0 rgba(0, 0, 0, .5);
}
#menu-main .menu-item.even {
margin-top: -100px;
transform: perspective(320px) rotateX(90deg);
transform-origin: bottom;
box-shadow: inset 0 50px 25px 0 rgba(0, 0, 0, .5);
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.min.css" rel="stylesheet"/>
<nav id="nav-primary" class="text-center">
<button id="menu-main-toggle" class="dropdown-toggle">Menu</button>
<ul id="menu-main" class="toggleable">
<li class="menu-item odd">
<a class="menu-link" href="#">Lorem</a>
</li>
<li class="menu-item even">
<a class="menu-link" href="#">Ipsum</a>
</li>
<li class="menu-item odd">
<a class="menu-link" href="#">Situs Dolor</a>
</li>
<li class="menu-item even">
<a class="menu-link" href="#">Consectetur</a>
</li>
<li class="menu-item odd">
<a class="menu-link" href="#">Duis</a>
</li>
<li class="menu-item even">
<a class="menu-link" href="#">Vivamus</a>
</li>
</ul>
</nav>
&#13;
答案 0 :(得分:2)
这是一个可行的解决方案。
我只在Chrome中测试过它,因为它使用的变量需要现代浏览器。但是你可以很容易地适应它而无需变量。
使用的变换是硬。我稍后会尝试解释它们。
将鼠标悬停在列表上以折叠
.test {
--height: 150px;
--time: 5s;
--angle: 0deg;
--angle2: -0deg;
--bkg1: 0%;
--bkg2: 100%;
}
.test:hover {
--angle: 90deg;
--angle2: -90deg;
--bkg1: 100%;
--bkg2: 0%;
}
ul {
margin-top: 10px;
width: 70%;
position: relative;
list-style: none;
}
li {
position: absolute;
width: 100%;
transition: transform var(--time);
bottom: 0px;
transform: rotateX(var(--angle)) translateY(100%) rotateX(var(--angle2));
}
li:nth-child(1) {
height: 0px;
}
li:nth-child(2), li:nth-child(3) {
height: calc(2 * var(--height));
}
li:nth-child(4), li:nth-child(5) {
height: calc(4 * var(--height));
}
li:nth-child(6), li:nth-child(7) {
height: calc(6 * var(--height));
}
a {
position: absolute;
height: var(--height);
width: 100%;
display: block;
font-size: 40px;
background-size: 100% 300%;
background-repeat: no-repeat;
transition: transform var(--time), background-position var(--time);
}
li:nth-child(odd) a {
top: 100%;
transform-origin: top;
transform: rotateX(var(--angle)) translateY(100%) perspective(400px) translateY(-100%) rotateX(var(--angle2)) rotateX(var(--angle2));
background-image: linear-gradient(to top, rgba(0,0,0,0.6) 30%, transparent 66%);
background-position: center var(--bkg1);
}
li:nth-child(even) a {
bottom: 0px;
transform-origin: bottom;
transform: rotateX(var(--angle2)) translateY(-100%) perspective(400px) translateY(100%) rotateX(var(--angle)) rotateX(var(--angle));
background-image: linear-gradient(rgba(0,0,0,0.6) 30%, transparent 66%);
background-position: center var(--bkg2);
}
li:nth-child(1) a {
background-color: rgba(200,0,0,0.3);
}
li:nth-child(2) a {
background-color: rgba(0,200,0,0.3);
}
li:nth-child(3) a {
background-color: rgba(0,0,200,0.3);
}
li:nth-child(4) a {
background-color: rgba(200,200,0,0.3);
}
li:nth-child(5) a {
background-color: rgba(200,0,200,0.3);
}
li:nth-child(6) a {
background-color: rgba(0,200,200,0.3);
}
<ul class="test">
<li>
<a>-1-</a>
</li>
<li>
<a>-2-</a>
</li>
<li>
<a>-3-</a>
</li>
<li>
<a>-4-</a>
</li>
<li>
<a>-5-</a>
</li>
<li>
<a>-6-</a>
</li>
</ul>
让我们试着解释变换。
为了让事情变得更容易,我使用2个元素来实现变换:基本li将处理Y运动,a将处理自己的旋转。
对于给定元素,Y平移量由其顶部元素的旋转给出。这可以通过单个元素再现,具有相同高度的这些元素的总和,以相同的速度旋转。
在第一时刻,li被置于Y = 0.然后它被旋转,然后平移与其高度相同的量,并且反向旋转,因为我们只希望该元素达到Y位置而不是旋转。
对于a元素,这更难:-(。我们希望它旋转,并以透视方式进行。但我无法调整以下元素到这种情况,所以我需要它是一个< em>假的透视。这个透视会缩小元素的宽度,但不会缩小高度。在旋转的情况下,有2个点保持不变:旋转轴和透视点。所以我需要先将元素移动到它的旋转边框,在这里应用透视图,返回到原来的位置,然后应用最终旋转。
最后2次轮换解决了CSS变量的问题。我需要
rotateX(calc( 2 * var(--angle)))
但这似乎对Chrome来说太过分了。