首页 > 解决方案 > 中间出现缝隙

问题描述

为了重现,为了能够看到差距,必须在基于 Chromium 的浏览器中的这些视口中查看代码。Firefox 中不会出现间隙。

您可以在 jsitor 中将其设置为不同的视口。

此外,通过增加和减少浏览器,您可以在提供的代码段中看到 Gap。我刚检查过。

在此处输入图像描述

单击Run,而不是更新到测试代码:

进一步调查发现:

间隙可见 https://jsitor.com/ublt2Y43V8

在此处输入图像描述

删除 YouTube 代码后,看不到任何差距。 https://jsitor.com/XT3U947ICr

有没有解决这个差距问题的解决方案?

https://i.imgur.com/zPivkcI.png

中间出现缝隙

在此处输入图像描述

从片段:

在此处输入图像描述

const cover = document.querySelector(".jacket");
(function manageCurtain() {
  "use strict";

  function hide(el) {
    el.classList.add("hide");
  }

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    hide(cover);
    const curtain = document.querySelector(".curtain-ratio-keeper");
    curtain.classList.add("slide");
  }

  const cover = document.querySelector(".jacket");
  cover.addEventListener("click", coverClickHandler);
})();

const videoPlayer = (function makeVideoPlayer() {
  "use strict";

  let player = null;

  const tag = document.createElement("script");
  tag.src = "https://www.youtube.com/iframe_api";
  const firstScriptTag = document.getElementsByTagName("script")[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  function onPlayerReady(event) {
    player = event.target;
    player.setVolume(100); // percent
  }
  let hasShuffled = false;

  function onPlayerStateChange(event) {
    const player = event.target;
    const shufflePlaylist = true;

    if (!hasShuffled) {
      player.setShuffle(shufflePlaylist);
      player.playVideoAt(0);
      hasShuffled = true;
    }
  }

  function addPlayer(video) {
    const playlist = "M7lc1UVf-VE";

    new YT.Player(video, {
      width: 640,
      height: 360,
      host: "https://www.youtube-nocookie.com",
      playerVars: {
        autoplay: 0,
        controls: 1,
        loop: 1,
        rel: 0,
        iv_load_policy: 3,
        cc_load_policy: 0,
        fs: 0,
        disablekb: 1,
        playlist
      },
      events: {
        onReady: onPlayerReady,
        onStateChange: onPlayerStateChange
      }
    });
  }

  return {
    addPlayer
  };
})();

function onYouTubeIframeAPIReady() {
  const wrapper = cover.parentElement;
  const frameContainer = wrapper.querySelector(".video");
  videoPlayer.addPlayer(frameContainer);
}

(function iife() {
  "use strict";

  function show(el) {
    el.classList.remove("hide");
  }

  function coverClickHandler(evt) {
    const wrapper = evt.currentTarget.parentElement;
    show(wrapper);
  }

  cover.addEventListener("click", coverClickHandler);
})();
html,
body {
  padding: 0;
  margin: 0;
}
body {
  height: 100vh;
  background: url(https://picsum.photos/id/1015/1500/1500) no-repeat;
  background-attachment: fixed;
  background-size: cover;
}
.outer {
  display: flex;
  min-height: 100vh;
  padding:8px 6px;
  box-sizing:border-box;
}
.inner{ 
  min-width: 40%;
  max-width: 640px;
  margin: auto;
}
.curtain-ratio-keeper {
  position: relative;
  padding-top: 56.25%;
  border-radius: 25px;
  height:0;
  overflow: hidden;
  border: 3px solid red;
}

.video-frame {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.jacket {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  margin: auto;
  cursor: pointer;
  z-index: 3;
}

.play {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  margin: auto;
  min-width: 70px;
  min-height: 70px;
  max-width: 30%;
  max-height: 30%;
  fill: red;
  filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.7));
  cursor: pointer;
}

.wrap iframe {
  position: absolute;
  top: -3px;
  left: -3px;
  width: calc(100% + 6px);
  height: calc(100% + 6px);
}

.wrap,
.jacket {
  position: absolute;
  top: -3px;
  left: -3px;
  width: calc(100% + 6px);
  height: calc(100% + 6px);
}
.hide {
  display: none;
}

.slide-wrap:before,
.slide-wrap:after {
  content: "";
  position: absolute;
  top: 0;
  width: 50%;
  height: 100%;
  transition: transform 5s linear;
  display: flex;
  align-items: center;
  background: url(https://picsum.photos/id/1015/1500/1500) no-repeat;
  background-attachment: fixed;
  background-size: cover;
  z-index: 2;
}
.slide-wrap:before {
  left: 0;
  justify-content: flex-end;
}
.slide-wrap:after {
  right: 0;
  justify-content: flex-start;
}
.slide .slide-wrap::before {
  transform: translateX(-100%);
}
.slide .slide-wrap::after {
  transform: translateX(100%);
}
<div class="outer">
    <div class="inner">
        <div class="curtain-ratio-keeper">
            <div class="video-wrapper">
                <div class="video-ratio-keeper slide-wrap">
                    <div class="wrap">
                        <div class="video video-frame"></div>
                    </div>
                </div>
            </div>
            <div class="jacket" title="Play">
                <svg class="play" width="100%" height="100%" viewBox="0 0 64 64">
                    <path d="M25.6,46.4L44.8,32L25.6,17.6V46.4z M32,0C14.3,0,0,14.3,0,32s14.3,32,32,32s32-14.3,32-32S49.7,0,32,0z
              M32,57.6C17.9,57.6,6.4,46.1,6.4,32S17.9,6.4,32,6.4S57.6,17.9,57.6,32S46.1,57.6,32,57.6z" />
                </svg>
            </div>
        </div>
    </div>
</div>

标签: javascriptcssbackground-imagerounding-error

解决方案


当容器的宽度为非整数(例如,241.118px)时,这是浮点舍入错误。:beforeand元素将:after填充 50% 的容器,但浮点数学并不完美,可能会错误地舍入结果,因此它可能不是 120.559px,而是类似于 120.554px。这会导致两个伪元素的宽度没有完全填满容器,从而导致您看到的间隙。

一个简单的,尽管是“创可贴”的修复方法是将两个伪元素的宽度增加到大于 50%,这样即使存在舍入误差,整个容器也会被覆盖。我最初建议51%,但由于差距总是小于1px,所以你使用也是正确的calc(50% + 1px)

.slide-wrap:before,
.slide-wrap:after {

  width: calc(50% + 1px);

}

推荐阅读