在偏移内联元素时定位粘滞
Position Sticky While Offsetting Inline Elements
我想做的是在对内联元素使用粘性位置的同时逐渐偏移内联元素,以便在用户滚动时将元素锁定到位,形成连贯的结构。例如,我有一个parent元素,div
,它包含一个p
child,它又包含多个span
children。
<div>
<p>
<span>w</span>
<span>o</span>
<span>r</span>
<span>d</span>
</p>
</div>
我所做的是使用 translateY
逐渐偏移每个字母(因为 sticky
显然使用 top
等来确定症结点),因此第一个字母是例如,偏移 100%
,第二个字母偏移 200%
,依此类推。这个想法是,当用户滚动时,每个字母都会锁定到位,最终在用户完成滚动时形成一个单词。
我知道问题是一旦我启用 sticky
,span
元素就会被定位到 relative
到 parent,这意味着元素是始终相对于 parent 进行偏移。我只是想不出一个纯粹的 CSS 解决方案。
我在写这篇文章时突然想到:也许诀窍是用top
来抵消,而bottom
来坚持?
Here是下面嵌入代码的codepen。
html,
body { width: 100%; height: 100%; margin: 0; }
div { border: solid red 2px; box-sizing: border-box; }
p { font-family: arial; font-size: 104px; border: solid blue 2px; box-sizing: border-box;
overflow-y: scroll;
margin: 0;
}
span { border: solid black 2px; box-sizing: border-box;
/* position: sticky; */
top: 0;
display: inline-block;
}
span:nth-child(1) { transform: translateY(100%); }
span:nth-child(2) { transform: translateY(200%); }
span:nth-child(3) { transform: translateY(300%); }
span:nth-child(4) { transform: translateY(400%); }
<div>
<p>
<span>w</span>
<span>o</span>
<span>r</span>
<span>d</span>
</p>
</div>
您可以在每个字母上使用负百分比来抵消转换:
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
div {
border: solid red 2px;
box-sizing: border-box;
}
p {
font-family: arial;
font-size: 104px;
border: solid blue 2px;
box-sizing: border-box;
overflow-y: scroll;
margin: 0;
}
span {
border: solid black 2px;
box-sizing: border-box;
position: sticky;
display: inline-block;
}
span:nth-child(1) {
transform: translateY(100%);
top: -100%;
}
span:nth-child(2) {
transform: translateY(200%);
top: -200%;
}
span:nth-child(3) {
transform: translateY(300%);
top: -300%;
}
span:nth-child(4) {
transform: translateY(400%);
top: -400%;
}
<div>
<p>
<span>w</span>
<span>o</span>
<span>r</span>
<span>d</span>
</p>
</div>
这是另一个更适合等宽字体和通用的解决方案(您不需要使用 nth-child
设置样式)
div {
border: solid red 2px;
box-sizing: border-box;
}
p {
font-family: monospace;
font-size:90px;
border: solid blue 2px;
box-sizing: border-box;
overflow-y: scroll;
margin: 0;
line-height: 1.2em;
height: 1.2em; /* equal to line-height */
}
span {
position: sticky;
top: 0;
display: block;
}
span:first-child {
margin-top: 1.2em; /* equal to line-height */
}
span:not(:first-child)::before {
content: "";
float: left;
width: 1ch;
height: 1.3em; /* a bit bigger than the line-height */
}
<div>
<p>
<span>H</span>
<span>e</span>
<span>l</span>
<span>l</span>
<span>o</span>
<span> </span>
<span>w</span>
<span>o</span>
<span>r</span>
<span>d</span>
</p>
</div>
我想做的是在对内联元素使用粘性位置的同时逐渐偏移内联元素,以便在用户滚动时将元素锁定到位,形成连贯的结构。例如,我有一个parent元素,div
,它包含一个p
child,它又包含多个span
children。
<div>
<p>
<span>w</span>
<span>o</span>
<span>r</span>
<span>d</span>
</p>
</div>
我所做的是使用 translateY
逐渐偏移每个字母(因为 sticky
显然使用 top
等来确定症结点),因此第一个字母是例如,偏移 100%
,第二个字母偏移 200%
,依此类推。这个想法是,当用户滚动时,每个字母都会锁定到位,最终在用户完成滚动时形成一个单词。
我知道问题是一旦我启用 sticky
,span
元素就会被定位到 relative
到 parent,这意味着元素是始终相对于 parent 进行偏移。我只是想不出一个纯粹的 CSS 解决方案。
我在写这篇文章时突然想到:也许诀窍是用top
来抵消,而bottom
来坚持?
Here是下面嵌入代码的codepen。
html,
body { width: 100%; height: 100%; margin: 0; }
div { border: solid red 2px; box-sizing: border-box; }
p { font-family: arial; font-size: 104px; border: solid blue 2px; box-sizing: border-box;
overflow-y: scroll;
margin: 0;
}
span { border: solid black 2px; box-sizing: border-box;
/* position: sticky; */
top: 0;
display: inline-block;
}
span:nth-child(1) { transform: translateY(100%); }
span:nth-child(2) { transform: translateY(200%); }
span:nth-child(3) { transform: translateY(300%); }
span:nth-child(4) { transform: translateY(400%); }
<div>
<p>
<span>w</span>
<span>o</span>
<span>r</span>
<span>d</span>
</p>
</div>
您可以在每个字母上使用负百分比来抵消转换:
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
div {
border: solid red 2px;
box-sizing: border-box;
}
p {
font-family: arial;
font-size: 104px;
border: solid blue 2px;
box-sizing: border-box;
overflow-y: scroll;
margin: 0;
}
span {
border: solid black 2px;
box-sizing: border-box;
position: sticky;
display: inline-block;
}
span:nth-child(1) {
transform: translateY(100%);
top: -100%;
}
span:nth-child(2) {
transform: translateY(200%);
top: -200%;
}
span:nth-child(3) {
transform: translateY(300%);
top: -300%;
}
span:nth-child(4) {
transform: translateY(400%);
top: -400%;
}
<div>
<p>
<span>w</span>
<span>o</span>
<span>r</span>
<span>d</span>
</p>
</div>
这是另一个更适合等宽字体和通用的解决方案(您不需要使用 nth-child
设置样式)
div {
border: solid red 2px;
box-sizing: border-box;
}
p {
font-family: monospace;
font-size:90px;
border: solid blue 2px;
box-sizing: border-box;
overflow-y: scroll;
margin: 0;
line-height: 1.2em;
height: 1.2em; /* equal to line-height */
}
span {
position: sticky;
top: 0;
display: block;
}
span:first-child {
margin-top: 1.2em; /* equal to line-height */
}
span:not(:first-child)::before {
content: "";
float: left;
width: 1ch;
height: 1.3em; /* a bit bigger than the line-height */
}
<div>
<p>
<span>H</span>
<span>e</span>
<span>l</span>
<span>l</span>
<span>o</span>
<span> </span>
<span>w</span>
<span>o</span>
<span>r</span>
<span>d</span>
</p>
</div>