33
#tooltip
{ 
    position: absolute;
    width:auto;
    min-width:50px;
    max-width:250px;
    padding:10px;
    background-color:#eee;
    border:1px solid #aaa;
}

Based on this style I would expect my tooltip to shrink or grow to fit the content, down to 50px or up to 250px. However, the max-width property seems to be over-riding my width property when a content wraps to the next line. It is an aesthetics thing when the word at the end of a sentence is long, it looks like it leaves a bunch of padding (see screenshot). Is that the normal behavior?

enter image description here

Sam
  • 9,933
  • 12
  • 68
  • 104

3 Answers3

32

Yes, that's the normal behavior.

A browser will try to flow your text inline within the box until it reaches its maximum allowed width of 250px, then wrap to the next and subsequent lines any text that cannot fit on the first line. (If there is not enough text to reach the maximum width, then width: auto causes the box to shrink to fit just that amount of text.)

However, the box will not shrink again to fit the text after wrapping it, because text wrapping just doesn't work that way. This means the box's width is computed as 250px, and only because your CSS states that it can only be 250px at most. It's not computed to some smaller value equal to the width of the text after wrapping then overridden by max-width.

I don't think there is anything you can do to change this behavior.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Thanks for confirming! Couldn't find the answer elsewhere. – Sam Sep 11 '12 at 21:38
  • There may not be any way to change this behavior with CSS, but it can be done with JS. http://stackoverflow.com/q/33244477/3597276 – Michael Benjamin Oct 20 '15 at 21:01
  • I don't quite understand. `causes the box to shrink to fit just that amount of text` or `the box will not shrink again to fit the text after wrapping it`? Both can't be true. The 2nd and 3d paragraph of your answer seem to me to contradict. – Mikhail Batcer Aug 08 '16 at 15:10
  • @Mikhail Batcer: Both can be true, because the box shrinks to fit the text *before* wrapping it, and doesn't do that again *after* it's wrapped. – BoltClock Aug 08 '16 at 15:15
  • @BoltClock From the 2nd paragraph, it looks like box shrinks _after_ wrapping: 1. try to flow your text inline 2. wrap to the next and subsequent lines any text that cannot fit 3. the box to shrink to fit. That's the original order in your answer :) – Mikhail Batcer Aug 08 '16 at 15:25
  • 2
    @Mikhail Batcer: Yeah I got confused there (this is a really old answer and I had to reread the question to get a refresher). What I *totally* meant to say, was that "causes the box to shrink to fit just that amount of text" only applies when there is not enough text to be wrapped in the first place. Which means, really, no wrapping is done at all. And "the box will not shrink again to fit the text after wrapping it" only applies when wrapping does take place because the box is being constrained by max-width. So, you're right, both can't be true - because they're mutually exclusive. – BoltClock Aug 08 '16 at 15:31
  • @Mikhail Batcer: In any case, I edited my answer to clarify. – BoltClock Aug 08 '16 at 15:32
  • 1
    @BoltClock Yeah, now it's clear. What a pity wrapping works this way... It makes it much less useful. – Mikhail Batcer Aug 08 '16 at 15:42
  • NOte if you manually add BR tags for line breaks in you html it will behave as expected. – yeahdixon Sep 27 '18 at 02:35
7

You will need some JavaScript to get the desired result.

Create a Range object to measure the size of your content. Set the width of your container accordingly.

const range = document.createRange();
const p = document.getElementById('good');
const text = p.childNodes[0];
range.setStartBefore(text);
range.setEndAfter(text);

const clientRect = range.getBoundingClientRect();
p.style.width = `${clientRect.width}px`;
p {
  max-width: 250px;
  padding: 10px;
  background-color: #eee;
  border: 1px solid #aaa;
}

#bad {
  background-color: #fbb;
}
<p id="bad">This box has a max width but also_too_much_padding.</p>
<p id="good">This box has a max width and the_right_amount_of_padding.</p>
mfluehr
  • 2,832
  • 2
  • 23
  • 31
6

Try using one of this:

width: max-content;
width: min-content;
width: available;
width: fit-content;

They are not 100% compatible, but prefixes fix that problem more or less.

Source: https://developer.mozilla.org/docs/Web/CSS/width

daniels
  • 4,961
  • 2
  • 22
  • 11