在 `display: flex` 父元素中固定子元素

huangapple go评论76阅读模式
英文:

Sticky child element in display: flex parent

问题

我想要我的.sidebar flex元素在我滚动时保持粘性定位,但position: sticky; top: 0;不起作用。

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
}

header {
  width: 100%;
  height: 100px;
  background-color: blue;
  opacity: 0.5;
  position: sticky;
  z-index: 100;
  top: 0;
}

.container {
  display: flex;
  gap: 2rem;
  position: relative;
}

.sidebar {
  position: sticky;
  top: 0;
}

.main {
  display: flex;
  gap: 2rem;
  flex-direction: column;
}

.main div {
  width: 300px;
  aspect-ratio: 1 / 1;
  background-color: red;
}
<div class="root">
  <header></header>
  <div class="container">
    <div class="sidebar">
      <p>Sidebar</p>
      <button>Upload image</button>
    </div>
    <div class="main">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>
  </div>
</div>
英文:

I want my .sidebar flex element to be sticky when I'm scrolling but position: sticky; top: 0; doesn't work.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
}

header {
  width: 100%;
  height: 100px;
  background-color: blue;
  opacity: 0.5;
  position: sticky;
  z-index: 100;
  top: 0;
}

.container {
  display: flex;
  gap: 2rem;
  position: relative;
}

.sidebar {
  position: sticky;
  top: 0;
}

.main {
  display: flex;
  gap: 2rem;
  flex-direction: column;
}

.main div {
  width: 300px;
  aspect-ratio: 1 / 1;
  background-color: red;
}

<!-- language: lang-html -->

&lt;div class=&quot;root&quot;&gt;
  &lt;header&gt;&lt;/header&gt;
  &lt;div class=&quot;container&quot;&gt;
    &lt;div class=&quot;sidebar&quot;&gt;
      &lt;p&gt;Sidebar&lt;/p&gt;
      &lt;button&gt;Upload image&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class=&quot;main&quot;&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

答案1

得分: 3

问题在于弹性元素的align-items的默认属性是normal(在这个上下文中的表现类似于stretch),因此.sidebar元素占据了所有可用的高度,无法实现"粘性效果"。
您可以通过将.container元素上的align-items属性更改为flex-start来实现"粘性效果",像这样:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
}

header {
  width: 100%;
  height: 100px;
  background-color: blue;
  opacity: 0.5;
  position: sticky;
  z-index: 100;
  top: 0;
}

.container {
  display: flex;
  align-items: flex-start; /* <- 添加此行 */
  gap: 2rem;
  position: relative;
}

.sidebar {
  position: sticky;
  top: 100px; /* 也注意我更改了.sidebar元素上的top属性,以便它不会隐藏在标头下方 */
}

.main {
  display: flex;
  gap: 2rem;
  flex-direction: column;
}

.main div {
  width: 300px;
  aspect-ratio: 1 / 1;
  background-color: red;
}

希望这有所帮助!

英文:

The issue is that the default property of align-items for flex elements is normal (acts like stretch in this context) therefore the .sidebar element takes all the available height and can't have the "sticky effect".
You can achieve the the sticky efect by changing the align-items property on the .container element to flex-start like this :

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
}

header {
  width: 100%;
  height: 100px;
  background-color: blue;
  opacity: 0.5;
  position: sticky;
  z-index: 100;
  top: 0;
}

.container {
  display: flex;
  align-items: flex-start; /* &lt;- ADD THIS */
  gap: 2rem;
  position: relative;
}

.sidebar {
  position: sticky;
  top: 100px;
}

.main {
  display: flex;
  gap: 2rem;
  flex-direction: column;
}

.main div {
  width: 300px;
  aspect-ratio: 1 / 1;
  background-color: red;
}

<!-- language: lang-html -->

&lt;div class=&quot;root&quot;&gt;
  &lt;header&gt;&lt;/header&gt;
  &lt;div class=&quot;container&quot;&gt;
    &lt;div class=&quot;sidebar&quot;&gt;
      &lt;p&gt;Sidebar&lt;/p&gt;
      &lt;button&gt;Upload image&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class=&quot;main&quot;&gt;
      &lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

(Note that I also changed the top property on the .sidebar element so it doesn't hide under the header)

huangapple
  • 本文由 发表于 2023年1月9日 18:27:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75055912.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定