纯html+css的轮播图问题

html:

<div class="slide">
    <div id="slide1" class="slide-content"></div>
    <div id="slide2" class="slide-content"></div>
    <div id="slide3" class="slide-content"></div>
    <div class="btns">
        <a href="#slide1" class="btn">1</a>
        <a href="#slide2" class="btn">2</a>
        <a href="#slide3" class="btn">3</a>
    </div>
</div>

css:

.slide{
    width: 200px;
    height: 80px;
    position: relative;
    margin: 0 auto;
    overflow: hidden;
    background-color: #f00;
}
.slide-content{
    width: 100%;
    height: 100%;
    position: absolute;
    right: -100%;
    top: 0;
    animation: slider-out 0.5s linear;
}
.slide-content:target{
    right: 0%;
    animation: slider-in 0.5s linear;
}
@keyframes slider-out{
    from{
        right: 0%;
    }
    to{
        right: -100%;
    }
}
@keyframes slider-in{
    from{
        right: 100%;
    }
    to{
        right: 0%;
    }
}
#slide1{
    background-color: #f00;
}
#slide2{
    background-color: #0f0;
}
#slide3{
    background-color: #00f;
}
.btns{
    position: absolute;
    left: 0;
    bottom: 0;
    z-index: 100;
}
.btn{
    float: left;
    margin-left: 10px;
    display: block;
    text-align: center;
    text-decoration: none;
    width: 20px;
    line-height: 20px;
    opacity: 0.6;
    color: #fff;
    background-color: #b7b7b7;
}

想达到的效果是点击按钮后,对应的slide块由左往右滑动出现。

调试发现:

  1. 单击按钮后,所点按钮对应的slide块的显示效果没有按预期地变化,但其right属性和预期是一样的,与显示效果不符?
  2. 按钮部分会很奇怪地跑到右边去,我的理解是按钮明明是position:absolute的,应该基于父元素div.slide定位,为什么会和它兄弟元素一起移动所以理解不能~
  3. slide-content元素的属性改为 right:100%后,完美运行,为什么?测试了一下animation配合@keyframes的动画,即使0%时的属性与元素本身属性不符,动画也会正常按流程运行,只是有个突变的效果,为什么此处行不通?

请各位指教!谢谢~!

阅读 4.5k
1 个回答

效果JSFiddle

加了一层 slide-wrapper 把底下的指示器和 slide 卡片隔离开了,让 slide-wrapper 来 overflow: hidden.

原因是卡片横向排放,导致溢出,虽然使用了 overflow: hidden, 但是改变不了 .slide 的 scrollWidth 还是 3 倍的卡片宽度的事实, position absolute 确实是不可能受同为 absolute 的兄弟元素的影响,但是由于 .slide 容器本身存在内容溢出,其实应该会出现滚动条的,只不过我们用 css 禁用了滚动条。a 链接的锚点定位元素,有一个功效是会把不在显示区域的内容通过拖动滚动条的方式 scroll 到可视区域。 尽管我们禁用了滚动条,但是这个滚动元素的功能还在,不信你去尝试取一下 .slide DOM 的 scrollLeft 值打印出来看看, 或者去掉 overflow:hidden 看看点击锚点滚动条是不是移动了。 所以,这就是底下的指示器跑到看不见的左边去了的原因。

============== 更新 ================

关于 right -100% 和 right 100%

right 是指元素右边距离定位父容器的右边的距离,例如, right:0 表示右边贴着定位父容器的右边,right: 50% 表示右边在定位父容器的正中间。

right: 100% 呢? 是指容器右边贴着定位父容器的左边(距离父容器的右边刚好是父容器宽度的 100%)。 负数呢?负数就是正数相反的方向啊。

比较有意思的现象是,absolute 的元素超出右边会拉伸定位父容器的 scrollWidth, 而往左边超出并不会。

看示例: absolute 元素超出定位父容器边界

实际你这个例子中,由于移走的卡片在进行动画时也会往右边超出 relative 父容器的宽度,但是由于新出现的卡片在左边,所以锚点定位不会动滚动条的位置(slide的offsetLeft), 而且动画结束后,卡片立马归位到左边不可见位置,因此能达到效果。

我给出的解决办法是加一层 div 包裹,能达到效果的原因是把锚点定位元素移动 offsetLeft 的特性转嫁到这层 div 身上,这样外层的 .slide 就相安无事,指示器自然就仍可见喽。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题