当粘性元素位于容器内时保持粘性定位行为(因为 React 必须渲染单个父元素)

Posted

技术标签:

【中文标题】当粘性元素位于容器内时保持粘性定位行为(因为 React 必须渲染单个父元素)【英文标题】:Keeping sticky positioning behaviour when sticky elements are inside a container (because of React having to render a single parent element) 【发布时间】:2017-10-07 17:08:09 【问题描述】:

我在一些主要内容上方有一个顶部。

顶部包含 5 个部分:“主标题”、3 个“类别”和“设置”。

鉴于用户向下滚动页面,“主标题”将sticky 保持在页面顶部,settings 保持在其下方sticky。虽然“类别”仍然可见,但它们逐渐折叠起来,再次使用position: sticky

这是一个 GIF 示例:

这是一个演示:

body 
  height: 300vh;


.header 
  height: 100px;


.header__main 
  background-color: springgreen;
  position: sticky;
  top: 0;

.header__category--top 
  background-color: grey;
  position: sticky;
  top: 100px;

.header__category--middle 
  background-color: darkgrey;
  position: sticky;
  top: 100px;

.header__category--bottom 
  background-color: lightgrey;
  position: sticky;
  top: 100px;

.header__settings 
  background-color: gold;
  position: sticky;
  top: 100px;


.header, .main 
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 40px;


.main 
  background-color: dodgerblue;
  height: 100%;
  flex-direction: column;
  justify-content: space-between;
<div class="header header__main">MAIN HEADER</div>
<div class="header header__category header__category--top">Category 1</div>
<div class="header header__category header__category--middle">Category 2</div>
<div class="header header__category header__category--bottom">Category 3</div>
<div class="header header__settings">Settings</div>
<div class="main">
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
</div>

但是,我的问题是,因为我将顶部内容呈现为 React 组件,所以它必须全部位于容器元素内。

这打破了我的粘性行为。

这是一个演示,代码相同,但顶部部分是容器元素:

body 
  height: 300vh;


.header 
  height: 100px;


.header__main 
  background-color: springgreen;
  position: sticky;
  top: 0;

.header__category--top 
  background-color: grey;
  position: sticky;
  top: 100px;

.header__category--middle 
  background-color: darkgrey;
  position: sticky;
  top: 100px;

.header__category--bottom 
  background-color: lightgrey;
  position: sticky;
  top: 100px;

.header__settings 
  background-color: gold;
  position: sticky;
  top: 100px;


.header, .main 
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 40px;


.main 
  background-color: dodgerblue;
  height: 100%;
  flex-direction: column;
  justify-content: space-between;
<div>
  <div class="header header__main">MAIN HEADER</div>
  <div class="header header__category header__category--top">Category 1</div>
  <div class="header header__category header__category--middle">Category 2</div>
  <div class="header header__category header__category--bottom">Category 3</div>
  <div class="header header__settings">Settings</div>
</div>
<div class="main">
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
  <span>Main Content</span>
</div>

我解决这个问题的最初感觉是: • 能够返回不在容器内的单独元素 • 以这样一种方式使用position: sticky,即我的顶部部分是否在容器元素内并不重要

我该如何解决这个问题?

Codepen 示例:

工作:https://codepen.io/alanbuchanan/pen/KmZrdr?editors=1100 坏了:https://codepen.io/alanbuchanan/pen/ybpQpd?editors=1100

【问题讨论】:

如果你使用的是 React 16.2,你可以使用 &lt;React.Fragment&gt;&lt;/React.Fragment&gt; 来返回多个元素,而不必将它们包装在一个实际的 html 元素中 【参考方案1】:

浏览器支持还不是很好,但是容器 div 上的display: contents 可以让它工作。 https://caniuse.com/#search=display

【讨论】:

以上是关于当粘性元素位于容器内时保持粘性定位行为(因为 React 必须渲染单个父元素)的主要内容,如果未能解决你的问题,请参考以下文章

使用“位置:粘性”将元素始终显示在屏幕上

定位位置:当前处于“卡住”状态的粘性元素

标题中的粘性导航栏[关闭]

类似于原生联系人应用程序的粘性搜索栏和部分标题行为

彻底理解粘性定位 - position: sticky

粘性标题 - 使用标签滚动