GlennGilbert
asked on
Setting "shrink-to-fit" width on a non-floated element
I need a non-floated box to have a variable width according to the content. This is the behaviour for a floated box.
Ultimately this is to create a 'tab' style on a heading (setting the left and right background images).
<p style="margin:0; border:1px solid black; padding:5px; background:yellow;">A full-width box</p>
<p style="float:left; clear:left; margin:0; border:1px solid black; padding:5px; background:yellow;">A shrink-to-fit box</p>
(e.g. section 10.3.3 of CSS2.1 spec)
Any ideas?
Glenn
Ultimately this is to create a 'tab' style on a heading (setting the left and right background images).
<p style="margin:0; border:1px solid black; padding:5px; background:yellow;">A full-width box</p>
<p style="float:left; clear:left; margin:0; border:1px solid black; padding:5px; background:yellow;">A shrink-to-fit box</p>
(e.g. section 10.3.3 of CSS2.1 spec)
Any ideas?
Glenn
ASKER
Oops. The <p> represents any box element.
With your code, the box will extend to the full width of the 'page'.
I don't want to specify the width as I don't know the width.
With your code, the box will extend to the full width of the 'page'.
I don't want to specify the width as I don't know the width.
ASKER
The designer's specified a sort of 'tabbed' style on the heading (I meant to say heading, but the principle remains for any box). It's fairly straightforward to set the tabbed style (as in this site's tabs).
The interesting point is being able to style both ends of the content area without floating the element (which sets the shrink-to-fit content area size). As there's no way of setting float:center, a float isn't the best solution.
The interesting point is being able to style both ends of the content area without floating the element (which sets the shrink-to-fit content area size). As there's no way of setting float:center, a float isn't the best solution.
Hmmm, i see what you mean... i got confused in my sliding doors technique...
I thought you could use the narrow background image on the <h3> and the wide background image on the <strong>... but then the small image would be covered by the wide image.
I guess you need to use inline elements only...
Either set "h3 { display:inline }", or use an additional inline element inside your <h3>.
I thought you could use the narrow background image on the <h3> and the wide background image on the <strong>... but then the small image would be covered by the wide image.
I guess you need to use inline elements only...
Either set "h3 { display:inline }", or use an additional inline element inside your <h3>.
ASKER
It's an interesting one this! I'd never really thought about it before.
Going back to the standards:
http://www.w3.org/TR/CSS21/visudet.html#Computing_widths_and_margins
Going back to the standards:
http://www.w3.org/TR/CSS21/visudet.html#Computing_widths_and_margins
ASKER
Setting the element to use inline formatting does indeed set a shrink-to-fit width.
But... you can't set padding & margins on inline elements!
Lets have a fiddle....
But... you can't set padding & margins on inline elements!
Lets have a fiddle....
> But... you can't set padding & margins on inline elements!
Yes you can. Inline elements don't have width nor height, but they have margins and padding.
Yes you can. Inline elements don't have width nor height, but they have margins and padding.
ASKER
... although it's possible to set the left/right padding (doesn't work on IE5 - see formating of display:inline horizontal menus), it's not possible to set the other styles, hence you rely on line-height.
I wonder if it's possible to use one of the table display styles...
I wonder if it's possible to use one of the table display styles...
Just note that it's not excellent coding style because of the unnecessary html tags... CSS3 draft defines multiple backgrounds for one single element, but we'll need to wait a little before browsers support that feature.
ASKER
One answer is to use a placeholder and absolute positioning (a bit like another answer from a few days ago).
Yuck.
Yuck.
ASKER
> Inline elements don't have width nor height,
Unfortunately this means that it's not particularly useful as the box has been 'partally' taken out of the flow.
However, it's possible to add any padding back by adding it to the surrounding elements: vis:
<style type="text/css">
h1 { background:#ffc;
margin:20px; /* add some margin to counteract the proceeding 'shrink-to-fit' element. Take into account collapsed v.margins */
border:0; padding:0; }
h2 { background:#fcf;
display:inline;
margin:0; border:0;
padding:20px; /* place some padding on the element */ }
p { background:#cff;
margin:20px; /* add some margin to counteract the preceeding 'shrink-to-fit' element. Take into account collapsed v.margins */
border:0; padding:0; }
</style>
</head>
<body>
<h1>Some text</h1>
<h2>Some more text that's longer</h2>
<p>Shorter text</p>
Now to add some sliding doors....
Unfortunately this means that it's not particularly useful as the box has been 'partally' taken out of the flow.
However, it's possible to add any padding back by adding it to the surrounding elements: vis:
<style type="text/css">
h1 { background:#ffc;
margin:20px; /* add some margin to counteract the proceeding 'shrink-to-fit' element. Take into account collapsed v.margins */
border:0; padding:0; }
h2 { background:#fcf;
display:inline;
margin:0; border:0;
padding:20px; /* place some padding on the element */ }
p { background:#cff;
margin:20px; /* add some margin to counteract the preceeding 'shrink-to-fit' element. Take into account collapsed v.margins */
border:0; padding:0; }
</style>
</head>
<body>
<h1>Some text</h1>
<h2>Some more text that's longer</h2>
<p>Shorter text</p>
Now to add some sliding doors....
ASKER
Here's the solution... a 'tabbed' wrapped around a H2 element that varies in width as the font is changed (<ctl>+<scrolly_rolly_mous ewheel>).
However, there's a modification to the sliding doors technique. The big drawback of the 'classic' sliding doors technique is that it uses two (or more) images. This means there's loads of superflous HTTP transactions, making the page appear slowly. You can use one image and change the background attachment. This technique can also be used for the variable-width and variable-height cornered box problem - www.alistapart.com's method uses FIVE images! You can use one image, provided:
1) the edges are solid and match the background
2) the centre's transparent.
So, the working code:
<style type="text/css">
body { font-family:Verdana, Arial, Helvetica, sans-serif; }
h1 { background:#ffc;
margin:10px; /* add some margin to counteract the proceeding
'shrink-to-fit' element. Take into account collapsed v.margins */
border:0; padding:0; }
h2 { background:#fcf url(../images/Border_Box_1 800w_369.g if) top right no-repeat;
display:inline;
margin:0; border:0;
padding:10px 30px 10px 0; /* place some padding on the element */ }
h2 strong { background: url(../images/Border_Box_1 800w_369.g if) top left no-repeat;
padding:10px 0 10px 30px; }
p { background:#cff;
margin:10px 0; /* add some margin to counteract the preceeding
'shrink-to-fit' element. Take into account collapsed v.margins */
border:1px solid red;
padding:10px; }
</style>
</head>
<body>
<h1>Some text</h1>
<h2><strong>Some more text that's longer</strong></h2>
<p>Lorum ipsum de blah blah...</p>
</body>
Tested on Firefox and works great. Was testing it on IE, but it's exploded and sulking, so I'll have to reboot my PC then...
However, there's a modification to the sliding doors technique. The big drawback of the 'classic' sliding doors technique is that it uses two (or more) images. This means there's loads of superflous HTTP transactions, making the page appear slowly. You can use one image and change the background attachment. This technique can also be used for the variable-width and variable-height cornered box problem - www.alistapart.com's method uses FIVE images! You can use one image, provided:
1) the edges are solid and match the background
2) the centre's transparent.
So, the working code:
<style type="text/css">
body { font-family:Verdana, Arial, Helvetica, sans-serif; }
h1 { background:#ffc;
margin:10px; /* add some margin to counteract the proceeding
'shrink-to-fit' element. Take into account collapsed v.margins */
border:0; padding:0; }
h2 { background:#fcf url(../images/Border_Box_1
display:inline;
margin:0; border:0;
padding:10px 30px 10px 0; /* place some padding on the element */ }
h2 strong { background: url(../images/Border_Box_1
padding:10px 0 10px 30px; }
p { background:#cff;
margin:10px 0; /* add some margin to counteract the preceeding
'shrink-to-fit' element. Take into account collapsed v.margins */
border:1px solid red;
padding:10px; }
</style>
</head>
<body>
<h1>Some text</h1>
<h2><strong>Some more text that's longer</strong></h2>
<p>Lorum ipsum de blah blah...</p>
</body>
Tested on Firefox and works great. Was testing it on IE, but it's exploded and sulking, so I'll have to reboot my PC then...
ASKER
Now rebooted. In the mean time I tested it against Safari/Mac, Opera8.5/Mac, and Firefox/Mac.
They all work.
**even** IE 5/Mac works - wow!
Needless to say it doesn't work on Internet Exploder/windoze...
They all work.
**even** IE 5/Mac works - wow!
Needless to say it doesn't work on Internet Exploder/windoze...
ASKER
OK, this is silly.
Could someone spread some light on this - why is IE adding an extra 10 pixels between the h2 and the strong?
Could this be the expanding box problem?
The following code fails on IE6/win. It works on all other platforms.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
body { font-family:Verdana, Arial, Helvetica, sans-serif; }
h1 { background:#ffc;
margin:10px; /* add some margin to counteract the proceeding
'shrink-to-fit' element. Take into account collapsed v.margins */
border:0; padding:0; }
h2 { background:#fcf;
display:inline;
margin:0; border:1px solid red;
padding:10px 30px 10px 0; /* place some padding on the element */ }
h2 strong { margin:0;
border:1px solid green;
padding:10px 0 10px 30px; }
p { background:#cff;
margin:10px 0; /* add some margin to counteract the preceeding
'shrink-to-fit' element. Take into account collapsed v.margins */
border:1px solid red;
padding:10px; }
</style>
</head>
<body>
<h1>Some text</h1>
<h2><strong>Some more text that's longer</strong></h2>
<p>Lorum ipsum de blah blah...</p>
</body>
</html>
Could someone spread some light on this - why is IE adding an extra 10 pixels between the h2 and the strong?
Could this be the expanding box problem?
The following code fails on IE6/win. It works on all other platforms.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
body { font-family:Verdana, Arial, Helvetica, sans-serif; }
h1 { background:#ffc;
margin:10px; /* add some margin to counteract the proceeding
'shrink-to-fit' element. Take into account collapsed v.margins */
border:0; padding:0; }
h2 { background:#fcf;
display:inline;
margin:0; border:1px solid red;
padding:10px 30px 10px 0; /* place some padding on the element */ }
h2 strong { margin:0;
border:1px solid green;
padding:10px 0 10px 30px; }
p { background:#cff;
margin:10px 0; /* add some margin to counteract the preceeding
'shrink-to-fit' element. Take into account collapsed v.margins */
border:1px solid red;
padding:10px; }
</style>
</head>
<body>
<h1>Some text</h1>
<h2><strong>Some more text that's longer</strong></h2>
<p>Lorum ipsum de blah blah...</p>
</body>
</html>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
> The big drawback of the 'classic' sliding doors technique is that it uses two (or more) images.
Not a big deal IMHO. If you use 2 images, that's just one more http request on the first page view... which is really nothing (for all subsequent pages, it's the cached image that will be used).
Having multiple backgrounds on one single image only has advantages when used for roll-over effects, so you don't need to preload your "hover" images.
Not a big deal IMHO. If you use 2 images, that's just one more http request on the first page view... which is really nothing (for all subsequent pages, it's the cached image that will be used).
Having multiple backgrounds on one single image only has advantages when used for roll-over effects, so you don't need to preload your "hover" images.
ASKER
Fantastic!!!
I've made a modification to let it work on IE7 (which won't support the Holly hack). I've not changed the image, but on the live version I will use a single image and change the background attachment.
Thanks for that,
Glenn
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Title</title>
<style type="text/css">
h3 { text-align: center; }
h3.MyHeading strong {
padding: .5em 0;
background: url("http://www.alistapart.com/d/slidingdoors/v1/norm_right.gif") right top no-repeat;
}
h3.MyHeading span {
padding: .5em 1em;
background: url("http://www.alistapart.com/d/slidingdoors/v1/norm_left.gif") left top no-repeat;
}
</style>
<!--[if ie]>
<style>
/* insert all the fixes that will be required by IE */
html h3.MyHeading strong { padding:0; display:inline-block; }
html h3.MyHeading span { display: inline-block; }
</style>
<![endif]-->
</head>
<body>
<h3 class="MyHeading"><strong> <span>My Heading</span></strong></h 3>
</body>
</html>
I've made a modification to let it work on IE7 (which won't support the Holly hack). I've not changed the image, but on the live version I will use a single image and change the background attachment.
Thanks for that,
Glenn
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Title</title>
<style type="text/css">
h3 { text-align: center; }
h3.MyHeading strong {
padding: .5em 0;
background: url("http://www.alistapart.com/d/slidingdoors/v1/norm_right.gif") right top no-repeat;
}
h3.MyHeading span {
padding: .5em 1em;
background: url("http://www.alistapart.com/d/slidingdoors/v1/norm_left.gif") left top no-repeat;
}
</style>
<!--[if ie]>
<style>
/* insert all the fixes that will be required by IE */
html h3.MyHeading strong { padding:0; display:inline-block; }
html h3.MyHeading span { display: inline-block; }
</style>
<![endif]-->
</head>
<body>
<h3 class="MyHeading"><strong>
</body>
</html>
ASKER
> If you use 2 images, that's just one more http request on the first page view...
There's little problem with one or two extra images. However, by creating a set of generic 'furniture' images, it does speed up the site - even in this age of broadband (just look at how slowly an eBay page loads).
The other benefit is that you rely less on designers to produce different size images.
There's little problem with one or two extra images. However, by creating a set of generic 'furniture' images, it does speed up the site - even in this age of broadband (just look at how slowly an eBay page loads).
The other benefit is that you rely less on designers to produce different size images.
ASKER
Just checked out the other browsers:
Working:
Firefox/Win, Firefox/Mac
IE6, IE5.5
Safari/Mac
Broken:
IE5 - doesn't expand the box (standard problem)
IE5/Mac - pretty knackered, which is hardly a surprise!
Glenn
Working:
Firefox/Win, Firefox/Mac
IE6, IE5.5
Safari/Mac
Broken:
IE5 - doesn't expand the box (standard problem)
IE5/Mac - pretty knackered, which is hardly a surprise!
Glenn
I also prefer using "<!--[if ie]>" for IE-only styles.
<:°)
<:°)
On a heading? then why do you use a <p>?
You can try using an inline element to set your right background image:
<h3 class="MyHeading"><strong>
Then in your CSS:
h3.MyHeading {
margin: 0;
padding: 0;
background: url("left.png") left top no-repeat;
}
h3.MyHeading strong {
padding: .5em 1em;
background: url("right.png") right top no-repeat;
}