【问题标题】:position: sticky in Chrome vs Safari位置:粘在 Chrome 和 Safari 中
【发布时间】:2018-07-21 21:07:12
【问题描述】:

似乎position: sticky 在 Chrome 和 Safari 中的处理方式不同。我会尽力解释这个问题,但请参考下面的小提琴和 sn-ps 以查看发生了什么。

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

Fiddle #1 - 最高值为 0

在这个小提琴中,定位为sticky 的元素的最高值为0。这本质上应该意味着该元素始终为fixed。在 Safari 中,这显示了类似于“绝对定位到父元素顶部 0 像素”的元素。

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

我的意思是,我希望需要在粘性元素上添加一个top: 40px 值,以使其按我想要的方式运行,但似乎我这样做不是;很棒。

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

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

Fiddle #2 - 40px 的最高值

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

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

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


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


小提琴 #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);
}
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;
}
<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>

小提琴 #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);
}
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;
}
<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>

小提琴片段示例

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);
}
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;
}
<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>

【问题讨论】:

  • 我没有关注... sn-ps 的行为与我相同。第一个显示黄色标题,然后显示红色粘性,内容在 Firefox 和 Chrome 中移动。第二个显示黄色标题,然后是“移动”的灰色空间,然后是红色粘性,然后是也移动的内容,并且在两个浏览器中再次显示相同。而且我可以在两个浏览器的两个 sn-ps 上的输入上放置文本。现在我在一个 Windows 系统上,两个浏览器的最新标准版本
  • @FacundoCorradini 我没有在 Windows 机器上检查过,我可能应该在问题中注意到这一点。在 Mac 上,Safari/Firefox 和 Chrome 之间的行为有所不同。在 Safari 上的 Fiddle #1 中,一切都按预期工作,在 Safari 上的 Fiddle #2 中,sticky 元素(红色)位于距离顶部 20px 的位置。在 Chrome 上的 Fiddle #1 中,元素不是“粘着”的,但我可以在输入中输入文本,在 Chrome 上的 Fiddle #2 中,元素是粘着的,但为了输入文本,我需要点击向下 20px 的“空白”空间元素实际所在的位置
  • @FacundoCorradini 我在完成第一条评论之前不小心按了 Enter,我添加了一些解释
  • 我注意到 Chrome 和 Safari 之间的另一个区别: Chrome:user-images.githubusercontent.com/36432/… Safari:user-images.githubusercontent.com/36432/… 请注意,就我而言,Safari 是预期的行为。 Chrome 似乎无法计算粘性元素的高度。
  • @DanielBachhuber 有定义。两个浏览器之间有些古怪。我还没有找到解决跨浏览器问题的好方法。感谢您也提供一些图像

标签: css google-chrome position overflow


【解决方案1】:

在这种情况下,似乎不需要使用 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;
}

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

【讨论】:

  • 这不能回答问题。不管是否有解决方法,我问的是为什么浏览器之间的行为不同,而不是我如何实现这种效果
  • @justinw 很高兴您重写了上面的问题。你从我这里得到的答案可能反映了它最初的措辞方式。我现在更好地理解了你的问题。
  • @justinw 你有没有得到你的答案?看来您最终只是问为什么 safari 和 chrome 不同。
猜你喜欢
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2011-11-12
  • 1970-01-01
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
相关资源
最近更新 更多