“Position: sticky”无法固定位置

9
我已经创建了一个侧边栏,现在想让它在用户向下滚动页面时固定在头部以下大约15像素的位置。一开始我使用JS实现,但是它会拖慢我的页面速度并导致页面出现卡顿。后来我发现使用position: sticky属性可以适用于大多数浏览器,但是我的侧边栏却无法在滚动时固定。
我在各个地方都看到建议要确保没有设置父元素的高度和溢出,而我的确没有这样设置。所以我正在努力找到问题的原因。我想知道是否还有其他因素可能会影响position:sticky属性,但我在网上没有找到相关信息。

.btn.sidebar {
  backface-visibility: hidden;
  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
  display: inline-block;
  position: relative;
  vertical-align: middle;
  width: 100%;
  background: rgba(255, 255, 255, .6);
  border-radius: 0;
  font-size: 22px;
  transition: ease .5s;
}

.btn.sidebar:hover {
  background: #97B2AC;
  color: #fff;
}

p.contact-text {
  color: #eee;
  text-align: center;
}

div.modal-form-sidebar {
  position: sticky;
  position: -webkit-sticky;
  top: 0px;
  font: 95% Arial, Helvetica, sans-serif;
  width: 320px;
  padding: 16px;
  background: #5d84a1;
}

.modal-form-sidebar h1 {
  background: rgba(255, 255, 255, .4);
  padding: 13px 0;
  font-size: 140%;
  font-weight: 300;
  text-align: center;
  color: #fff;
  margin: 0;
}

.modal-form-sidebar input[type="text"],
.modal-form-sidebar input[type="date"],
.modal-form-sidebar input[type="datetime"],
.modal-form-sidebar input[type="email"],
.modal-form-sidebar input[type="number"],
.modal-form-sidebar input[type="search"],
.modal-form-sidebar input[type="time"],
.modal-form-sidebar input[type="url"],
.modal-form-sidebar textarea,
.modal-form-sidebar select {
  -webkit-transition: all 0.30s ease-in-out;
  -moz-transition: all 0.30s ease-in-out;
  -ms-transition: all 0.30s ease-in-out;
  -o-transition: all 0.30s ease-in-out;
  outline: none;
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  width: 100%;
  background: #fff;
  margin-bottom: 4%;
  border: 1px solid #ccc;
  padding: 3%;
  color: #555;
  font: 95% Arial, Helvetica, sans-serif;
}

.modal-form-sidebar input[type="text"]:focus,
.modal-form-sidebar input[type="date"]:focus,
.modal-form-sidebar input[type="datetime"]:focus,
.modal-form-sidebar input[type="email"]:focus,
.modal-form-sidebar input[type="number"]:focus,
.modal-form-sidebar input[type="search"]:focus,
.modal-form-sidebar input[type="time"]:focus,
.modal-form-sidebar input[type="url"]:focus,
.modal-form-sidebar textarea:focus,
.modal-form-sidebar select:focus {
  box-shadow: 0 0 5px #5d84a1;
  padding: 3%;
  border: 1px solid #5d84a1;
}

.modal-form-sidebar input[type="submit"],
.modal-form-sidebar input[type="button"] {
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  width: 100%;
  padding: 3%;
  background: #5d84a1;
  border-bottom: 2px solid #374F60;
  border-top-style: none;
  border-right-style: none;
  border-left-style: none;
  color: #fff;
}

.modal-form-sidebar input[type="submit"]:hover,
.modal-form-sidebar input[type="button"]:hover {
  background: #7d9cb3;
}
<div class="modal-form-sidebar">

  <p class="contact-text">Text here</p>

  <h1>Email Us</h1>
  <form action="#" id="client_capture_sidebar" method="POST" onsubmit="submitted=true;" target="hidden_iframe" role="form">

    <input type="text" name="field1" placeholder="Your Name" />
    <input type="email" name="field2" placeholder="Email Address" />
    <input type="email" name="field2" placeholder="Phone Number" />
    <textarea name="field3" placeholder="Type your Message"></textarea>
    <input type="submit" value="Send" />

  </form>
  <br>
  <div class="white-txt">or</div>
  <br>
  <h1>Call Us</h1>
  <a class="btn sidebar" href="tel:1-222-222-2222"><i class="fa fa-phone" aria-hidden="true"></i>(222) 222-2222</a>

