I came across an interesting issue today with the max-width property. It’s a property that I’ve only used in a few occasions in the past – mainly due to the constraints of legacy browsers that do not support it.
That being said, it’s extremely useful and this week I’ve found an interesting peculiarity with it that I have not come across before. Searching for this issue proved to be fruitless – mainly due to the fact that it’s a bit of a tricky one to word properly!
The issue I was finding in all browsers that support min-width (with the exception of IE7) was how it handled the width when a text label exceeded the allotted max-width value and thus was forced to wrap onto a subsequent line(s).
For example, I had a series of 7 navigational items. No item in the list was to exceed 104 pixels in width. This worked, as expected, but where I saw the ‘funniness’ were on the navigational elements that required word-wrapping (since they were to wide to fit on a single line). In these cases, the max-width value of the item was still being applied as 104 pixels even though the item was now technically less than that in width. This created really ugly gaps between the items, as you can see from the screen-shot below:
In order to get some context on the issue I was having, I’ve provided the HTML and CSS I used:
<ul id="primary" class="clearfix"> <li><a href="about_e.html">About us</a></li> <li><a href="products_e.html">Investment products</a></li> <li><a href="prices_e.html">Prices and performance</a></li> <li><a href="management_e.html">Investment management</a></li> <li><a href="informed_e.html">Stay informed</a></li> <li><a href="helpful_e.html">Helpful information</a></li> <li><a class="lit" href="investor_e.html">Investor learning</a></li> </ul>
#primary {
font-size: 14px;
line-height: 1;
list-style-type: none;
margin: 0;
position: relative;
word-wrap: normal;
z-index: 100;
}
/**
* @subsection Custom-styled for "Home" Page
*/
#primary li {
display: inline-block;
font-family: Arial, Helvetica, sans-serif;
margin: 0 0 0 20px;
max-width: 7.43em; /* 104 pixels */
padding: 10px 0;
vertical-align: middle;
*display: inline;
*zoom: 1;
}
#primary a {
display: inline;
text-decoration: none;
text-transform: uppercase;
}
#primary :hover a,
#primary .sfhover a,
#primary a.lit,
#primary a:hover { color: #eaac1f !important; }
Note: This was taken from the existing project so a few extraneous styling rules may have been missed (that were elsewhere in the CSS document), but for the most part this is what I had.
I thought this was a bug until I cracked open a copy of the W3C specification and found the following:
- The tentative used width is calculated (without ‘min-width’ and ‘max-width’) following the rules under “Calculating widths and margins” above.
- If the tentative used width is greater than ‘max-width’, the rules above are applied again, but this time using the computed value of ‘max-width’ as the computed value for ‘width’.
- If the resulting width is smaller than ‘min-width’, the rules above are applied again, but this time using the value of ‘min-width’ as the computed value for ‘width’.
Item number two from the list above is where my problems were stemming from. For all intents and purposes, the max-width properly was working the way it was supposed to (which means that IE7′s version of the property is incorrect, even if it meant that it worked the way I was hoping it would).
In terms of finding a solution with CSS it would appear I was out of luck. Short of rewriting the specification for the property and having it ok’d and implemented cross-browser before this project I was working on was due, well, that wasn’t going to happen!
The solution to my problem was to use a bit of JavaScript that ran through each item in the navigation and then assigned a width to the item (the one that has been assigned the max-width property) that was equal to the width of the hyperlink contained therein. Since this width value of the hyperlink could not possibly exceed the max-width value, I knew that the highest the value could go was 104 pixels and the lowest would be however wide the now reformatted (word-wrapped) hyperlink was:
<script type="text/javascript">
$('#primary > li').each(function() {
$(this).width($('a', this).width());
});
</script>
This rendered the navigation in the way I wanted – each item that was previously set to the max-width value was now re-sized to be the actual width of it’s child element, as shown in the screen-shot below:
Notes
- The hyperlink had to be styled as an inline-level element; otherwise if was styled as a block-level element the
widthof it would always be equal to thewidthof it’s parent.


As shown on the right, this is just a simple static content feature for the client’s Facebook and Twitter accounts. The layout and decoration of the feature, however, is a bit more complicated. Add to the fact that this element should have a fluid width and height, and you are looking at a very ‘heavy’ piece in terms of the HTML, CSS and imagery that are required to achieve this.
