0

I am creating a navbar that will horizontally scroll when it is larger than its parent container.

It has a bottom border on the navbar with a different border color for the active link. Using a negative margin to overlap them works fine but when adding overflow-x: auto; the active color disappears.

Here is a codepen to demonstrate: https://codepen.io/scottknight/pen/aboxYZY

(uncomment the overflow-x and the active border appears)

<div class="container">
    <div class="navbar">
        <a href="#" class="navlink">Link One</a>
        <a href="#" class="navlink active">Link Two</a>
        <a href="#" class="navlink">Link Three</a>
        <a href="#" class="navlink">Link Four</a>
        <a href="#" class="navlink">Link Five</a>
        <a href="#" class="navlink">Link Six</a>
        <a href="#" class="navlink">Link Seven</a>
        <a href="#" class="navlink">Link Eight</a>
        <a href="#" class="navlink">Link Nine</a>
        <a href="#" class="navlink">Link Ten</a>
    </div>
</div>
.container {
    width: 800px;
}

.navbar {
    display: flex;
    /*   overflow-x: auto; */
    border-bottom: solid;
    border-bottom-width: 5px;
    border-color: gray;
}

.navlink {
    padding: 20px;
    flex: none;
    margin-bottom: -5px;
}

.navlink.active {
    border-bottom: solid;
    border-bottom-width: 5px;
    border-color: red;
}
scottknight
  • 442
  • 4
  • 6
  • This might vary depending on browser and OS settings, but for me the active color is obscured by the horizontal scrollbar when overflow is auto. Removing the negative margin gives it room to render. – ray Sep 27 '19 at 03:47

1 Answers1

2

As described nicely in this answer to a different question, some combinations with overflow-x and overflow-y are not possible. When you set overflow-x to auto, overflow-y (visible by default) also becomes auto.

Looking at your code, I noticed that due to a negative margin, the navlink border is technically overflowing the containing navbar, so when overflow is visible, it bleeds out of the container and you can see it. When overflow is auto, however, you have to scroll down inside your element to see it.

instead of applying the border to your navbar, try applying it to each navlink and override it with active.

.navbar {
    display: flex;
    overflow-x: auto;
}

.navlink {
    padding: 20px;
    flex: none;
    border-bottom: 5px solid gray;
}

.navlink.active {
    border-color: red;
}
  • Ok that makes sense. Unfortunately though, using just the border on the navlink elements end up with individual borders and spaces between them instead of the single solid horizontal border effect. I guess you could do negative x margins on each navlink to connect them? – scottknight Sep 27 '19 at 04:18
  • I would advise against the use of negative margins, they're typically more trouble than they're worth. You may be able to accomplish this with an `::after` pseudo element and absolute positioning. That would remove it from the flow and prevent it from contributing to the link's height. –  Sep 27 '19 at 04:24
  • Actually I just tried your code on the codepen and it worked but it wasn't working on my main project. I'll keep tinkering, thanks! – scottknight Sep 27 '19 at 04:24
  • @scottknight Great! Glad I could help. A tip if it helps: spaces between inline and inline-block elements are caused by actual text space characters. You can avoid that by setting the parent's font-size to 0 and the child's font-size to whatever it needs to be. –  Sep 27 '19 at 04:32
  • I remember now why I was using the negative margin technique. I want a bottom border across the whole width of the parent container, and the active link to change the color of that border. [Example](https://bulma.io/documentation/components/navbar/) If there's only a bottom border on the link then it does not span the whole length if there's just a few links. Any ideas on how to achieve this and have still have horizontal scrolling ability if needed? – scottknight Sep 27 '19 at 17:16
  • I meant to link to [this example](https://bulma.io/documentation/components/tabs/) of a tabs menu in Bulma. – scottknight Sep 27 '19 at 19:29
  • [Try this](https://jsfiddle.net/ow1qg7hy/2/), the overflow is applied to the overall container instead. On the navbar, I used `display: inline-block`, because we can still get the same result as `display: flex` if `white-space: nowrap` is set on the container. Doing it this way also moves the border to the inside of the scrollbar, which looks nicer in certain browsers. –  Sep 27 '19 at 21:02