</div>


你试图定位的div是否被包含在父元素中? - Steve K
1
“对我来说似乎可以工作”(https://jsfiddle.net/59c7v9uf/)。但是,我没有看到你的标题。你期望发生什么事情?也许我误解了你的意图。 - showdev
是的,我正在使用col-md-4和sidebar wrapper进行包装,两者都没有任何高度或溢出属性。我只是希望一旦距离标题下方15像素,侧边栏就会固定。我已经将顶部属性更改为135像素以适应标题。它将不得不检查并查看其他容器是否引起了问题。我正在使用WordPress,因此所有内容都在侧边栏模板中。 - MAS89
它确实可以工作,但只有在被接下来的兄弟元素推上去之前才能正常工作。如果使用sticky属性是有用的,但它并不像人们期望的那样工作(使用误解或错误),但如果它被固定在top:0;(就像一个固定的元素一样),你将永远无法看到或者打电话给我们... 你试图做什么对我来说其实不清楚 :) - G-Cyrillus
如果您发布的代码没有展示您想要实现的内容,建议创建一个可工作示例来进行演示。 - showdev
显示剩余2条评论
3个回答

6
我猜测它无法工作的原因是由于您的父容器没有高度。 position:sticky 只会将元素固定到父容器的高度上。所以在您的情况下,父容器没有高度,因此一旦滚动到粘性元素,父容器中就没有距离可供粘性元素移动,因此看起来好像什么也没发生,因为当粘性元素到达顶部时,它的位置从静态变为固定,直到窗口到达父元素的底部。因此,当您的元素变为固定时,您的父容器高度为0。建议您将 position:sticky 添加到 .col-md-4 而不是侧边栏本身。
由于我不知道您的标记是什么样子,或者您使用的是哪个版本的 bootstrap,我假设您正在使用 bootstrap 3,并创建了一个示例标记,位于此处:Fiddle Demo
在演示中,我已经将position:sticky添加到了col-xs-4中,它可以工作。如果您将其从侧边栏中删除并添加到侧边栏本身,则无法正常工作。现在,如果您向下滚动到底部,您会发现当粘性元素触碰到下面的红色div时,它会停止。这是因为粘性元素的父元素高度已经结束。

因此,在您的情况下,当从div中删除粘性元素时,您的父div的高度为0,没有空间进行滚动。我建议您像我在演示中所做的那样,将position:sticky添加到col-md-4而不是侧边栏本身。


是的!现在它可以工作了。我之前一直无法重现我的原始问题。谢谢你。 - MAS89

1

它确实有效,但需要实现position:sticky。请参见https://caniuse.com/#search=sticky

添加一些内容以查看它是否粘在页面上,并且它是否按照您的预期行为工作,在下面的代码片段中,它会粘住直到底部将其推上去。这实际上是正确的行为。

.btn.sidebar {
  backface-visibility: hidden;
  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
  display: inline-block;
  position: relative;
  vertical-align: middle;
  width: 100%;
  background: rgba(255, 255, 255, .6);
  border-radius: 0;
  font-size: 22px;
  transition: ease .5s;
}

.btn.sidebar:hover {
  background: #97B2AC;
  color: #fff;
}

p.contact-text {
  color: #eee;
  text-align: center;
}

div.modal-form-sidebar {
  position: sticky;
  position: -webkit-sticky;
  top: 0px;
  font: 95% Arial, Helvetica, sans-serif;
  width: 320px;
  padding: 16px;
  background: #5d84a1;
}

