I found myself entangled in CSS. I needed app-header
to stick to the top at all times. I also needed template-header
to be right beneath app-header
at all times. Lastly, embedded-content
should begin immediately after template-header
and should not be sticky. Here’s how the page organisation might look like:
<div class="app">
<div class="app-header">
<!-- Content -->
</div>
<div class="app-content">
<div class="template-container">
<div class="template-header">
<!-- Content -->
</div>
<div class="embedded-content">
<!-- Content -->
</div>
</div>
</div>
</div>
The simplest approach is to place app-header
and template-header
inside a single div
. Then, we will only need to stick one element at the top. However, app-header
and app-content
are independent of each other. They are of different scopes in React. Here’s my initial approach:
.app-header {
position: sticky;
top: 0;
width: 100vw;
z-index: 1;
}
.app-content {
margin-top: 70px;
}
.template-header {
padding: 2px;
position: fixed; /* Changing to position: sticky; did not work for me. */
top: 56px;
z-index: 1;
}
Having margin-top: 70px
and top: 56px
was disturbing. Depending on the viewport, the height of app-header
changes due to overflow. A quick fix for top: 56px
is to use media queries. But, I’d want to defer that. The overflow problem may no longer apply when the content in app-header
gets condensed into something like a hamburger button.
As for margin-top: 70px
, it becomes a problem when there are pages without template-container
. They look like:
<div class="app">
<div class="app-header">
<!-- Content -->
</div>
<div class="app-content">
<!-- Content -->
</div>
</div>
This poses a problem because margin-top: 70px
means there will be a space between app-header
and app-content
. In a world where CSS can do whatever we want, we can have app-content
conditionally choose a style based on the presence of template-container
. But for now, this ideal approach isn’t possible.
A quick remedy for margin-top: 70px
is to refactor pages without template-container
to now have a header of a similar height. Sounds quick but I expect this to be rather tedious.
Update: Changing the position
value for template-header
to sticky
didn’t work at first because of the superfluous margin-top: 70px
. Here’s the simplified solution:
.app-header {
position: sticky;
top: 0;
width: 100vw;
z-index: 1;
}
.template-header {
padding: 2px;
position: sticky;
top: 56px;
z-index: 1;
}
I will sign off this post with a caniuse lookup.