31

(First question on Stack Overflow. Hope I'm doing it right.)

I'm trying to create a floating menu that inherits its width from its content (since I don't know the width in advance, i.e. loaded from a URL). I can do this by having the menu div absolutely positioned without setting a width or height.

The problem occurs when the content is tall enough to require scrolling. I set "overflow: auto;" so that it can be scrolled vertically, but the new scrollbar doesn't make the div wider. Instead, the div stays the same width, and the scrollbar juts into its previously nicely sized content, forcing the content to wrap.

Example: http://jsfiddle.net/w7Mm8/

In the example: in Firefox, "five" gets wrapped onto the next line, but in Chrome (for Mac at least), its all shown on one line.

Any elegant way to do this without explicitly setting the width of the menu to include the width of the scrollbar?

THANKS!

Dave L.
  • 9,595
  • 7
  • 43
  • 69
Tristan
  • 411
  • 1
  • 4
  • 6
  • 1
    As far as I know, there's no way to do this without using JavaScript. I'd love to hear about it if I'm wrong though! – thirtydot Dec 07 '11 at 02:37
  • The ugly hack-fix is that when you know the content is too tall and scrollbars will be visible, you can explicitly set the width of the containing div to its current inner width + the width of your browser's scroll bars (i.e. with code like this: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php). In Chrome for Mac, the scroll-bar width is 0, so it doesn't add any extra space. In Firefox for Mac, the scroll-bar width is 15. – Tristan Dec 07 '11 at 02:51
  • Yeah, that's the kind of JavaScript I was talking about. – thirtydot Dec 07 '11 at 02:54
  • 1
    One thing that is interesting is that it does not matter how much right padding you put on the div, it still will wrap in FF if a scroll bar shows up. See http://jsfiddle.net/w7Mm8/30/. – ScottS Dec 07 '11 at 03:58
  • @Tristan the code in the link you provided to calculate scroll width has a bug in it. You need to add an extra `` to the html that it dynamically creates. – speedplane Feb 04 '15 at 12:05

2 Answers2

4

You have a few options.

Use white-space:nowrap; and some padding.

Use overflow: scroll;, which adds an extra scrollbar on the bottom, but fixes the wrapping problem in Firefox.

Use overflow-y:scroll which is CSS3 and is supported by only modern browsers.

bookcasey
  • 39,223
  • 13
  • 77
  • 94
  • This is the best solution so far, though technically none of them solves the problem perfectly. The `white-space:nowrap;` padding is extraneous when the scrollbar isn't visible. And the `overflow[-y]:scroll;` options would show a scrollbar even if it is not necessary. Wrapping any of the three cases in a little Javascript (for when the content is too tall) solves this, and is definitely better than my solution of forcing a new width, so I'll use this for the time being. Thanks! – Tristan Dec 07 '11 at 03:27
  • 1
    (So strange that `overflow:scroll;` adds the scrollbar width to the content, whereas `overflow:auto;` doesn't, even when the scrollbar is visible in both cases.) – Tristan Dec 07 '11 at 03:30
  • 1
    Also, the `white-space:nowrap` will force a horizontal scroll on long content: http://jsfiddle.net/w7Mm8/32/. – ScottS Dec 07 '11 at 04:08
1

By chance I stumbled on this. Setting white-space: normal actually made Firefox push the scroll bar outside. See http://jsfiddle.net/w7Mm8/36/.

Edit: Wait... not with only five (the previous fiddle had six words): http://jsfiddle.net/w7Mm8/37/. Somehow, the extra word caused it to behave.

Edit2: Based on the bizarre observation above (the white-space: normal did not really have anything to do with it, it was the extra word), there is a bizarre "workaround" that may prove useful to some people (and a pain for others). See (five words) http://jsfiddle.net/w7Mm8/49/, (six words) http://jsfiddle.net/w7Mm8/57/. The content must be set to 3 characters and cannot be spaces (from my experiments). Note: the pseudo element has to be where the text content is, however deep that is, see: http://jsfiddle.net/w7Mm8/58/ where it does not work.

ScottS
  • 71,703
  • 13
  • 126
  • 146