位置:Chrome vs Safari 中的粘性

jus*_*inw 5 css position google-chrome overflow

似乎position: sticky在 Chrome 和 Safari 中被区别对待。我会尽力解释这个问题,但请参考下面的小提琴和片段,看看发生了什么。

我编辑了这篇文章,因为我认为我没有很好地解释我的第一个版本中发生的事情。

小提琴 #1 - 0 的最高值

在这个小提琴中,具有sticky定位的元素的最高值为0。这应该基本上意味着元素总是fixed。在 Safari 中,这显示元素类型类似于“绝对定位到顶部 0 像素处的父元素”。

它按我的意图运行,但对我来说没有多大意义。为什么top: 0 相对于母体时粘定位元素元件应该直到它们被固定的(固定元件是相对于窗口是相对的而不是元件)?

我要说的是,我希望需要top: 40px在粘性元素上放置一个值才能使其按我想要的方式运行,但似乎我没有;伟大的。

在同一个小提琴中,在 Chrome 中,它按照我的预期运行。一个top: 0值将元素“固定”在相对于浏览器窗口的 0 像素处,而不是父元素......

所以,如果我想拥有我想要的元素功能(基本上固定在父级中),我将top值设置为40px,除非这不起作用。

Fiddle #2 - 40px 的最高值

这个小提琴在 Chrome 中看起来视觉上是正确的但我无法与输入交互(除非我点击它下面的“空白”空间)。在 Safari 中,它运行正常,但看起来比父元素低 40 像素

很明显,这些浏览器的处理方式position: sticky不同。

哪种方式是正确的?有什么办法可以让它分别在每个浏览器中正常运行吗?


拜托,我不是在寻找如何实现效果的建议,而是为什么浏览器之间存在如此大的差异。下面的回答者指出,他们认为这可以通过一个position: fixed元素来完成,但在这种特定情况下,它不会以这种方式实现(固定元素,在具有溢出滚动的固定元素内,在隐藏溢出的主体中):见例子


小提琴 #1 片段

document.getElementById("toggle").addEventListener("click", function() {
    if (document.body.classList.contains("show-tracking")) {
        document.body.classList.remove("show-tracking");
    } else {
        document.body.classList.add("show-tracking");
        fix_safari_scroll("tracking");
    }
});

function fix_safari_scroll(id) {
    document.getElementById(id).style.overflowY = "hidden";
    setTimeout(function() {
        document.getElementById(id).style.overflowY = "scroll";
        document.getElementById(id).removeAttribute("style");
    }, 200);
}
Run Code Online (Sandbox Code Playgroud)
header {
    background: blue;
    height: 40px;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 10;
}

#ticker,
#tracking {
    padding-top: 40px;
}

#ticker {
    background: grey;
    position: relative;
    z-index: 1;
}

#tracking {
    background: lightblue;
    position: fixed;
    z-index: 5;
    top: 0;
    left: 0;
    width: 100%;
    transform: translate3d(100%, 0, 0);
    -webkit-transition: -webkit-transform 200ms ease-in;
    transition: -webkit-transform 200ms ease-in;
    transition: transform 200ms ease-in;
    transition: transform 200ms ease-in, -webkit-transform 200ms ease-in;
    max-height: 100vh;
}

.show-tracking {
    overflow: hidden;
}

.show-tracking #tracking {
    transform: translate3d(0, 0, 0);
    overflow-y: scroll;
}

.filter {
    background: yellow;
    position: -webkit-sticky;
    position: sticky;
    position: fixed;
    width: 100%;
    top: 40px;
    left: 0;
}
Run Code Online (Sandbox Code Playgroud)
<header>
    Header<button id="toggle">toggle</button>
</header>
<div id="ticker">
    <div style="padding: 400px 0;">ticker</div>
    ticcker
</div>
<div id="tracking">
    <div class="filter"><input type="text"></div>
    <div style="padding: 400px 0;">tracking</div>
    tracking
</div>
Run Code Online (Sandbox Code Playgroud)

小提琴 #2 片段

document.getElementById("toggle").addEventListener("click", function() {
    if (document.body.classList.contains("show-tracking")) {
        document.body.classList.remove("show-tracking");
    } else {
        document.body.classList.add("show-tracking");
        fix_safari_scroll("tracking");
    }
});

function fix_safari_scroll(id) {
    document.getElementById(id).style.overflowY = "hidden";
    setTimeout(function() {
        document.getElementById(id).style.overflowY = "scroll";
        document.getElementById(id).removeAttribute("style");
    }, 200);
}
Run Code Online (Sandbox Code Playgroud)
header {
    background: blue;
    height: 40px;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 10;
}

