cal*_*lum 83 css css-position css-selectors css3
position:sticky现在可以在某些移动浏览器上运行,因此您可以使菜单栏与页面一起滚动,但只要用户滚过它就会粘到视口顶部.
但是,如果您想要在粘贴的菜单栏中稍微重新设置,只要它现在"粘住",该怎么办?例如,您可能希望条形图在滚动页面时具有圆角,但是一旦它粘贴到视口顶部,您就想要摆脱顶部圆角,并在下面添加一点阴影它.
是否存在任何类型的伪选择器(例如::stuck)来定位具有position: sticky 并且当前正在粘附的元素?或者浏览器供应商在管道中有这样的东西吗?如果没有,我会在哪里申请?
NB.javascript解决方案对此不利,因为在移动设备上,scroll当用户松开手指时,通常只会收到一个事件,因此JS无法知道滚动阈值通过的确切时刻.
Bol*_*ock 83
目前没有针对当前"卡住"的元素提出选择器.所述Postioned布局模块,其中position: sticky被定义不任一提及任何此类选择器.
CSS的功能请求可以发布到www样式的邮件列表中.我相信:stuck伪类比::stuck伪元素更有意义,因为你希望在它们处于该状态时将元素本身作为目标.事实上,前一段时间:stuck讨论过一个伪类; 发现的主要复杂因素是,任何基于渲染或计算样式尝试匹配的任何提议的选择器都会受到困扰:循环依赖.
在:stuck伪类的情况下,使用以下CSS会出现最简单的圆形情况:
:stuck { position: static; /* Or anything other than sticky/fixed */ }
:not(:stuck) { position: sticky; /* Or fixed */ }
Run Code Online (Sandbox Code Playgroud)
并且可能存在更多难以解决的边缘情况.
虽然人们普遍认为,根据某些布局状态选择匹配的选择器会很好,但遗憾的是存在一些主要的限制因素,这些限制使这些非常重要.我不会很快屏住这个问题的纯CSS解决方案.
我想要一个纯 CSS 解决方案,允许为“卡住”元素设置样式,就好像存在::stuck伪选择器一样(唉,2021 年还没有)。
我创建了一个纯 CSS hack,无需 JS 即可实现效果并满足我的需求。它的工作原理是拥有元素的两个副本,一个是sticky,另一个不是(unstuck一个),后一个覆盖sticky元素,直到您滚动它为止。
演示:https : //codepen.io/TomAnthony/pen/qBqgErK
替代演示:https : //codepen.io/TomAnthony/pen/mdOvJYw(这个版本更符合我的要求,我希望粘性项目仅在“卡住”时出现 - 这也意味着没有重复的内容。)
HTML:
<div class="sticky">
<div class="unstuck">
<div>
Box header. Italic when 'stuck'.
</div>
</div>
<div class="stuck">
<div>
Box header. Italic when 'stuck'.
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
CSS:
.sticky {
height: 20px;
display: inline;
background-color: pink;
}
.stuck {
position: -webkit-sticky;
position: sticky;
top: 0;
height: 20px;
font-style: italic;
}
.unstuck {
height: 0;
overflow-y: visible;
position: relative;
z-index: 1;
}
.unstuck > div {
position: absolute;
width: 100%;
height: 20px;
background-color: inherit;
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下IntersectionObserver,如果情况允许在其根容器之外粘贴一个或两个像素,而不是对其进行适当冲洗,则简单的方法就可以解决问题。这样,当它正好位于边缘之外时,观察者就会开火,我们可以出发并奔跑了。
const observer = new IntersectionObserver(
([e]) => e.target.toggleAttribute('stuck', e.intersectionRatio < 1),
{threshold: [1]}
);
observer.observe(document.querySelector('nav'));
Run Code Online (Sandbox Code Playgroud)
使用将该元素刚从其容器中伸出top: -2px,然后通过stuck属性进行定位...
nav {
background: magenta;
height: 80px;
position: sticky;
top: -2px;
}
nav[stuck] {
box-shadow: 0 0 16px black;
}
Run Code Online (Sandbox Code Playgroud)
此处的示例:https : //codepen.io/anon/pen/vqyQEK
Google Developers 博客上的某个人声称已经找到了一个基于 JavaScript 的执行性解决方案,其中包含IntersectionObserver。
相关代码位在这里:
/**
* Sets up an intersection observer to notify when elements with the class
* `.sticky_sentinel--top` become visible/invisible at the top of the container.
* @param {!Element} container
*/
function observeHeaders(container) {
const observer = new IntersectionObserver((records, observer) => {
for (const record of records) {
const targetInfo = record.boundingClientRect;
const stickyTarget = record.target.parentElement.querySelector('.sticky');
const rootBoundsInfo = record.rootBounds;
// Started sticking.
if (targetInfo.bottom < rootBoundsInfo.top) {
fireEvent(true, stickyTarget);
}
// Stopped sticking.
if (targetInfo.bottom >= rootBoundsInfo.top &&
targetInfo.bottom < rootBoundsInfo.bottom) {
fireEvent(false, stickyTarget);
}
}
}, {threshold: [0], root: container});
// Add the top sentinels to each section and attach an observer.
const sentinels = addSentinels(container, 'sticky_sentinel--top');
sentinels.forEach(el => observer.observe(el));
}
Run Code Online (Sandbox Code Playgroud)
我自己没有复制它,但也许它可以帮助那些在这个问题上绊倒的人。