【问题标题】:How does negative margin work in bootstrap carousel?负边距如何在引导轮播中起作用?
【发布时间】:2021-11-03 19:03:52
【问题描述】:

我在下面为 bootstrap 4 轮播创建了一个演示,其转换速度减慢到 30 秒,以便每个人都可以检查并正确查看 js 添加的动态 css:

.carousel-item {
  transition: transform 30s ease-in-out!important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://getbootstrap.com/docs/4.6/dist/js/bootstrap.bundle.js"></script>

<link href="https://getbootstrap.com/docs/4.6/dist/css/bootstrap.css" rel="stylesheet"/>
<div id="carouselExampleCaptions" class="carousel slide" data-ride="carousel">
  <ol class="carousel-indicators">
    <li data-target="#carouselExampleCaptions" data-slide-to="0" class="active"></li>
    <li data-target="#carouselExampleCaptions" data-slide-to="1"></li>
    <li data-target="#carouselExampleCaptions" data-slide-to="2"></li>
  </ol>
  <div class="carousel-inner">
    <div class="carousel-item active">
      <svg class="bd-placeholder-img bd-placeholder-img-lg d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder: First slide" preserveAspectRatio="xMidYMid slice" focusable="false"><title>Placeholder</title><rect width="100%" height="100%" fill="#777"></rect><text x="50%" y="50%" fill="#555" dy=".3em">First slide</text></svg>
    </div>
    <div class="carousel-item">
      <svg class="bd-placeholder-img bd-placeholder-img-lg d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder: First slide" preserveAspectRatio="xMidYMid slice" focusable="false"><title>Placeholder</title><rect width="100%" height="100%" fill="#777"></rect><text x="50%" y="50%" fill="#555" dy=".3em">Second slide</text></svg>
    </div>
    <div class="carousel-item">
      <svg class="bd-placeholder-img bd-placeholder-img-lg d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder: First slide" preserveAspectRatio="xMidYMid slice" focusable="false"><title>Placeholder</title><rect width="100%" height="100%" fill="#777"></rect><text x="50%" y="50%" fill="#555" dy=".3em">Third slide</text></svg>
    </div>
  </div>
  <a class="carousel-control-prev" href="#carouselExampleCaptions" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#carouselExampleCaptions" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

如您所见,所有幻灯片都给出了margin-right: -100%,然后活动幻灯片被转换为translateX(-100%)。我没有得到的是:

问题 1:margin-right -100% 应该为每张幻灯片创建负空间,使所有幻灯片彼此重叠,但实际上它们是并排的,为什么?

问题 2:如果只变换活动幻灯片,为什么右边的幻灯片也会与活动幻灯片一起变换?

对于问题 1,请考虑以下演示:https://jsfiddle.net/2j1ug8x4/ 在这里您可以看到 12 如何出现在同一个地方。它们被赋予float: left,就像引导程序一样。

【问题讨论】:

    标签: html css twitter-bootstrap margin css-transforms


    【解决方案1】:

    问题 1:

    margin-right 实际上将幻灯片放在彼此的顶部 - 是 CSS 转换解决了这个问题并使幻灯片彼此相邻。看看this example,其中的幻灯片被强制转换为display: block,你会看到第三张幻灯片,另外两张叠在下面。

    使用margin-right: -100% 的真正原因是确保幻灯片连续显示,而不是垂直堆叠。请参阅this example,其中幻灯片可见并且负边距已删除 - 您可以向下滚动以查看所有幻灯片垂直堆叠。

    问题 2:

    那么为什么右边的幻灯片也发生了变化?这个调试起来有点棘手,但我认为引导程序正在向右侧幻灯片添加两个类:carousel-item-nextcarousel-item-left

    如果您查看源 CSS,carousel-item-next 会向元素添加 transform: translateX(100%)。但该 CSS 规则仅在第二个类不存在时才包含转换:

    .carousel-item-next:not(.carousel-item-left),
      transform: translateX(100%);
    }
    
    

    所以我认为正在发生的是引导程序正在添加第一类 (carousel-item-next),然后在添加第二类 (carousel-item-left) 之前有一点延迟。

    该延迟意味着右侧幻灯片被短暂地转换为translateX(100%),然后立即删除。因为幻灯片元素上有一个过渡,这会导致右侧幻灯片从translateX(100%) 动画到translateX(0),或从右到左。

    这是一个无需引导即可复制此行为的简化示例 - 单击 Move 按钮以触发移动。请注意 setTimeout 用于人为模拟添加第一个和第二个 CSS 类之间的间隙:

    const button = document.getElementById('move');
    
    button.addEventListener('click', () => {
      const childElements = document.querySelectorAll('.child');
    
      childElements[0].classList.toggle('left');
      childElements[1].classList.toggle('right');
    
      setTimeout(() => {
        childElements[1].classList.toggle('skip');
      }, 0);
    });
    #move {
      position: absolute;
      top: 10px;
      left: 55%;
    }
    
    .container {
      position: relative;
      width: 50%;
    }
    
    .child {
      display: none;
      position: relative;
      width: 100%;
      height: 300px;
      border: 1px dotted blue;
      float: left;
      margin-right: -100%;
      transition: 1s transform ease;
    }
    
    .left {
      transform: translateX(-100%);
    }
    
    .right:not(.skip) {
      transform: translateX(100%);
    }
    
    .active,
    .right {
      display: block;
    }
    <div class="container">
      <div class="child active">1</div>
      <div class="child">2</div>
    </div>
    
    <button id="move">Move</button>

    【讨论】:

    • 谢谢伙计,我会坚持一段时间的赏金。我不知道transform: none 会等同于transform: translateX(0)
    猜你喜欢
    • 1970-01-01
    • 2021-03-21
    • 2021-01-04
    • 1970-01-01
    • 2015-02-12
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多