.modal-form-sidebar h1 {
  background: rgba(255, 255, 255, .4);
  padding: 13px 0;
  font-size: 140%;
  font-weight: 300;
  text-align: center;
  color: #fff;
  margin: 0;
}

.modal-form-sidebar input[type="text"],
.modal-form-sidebar input[type="date"],
.modal-form-sidebar input[type="datetime"],
.modal-form-sidebar input[type="email"],
.modal-form-sidebar input[type="number"],
.modal-form-sidebar input[type="search"],
.modal-form-sidebar input[type="time"],
.modal-form-sidebar input[type="url"],
.modal-form-sidebar textarea,
.modal-form-sidebar select {
  -webkit-transition: all 0.30s ease-in-out;
  -moz-transition: all 0.30s ease-in-out;
  -ms-transition: all 0.30s ease-in-out;
  -o-transition: all 0.30s ease-in-out;
  outline: none;
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  width: 100%;
  background: #fff;
  margin-bottom: 4%;
  border: 1px solid #ccc;
  padding: 3%;
  color: #555;
  font: 95% Arial, Helvetica, sans-serif;
}

.modal-form-sidebar input[type="text"]:focus,
.modal-form-sidebar input[type="date"]:focus,
.modal-form-sidebar input[type="datetime"]:focus,
.modal-form-sidebar input[type="email"]:focus,
.modal-form-sidebar input[type="number"]:focus,
.modal-form-sidebar input[type="search"]:focus,
.modal-form-sidebar input[type="time"]:focus,
.modal-form-sidebar input[type="url"]:focus,
.modal-form-sidebar textarea:focus,
.modal-form-sidebar select:focus {
  box-shadow: 0 0 5px #5d84a1;
  padding: 3%;
  border: 1px solid #5d84a1;
}

.modal-form-sidebar input[type="submit"],
.modal-form-sidebar input[type="button"] {
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  width: 100%;
  padding: 3%;
  background: #5d84a1;
  border-bottom: 2px solid #374F60;
  border-top-style: none;
  border-right-style: none;
  border-left-style: none;
  color: #fff;
}

.modal-form-sidebar input[type="submit"]:hover,
.modal-form-sidebar input[type="button"]:hover {
  background: #7d9cb3;
}

.scrollme {overflow:hidden;height:200vh;background:pink;margin:1em;}
footer {
height:25vh;background:gray;margin:1em;}
<div class="modal-form-sidebar">

  <p class="contact-text">Text here</p>

  <h1>Email Us</h1>
  <form action="#" id="client_capture_sidebar" method="POST" onsubmit="submitted=true;" target="hidden_iframe" role="form">

    <input type="text" name="field1" placeholder="Your Name" />
    <input type="email" name="field2" placeholder="Email Address" />
    <input type="email" name="field2" placeholder="Phone Number" />
    <textarea name="field3" placeholder="Type your Message"></textarea>
    <input type="submit" value="Send" />

  </form>
  <br>
  <div class="white-txt">or</div>
  <br>
  <h1>Call Us</h1>
  <a class="btn sidebar" href="tel:1-222-222-2222"><i class="fa fa-phone" aria-hidden="true"></i>(222) 222-2222</a>

</div>
<div class="scrollme">tall div</div>
<footer>footer</footer>


这可能是由于我的页面或网站中的其他问题导致的。 - MAS89
@MAS89,好的,请尝试在您提供的代码片段中重现您的错误。请注意,这里的粘性元素是body的直接子元素;) - G-Cyrillus
downvoter,请解释一下你们的行为,回答或者检查一下position:sticky的工作原理,这个属性目前还没有被正式验证哦 ;) - G-Cyrillus
1
我建议,既然没有发现问题,那就没有什么可回答的了。在我看来,这很可能是负评的来源。 - showdev
@G-Cyr 我同意你的观点,并且我已经这样做了。我的评论在上面。我仍然很好奇可能出了什么问题,期待解决方案的出现。 - showdev
显示剩余3条评论

0

