jgthms / bulma

Modern CSS framework based on Flexbox
https://bulma.io
MIT License
49.25k stars 3.95k forks source link

Fixed-top navbar covers up content headings referred by anchors (i.e. TOC situation) #3668

Open digitigradeit opened 1 year ago

digitigradeit commented 1 year ago

This is about Bulma.

Overview of the problem

This is about the Bulma CSS framework I'm using Bulma version [0.9.4] My browser is: Safari I am pretty sure this issue is not a duplicate?

Description

Steps to Reproduce

A fairly typical setup, esp. in a blog, or on docs:

  1. Page with structured content - https://codepen.io/dogtoe/pen/ExOBwdv
  2. Content has headings with IDs, such as:
    <div class="content">
    <h1 id="hello-world">Hello World</h1> <!-- here -->
    <p>Lorem ipsum<sup><a>[1]</a></sup> dolor sit amet, consectetur adipiscing elit. Nulla accumsan, metus ultrices eleifend gravida, nulla nunc varius lectus, nec rutrum justo nibh eu lectus. Ut vulputate semper dui. Fusce erat odio, sollicitudin vel erat vel, interdum mattis neque. Sub<sub>script</sub> works as well!</p>
    <h2 id="second-level">Second level</h2> <!-- here -->
    <p>Curabitur accumsan turpis pharetra <strong>augue tincidunt</strong> blandit. Quisque condimentum maximus mi, sit amet commodo arcu rutrum id. Proin pretium urna vel cursus venenatis. Suspendisse potenti. Etiam mattis sem rhoncus lacus dapibus facilisis. Donec at dignissim dui. Ut et neque nisl.</p>
    <ul>
    <li>In fermentum leo eu lectus mollis, quis dictum mi aliquet.</li>
    <li>Morbi eu nulla lobortis, lobortis est in, fringilla felis.</li>
    <li>Aliquam nec felis in sapien venenatis viverra fermentum nec lectus.</li>
    <li>Ut non enim metus.</li>
    </ul>
    <h3 id="third-level">Third level</h3> <!-- here -->
  3. navbar with is-fixed-top, such as:
    <nav class="navbar is-dark is-fixed-top">
  4. "Sticky" sidebar widget with table of contents, such as:
    <aside class="box" id="toc">
    <p><a href="#hello-world">Hello World</a></p>
    <p><a href="#second-level">Second level</a></p>
    <p><a href="#third-level">Third level</a></p>
    </aside>
    #toc {
    position: sticky;
    top: 0;
    }

Expected behavior

The page would scroll to the corresponding heading, and the heading would appear just below the fixed navbar.

Actual behavior

Clicking on the links in the widget to scroll to the corresponding heading yields the following issues:

  1. The heading is navigated to, but the heading is now covered up by the fixed-top navbar
  2. The TOC sidebar widget is also partially cut off

Codepen demo: https://codepen.io/dogtoe/pen/ExOBwdv

digitigradeit commented 1 year ago

Should also point out that I have attempted a few fixes I found online, but the work-arounds are still somewhat unsatisfactory or dont work for all situations.

There's also a couple issues with Bulma that prevent some of of the workarounds from being used properly:

Workaround 1: Introducing a padding-top on all headings, then offsetting it by a negative margin-top, such as:

h1,h2,h3,h4,h5,h6 {
    padding-top: 1em;
    margin-top: -1em;
}

This has conflicts with headings that use the .title or .subtitle which adjusts the margins as indicated in content.sass because it also adjusts margin-top.

No bueno says the Codepen: https://codepen.io/dogtoe/pen/LYXKOxX

Workaround 2: Use scroll-margin-top: and/or use this in conjunction with Workaround 1

Naturally my guess was to set scroll-margin-top to $navbar-height and also use $navbar-height for the padding and margin, such as:

h1,h2,h3,h4,h5,h6 {
    scroll-margin-top: $navbar-height;
    padding-top: $navbar-height;
    margin-top: -$navbar-height;
}

Sorta works, says the Codepen: https://codepen.io/dogtoe/pen/rNQEYyp

But the challenge now is that the TOC is still cut off. My other challenge with Workaround 2 was that if you have a heading, and immediately under it you have some tabs, the tabs won't work!

Another issue is that a navbar with is-spaced complicates all solutions that I could find.

MehrshadHeisenberg commented 1 year ago

This has actually nothing to do with bulma and it's because of sticky and fixed themselves.

When an element's position is set to fixed, it will be taken out of the flow and this means that it is as if the that element is not even on the page and this will make your sidebar to go beneath the navbar.

As I explained what happents when you set the position property of an element to fixed, this is also the reason that the navbar covers your headings because it is completely out of the flow and the solution to this can be that you give some padding from the top to each section which helps to create some space so that the navbar doesn't cover the headings

But the only solution that comes to my mind for your second problem is that you keep the sidebar also in the navbar so that it also moves with the navbar because you have set the position to fixed

Tell me if you still have any problems about this

digitigradeit commented 1 year ago

This seems to be the best working solution which I could find that doesn't use margins or paddings that interfere with .title and .subtitle classes in Bulma.

https://getpublii.com/blog/one-line-css-solution-to-prevent-anchor-links-from-scrolling-behind-a-sticky-header.html

Here's what I am now doing on my blog.

html {
    scroll-padding-top: $navbar-height;
}

section {
    h1, h2, h3, h4, h5, h6 {
        scroll-margin-top: $navbar-height;
    }
}

I agree with you that it's not a bug with Bulma specifically, however, saying this has nothing to do with Bulma is where I respectfully disagree. It's something that could be an enhancement. It would not take much to add the above CSS to base/generic or elements/content with little to no impact.