position:sticky:当元素脱离正常文档流时添加样式

30

让我们来举一个简单的例子:

<nav id="#mynav">MY NAVBAR</nav>

和基本样式:

#mynav {
    position : sticky;
}
我希望将以下样式信息应用于我的导航栏,仅当它脱离正常流时,以便在视觉上将其与主要内容分隔开来(在这种情况下使用阴影)。
box-shadow : 0px 10px 15px 0px rgba(0,0,0,0.75);

有没有类似于伪类或媒体查询的东西可以用来实现这个?例如:

#mynav:some-pseudo-class {
    box-shadow : 0px 10px 15px 0px rgba(0,0,0,0.75);
}

我知道有一些不错的插件可以实现这个功能,但它们中的所有插件似乎都无法在不绕过(相当新的)本地特性position: sticky的情况下实现它。相反,它们使用了一种老式的方法(滚动事件和position:fixed;top:0)。

那么,有没有可能使用position:sticky来完成此操作,而不使用减缓页面流畅度的scroll事件(我不反对JavaScript,但滚动事件太慢了)?


2
这会有所帮助:https://developers.google.com/web/updates/2017/09/sticky-headers - maganap
4个回答

4

我在这里找到了答案:https://css-tricks.com/how-to-detect-when-a-sticky-element-gets-pinned/

目前,您需要使用JavaScript来实现:

const el = document.querySelector(".myElement")
const observer = new IntersectionObserver( 
  ([e]) => e.target.classList.toggle("is-pinned", e.intersectionRatio < 1),
  { threshold: [1] }
);

observer.observe(el);
#parent { 
  height: 2000px; 
}

.myElement {
  position: sticky;
  top: -1px;
}

/* styles for when the header is in sticky mode */
.myElement.is-pinned {
  color: red;
} 
<div id="parent">
  
  <br />  <br />  <br />  <br />
  <div class="myElement">Hello!</div>
  
</div> 

top: -1px非常重要,因为IntersectionObserver会检测“您的元素在屏幕上可见的程度”。e.intersectionRatio对应于您的el的“可见性”的百分比。因此,如果您使用top: 0px,那么e.intersectionRatio将始终等于1,并且类is-pinned将永远不会被添加。


3

@Yako 如果你查看我提到的链接,那里有几个可供选择的JS代码。 - adamk22
1
关于浏览器支持的一点说明,因为顶部评论是来自2017年。现在,Sticky已经得到了浏览器的广泛支持。ie11是唯一不支持的浏览器,在撰写本文时仅占全球用户的1%。Sticky还可以优雅地降级,因此如果适合您的需求,最好选择css解决方案。请参见https://caniuse.com/?search=sticky - user2528534

0
使用Jquery:
HTML:
<div class="elementSticky"></div>

CSS(层叠样式表):
.elementSticky {
 width: 100%;
 height: 50px;
 position: sticky;
 top: 0;
 background-color: blue;
}

.elementStickyScroll {
 background-color: yellow;
}

jQuery:

$(document).ready(function () {
 $(window).on('scroll', function () {
 var currentPosition = $(window).scrollTop();
 var stickyElement = $('.elementSticky');
 
 
 if(currentPosition >= 1) {
    stickyElement.addClass('elementStickyScroll');
   }else {
    stickyElement.removeClass('elementStickyScroll');
   }
  });
 });

-1

你最好的解决方案可能是依靠JavaScript滚动事件。CSS对于捕捉点有(有限的)支持,但目前最接近滚动事件支持的就是这个了。

如果你对JS解决方案唯一的担忧是流畅性,我建议尝试将CSS过渡应用到#mynav上,这样当元素在滚动时被改变时,会有更平滑的视觉提示表明有东西正在改变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接