.btn.sidebar {
  backface-visibility: hidden;
  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
  display: inline-block;
  position: relative;
  vertical-align: middle;
  width: 100%;
  background: rgba(255, 255, 255, .6);
  border-radius: 0;
  font-size: 22px;
  transition: ease .5s;
}

.btn.sidebar:hover {
  background: #97B2AC;
  color: #fff;
}

p.contact-text {
  color: #eee;
  text-align: center;
}

div.modal-form-sidebar {
  position: sticky;
  position: -webkit-sticky;
  top: 0px;
  font: 95% Arial, Helvetica, sans-serif;
  width: 320px;
  padding: 16px;
  background: #5d84a1;
}

.modal-form-sidebar h1 {
  background: rgba(255, 255, 255, .4);
  padding: 13px 0;
  font-size: 140%;
  font-weight: 300;
  text-align: center;
  color: #fff;
  margin: 0;
}

.modal-form-sidebar input[type="text"],
.modal-form-sidebar input[type="date"],
.modal-form-sidebar input[type="datetime"],
.modal-form-sidebar input[type="email"],
.modal-form-sidebar input[type="number"],
.modal-form-sidebar input[type="search"],
.modal-form-sidebar input[type="time"],
.modal-form-sidebar input[type="url"],
.modal-form-sidebar textarea,
.modal-form-sidebar select {
  -webkit-transition: all 0.30s ease-in-out;
  -moz-transition: all 0.30s ease-in-out;
  -ms-transition: all 0.30s ease-in-out;
  -o-transition: all 0.30s ease-in-out;
  outline: none;
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  width: 100%;
  background: #fff;
  margin-bottom: 4%;
  border: 1px solid #ccc;
  padding: 3%;
  color: #555;
  font: 95% Arial, Helvetica, sans-serif;
}

.modal-form-sidebar input[type="text"]:focus,
.modal-form-sidebar input[type="date"]:focus,
.modal-form-sidebar input[type="datetime"]:focus,
.modal-form-sidebar input[type="email"]:focus,
.modal-form-sidebar input[type="number"]:focus,
.modal-form-sidebar input[type="search"]:focus,
.modal-form-sidebar input[type="time"]:focus,
.modal-form-sidebar input[type="url"]:focus,
.modal-form-sidebar textarea:focus,
.modal-form-sidebar select:focus {
  box-shadow: 0 0 5px #5d84a1;
  padding: 3%;
  border: 1px solid #5d84a1;
}

.modal-form-sidebar input[type="submit"],
.modal-form-sidebar input[type="button"] {
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  width: 100%;
  padding: 3%;
  background: #5d84a1;
  border-bottom: 2px solid #374F60;
  border-top-style: none;
  border-right-style: none;
  border-left-style: none;
  color: #fff;
}

.modal-form-sidebar input[type="submit"]:hover,
.modal-form-sidebar input[type="button"]:hover {
  background: #7d9cb3;
}

.scrollme {overflow:hidden;height:200vh;background:pink;margin:1em;}
footer {
height:25vh;background:gray;margin:1em;}
<div class="modal-form-sidebar">

  <p class="contact-text">Text here</p>

  <h1>Email Us</h1>
  <form action="#" id="client_capture_sidebar" method="POST" onsubmit="submitted=true;" target="hidden_iframe" role="form">

    <input type="text" name="field1" placeholder="Your Name" />
    <input type="email" name="field2" placeholder="Email Address" />
    <input type="email" name="field2" placeholder="Phone Number" />
    <textarea name="field3" placeholder="Type your Message"></textarea>
    <input type="submit" value="Send" />

  </form>
  <br>
  <div class="white-txt">or</div>
  <br>
  <h1>Call Us</h1>
  <a class="btn sidebar" href="tel:1-222-222-2222"><i class="fa fa-phone" aria-hidden="true"></i>(222) 222-2222</a>

</div>
<div class="scrollme">tall div</div>
<footer>footer</footer>


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