Fer
Fer

Reputation: 4196

Position: sticky behavior on a child element whilst the parent is not sticky?

I'm trying to achieve something that I'm not sure is supposed to be possible at all. Note that I'm looking for a CSS-only solution, I know I can solve this with JS, but I don't want to.

Consider the following pen: https://codepen.io/fchristant/pen/PjoKOq

The second navigation bar (dark) is sticky, as you scroll down, it will stick to the top of the viewport. The first navigation bar (light) is not sticky, it will simply scroll away.

However, that light navigation bar has a child element that is sticky. The idea is that the parent will scroll away, yet the child sticks, effectively blending with the second navigation bar (which is sticky).

This does not work, however. Hence my question: is it possible at all to have a sticky child element inside a parent that is not sticky?

HTML:

<div class="site_header">
  Site header
  <div class="site_header_child">
    sticky
  </div>
</div>
<div class="site_nav">
  Site header
</div>

CSS:

.site_header {
  display:flex;
  position:relative;
  width:100%;
  padding:10px;
  background:#eee;
}

.site_header_child {
  border:1px solid red;
  margin-left:auto;
  position:sticky;
  z-index:2;
  top:0;
  right:20px;
}

.site_nav {
  display: block;
  position:sticky;
  padding:10px;
  background:#333;
  color:#fff;
  position:sticky;
  z-index:1;
  top:0;
}

Upvotes: 19

Views: 19872

Answers (4)

Johnny
Johnny

Reputation: 9964

You can try adding display: contents; to the parent to make it act as the parent.

Upvotes: 10

Milos Tanaskovic
Milos Tanaskovic

Reputation: 55

try it: -> instead of top: 0 => top: 10px

.site_header_child {
  border:1px solid red;
  margin-left:auto;
  position:sticky;
  top:10;
  z-index:2;
  right:20px;
}

.site_nav {
  display: block;
  position:sticky;
  top:10;
  padding:10px;
  background:#333;
  color:#fff;
  position:sticky;
  z-index:1;
}

Upvotes: 0

jfudman
jfudman

Reputation: 94

The .site_header_child will only stick for the duration of its parent element's height.

You will need to give the .site_header_child element a fixed position if you want it to appear in the second bar.

Upvotes: 0

adrian.krzysztofek
adrian.krzysztofek

Reputation: 969

It is not possible to use sticky in such case. The same effect can be achieved by other means though. You can simply use "fixed" positioning and the sticky child will stay were it was.

.site_header_child {    
  position:fixed;
  top:10px;
  background:#eee;
}

Demo: https://codepen.io/anon/pen/VMWovv

Upvotes: 5

Related Questions