我试图同时实现两种样式,一种包括粘性位置,另一种包括粘性元素的父级:
bottom
元素,当页面滚动到顶部,其余内容应在其后)此外,我尝试找到一种不使用 javascript、仅使用 css 的解决方案。 这里有一个代码片段可以清楚地说明这一点,有两列,一列用于解决问题的两个方面:
body {
margin: 0px 10px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
font-size: 10px;
}
.hero_bottom {
height: 50px;
background-color: lightblue;
margin: 10px 0px;
}
main {
height: 200vh;
background-image: linear-gradient(red, yellow);
}
section.left header {
display: grid;
grid-template-rows: 1fr 1fr auto;
gap: 10px;
height: 100vh;
border: 1px solid blue;
}
nav {
position: sticky;
top: 0px;
}
<section class="left">
<!-- HERO SECTION -->
<header>
<h1>
either I have the "bottom" element at the bottom of the screen view...
</h1>
<nav>
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
</nav>
<div class="hero_bottom">hero-bottom</div>
</header>
<!-- end HERO SECTION -->
<main>main content</main>
</section>
<section class="right">
<!-- HERO SECTION -->
<h1>
...or I have the navbar that stick through the entire website. But how to have both ?
</h1>
<nav>
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
</nav>
<div class="hero_bottom">hero-bottom</div>
<!-- end HERO SECTION -->
<main>main content</main>
</section>
如果导航栏是 body 的直接子元素(或者任何具有网站高度的元素,如我的示例中的
<section>
),则很容易使导航栏贯穿整个网站,并且很容易拥有
hero-bottom
如果页面顶部出现的所有内容(包括导航栏)都位于块级包装器内,则元素放置在英雄部分的底部。但是一个阻碍了另一个:底部元素需要块级包装器,而包装器会阻止导航栏粘在整个网站上。这是我的问题!
我不觉得有一个解决方案可以使导航栏粘在它的祖父母上(在这种情况下,因为我知道有时是可能的,例如,如果你可以使父级内联级别),所以也许最好找到一个解决方案是让
bottom
元素位于英雄部分的底部而不使用包装器?
<nav>
元素并将副本插入为正文的第一个子元素,但首先使其不可见。然后使用相交观察器来检测第一部分何时离开视口;当它出现时,使复制的
<nav>
可见。如果用户向上滚动并且第一部分重新进入视口,则使复制的 <nav>
不可见。这是第二个方面的解决方案,如何放置“英雄底部”,以及页面的其余部分,在英雄部分的底部,而不是在直接块级父级之外使用粘性的解决方案
技巧是在英雄部分使用一个不可见的浮动元素,给它一个100vh的高度,并清除页面的主要内容,使其跟随浮动元素。然后,我将“英雄底部”部分移动到主要内容内,并使其绝对位于顶部
一个例子会更好地解释它:
body {
margin: 0px 10px;
font-size: 10px;
}
body > h1, body > nav {
border: 1px solid blue;
}
.float {
float: left;
border: 2px solid green;
height: 100vh;
}
nav {
position: sticky;
top: 0px;
z-index: 1;
}
main {
position: relative;
height: 400vh;
background-image: linear-gradient(red, yellow);
clear: both;
}
main .hero_bottom {
height: 50px;
background-color: lightblue;
margin: 10px 0px;
position: absolute;
bottom: 100%;
left: 0px;
width: 100%;
}
<div class="float"></div>
<h1>
title
</h1>
<nav>
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
</nav>
<main>
<div class="hero_bottom">hero-bottom</div>
main-content
</main>
但是,由于英雄部分不能位于任何类型的块级元素(包括 Flexbox 和网格)内,因此自定义标题和导航栏的位置并不容易
可以使用
“clearfix”技巧
body {
margin: 0px 10px;
font-size: 10px;
}
header, nav {
border: 1px solid blue;
}
body * {
margin: 0px;
padding: 0px;
}
.float {
float: left;
border: 2px solid green;
}
.float_header {
height: 60vh;
}
.float_nav {
height: 40vh;
}
.clearfix::after {
content: "";
clear: both;
display: block;
}
.clear {
clear: both;
width: 0px;
height: 0px;
}
header {
display: block;
position: relative;
}
h1 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid orange;
}
nav {
position: sticky;
top: 0px;
z-index: 1;
text-align: center;
}
main {
position: relative;
height: 400vh;
background-image: linear-gradient(red, yellow);
clear: both;
}
main .hero_bottom {
height: 50px;
background-color: lightblue;
margin: 10px 0px;
position: absolute;
bottom: 100%;
left: 0px;
width: 100%;
}
<div class="float float_header"></div>
<header class="clearfix">
<h1>
title
</h1>
</header>
<div class="clear"></div>
<div class="float float_nav"></div>
<nav>
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
</nav>
<main>
<div class="hero_bottom">hero-bottom</div>
main-content
</main>
现在,我不确定是否会在生产中使用它