#ticker,
#tracking {
    padding-top: 40px;
}

#ticker {
    background: grey;
    position: relative;
    z-index: 1;
}

#tracking {
    background: lightblue;
    position: fixed;
    z-index: 5;
    top: 0;
    left: 0;
    width: 100%;
    transform: translate3d(100%, 0, 0);
    -webkit-transition: -webkit-transform 200ms ease-in;
    transition: -webkit-transform 200ms ease-in;
    transition: transform 200ms ease-in;
    transition: transform 200ms ease-in, -webkit-transform 200ms ease-in;
    max-height: 100vh;
}

.show-tracking {
    overflow: hidden;
}

.show-tracking #tracking {
    transform: translate3d(0, 0, 0);
    overflow-y: scroll;
}

.filter {
    background: yellow;
    position: -webkit-sticky;
    position: sticky;
    width: 100%;
    top: 40px;
    left: 0;
}
Run Code Online (Sandbox Code Playgroud)
<header>
    Header<button id="toggle">toggle</button>
</header>
<div id="ticker">
    <div style="padding: 400px 0;">ticker</div>
    ticcker
</div>
<div id="tracking">
    <div class="filter"><input type="text"></div>
    <div style="padding: 400px 0;">tracking</div>
    tracking
</div>
Run Code Online (Sandbox Code Playgroud)

示例小提琴片段

document.getElementById("toggle").addEventListener("click", function() {
    if (document.body.classList.contains("show-tracking")) {
        document.body.classList.remove("show-tracking");
    } else {
        document.body.classList.add("show-tracking");
        fix_safari_scroll("tracking");
    }
});

function fix_safari_scroll(id) {
    document.getElementById(id).style.overflowY = "hidden";
    setTimeout(function() {
        document.getElementById(id).style.overflowY = "scroll";
        document.getElementById(id).removeAttribute("style");
    }, 200);
}
Run Code Online (Sandbox Code Playgroud)
header {
    background: blue;
    height: 40px;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 10;
}

#ticker,
#tracking {
    padding-top: 40px;
}

#ticker {
    background: grey;
    position: relative;
    z-index: 1;
}

#tracking {
    background: lightblue;
    position: fixed;
    z-index: 5;
    top: 0;
    left: 0;
    width: 100%;
    transform: translate3d(100%, 0, 0);
    -webkit-transition: -webkit-transform 200ms ease-in;
    transition: -webkit-transform 200ms ease-in;
    transition: transform 200ms ease-in;
    transition: transform 200ms ease-in, -webkit-transform 200ms ease-in;
    max-height: 100vh;
}

.show-tracking {
    overflow: hidden;
}

.show-tracking #tracking {
    transform: translate3d(0, 0, 0);
    overflow-y: scroll;
}

.filter {
    background: yellow;
    position: fixed;
    width: 100%;
    top: 40px;
    left: 0;
}
Run Code Online (Sandbox Code Playgroud)
<header>
    Header<button id="toggle">toggle</button>
</header>
<div id="ticker">
    <div style="padding: 400px 0;">ticker</div>
    ticcker
</div>
<div id="tracking">
    <div class="filter"><input type="text"></div>
    <div style="padding: 400px 0;">tracking</div>
    tracking
</div>
Run Code Online (Sandbox Code Playgroud)

eag*_*283 -2

在这种情况下似乎不需要使用position:sticky。在您的示例中,红色输入栏永远不需要滚动。当元素位于页面顶部时,粘性有助于提供状态更改。这个元素从开始到结束都固定在某个位置,所以你可以只使用固定位置(甚至绝对),这里

    *,
*:before,
*:after  {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

body {
  margin: 0;
  font-size: 14px;
  line-height: 18px;
  position: relative;
}

header {
  height: 20px;
  background: yellow;
  width: 100%;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
}

.el {
  background: grey;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  min-height: 100vh;
  overflow-y: scroll;
  max-height: 100vh;
}

.content {
  background: lightblue;
}

.content span {
  display: block;
  padding: 250px 0;
}

.sticky {
  background: red;
  width: 100%;
  position: fixed;
  top: 20px;
}
Run Code Online (Sandbox Code Playgroud)

在这里查看 Apple 对position:sticky 的使用 => https://www.apple.com/do-more/

  • 这并不能回答问题。不管是否有解决办法,我问的是“为什么浏览器之间的行为不同”,而不是“我如何实现这种效果”。 (3认同)