The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

In the 4th quiz 2nd part it's easily done, but then the CSS code becomes very dependent on the heading. For example, if we change the heading text, the shadow effect won't work anymore. So I think the solution for the 1st part is more usable.

In the 4th quiz 2nd part it's easily done, but then the CSS code becomes very dependent on the heading. For example, if we change the heading text, the shadow effect won't work anymore. So I think the solution for the 1st part is more usable.

If you have a solution then PM it to me as there are not that many entries for the 4th quiz as yet.

Remember that not all the quizzes have a real life usage and are mainly for fun and exploring the limits of CSS

Erik is the overall winner as he completed three of the quizzes (it would have been four but that as his quiz anyway). Gary had the quickest entry for the equal spread and although it only works in modern browsers but as there were no other closer entries than Gary wins that one

I'm short of time as I am away on holiday tomorrow for 2 1/2 weeks so forgive that these explanations are short but I'm sure Erik can fill you in with the details later if you have questions while I'm away.

Quiz 1 (advert to the side of page and no scrollbar)

This confused a few of you and I thought you would find it easy but most of you stumbled on this.

This quiz by Yurikolovsky was to achieve a min-width in IE6 without using scripting or expressions. You didn't actually have to look far for the answer because it is there in the CSS faq for all to see. Unfortunately not many of you spotted it. The trick is to use a wide border on an outer div and then drag the content into the border.

In the second part of this quiz we set a trap for you because IE has a limit on how wide borders can be That's why we asked for a a rather large min-width to trigger this bug. IE will only apply a maximum border of 960px width and therefore would fail on anything larger.

<!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>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style>
* {
margin:0;
padding:0
}
body {
background:#f2f2f2;
text-align:center;
}
#outer {
width:80%;
background:#fffccc;
margin:auto;
text-align:left;
position:relative;
min-width:1024px;
border:1px solid #ccc;
}
h1 {
text-align:center;
}
p {
padding:10px;
margin:0 0 1em 0
}
</style>
<!--[if lt IE 7]>
<style type="text/css">
#inner{border-left:512px solid #fffccc;float:left;}
#inner2{border-left:512px solid #fffccc;float:left;}
#content{margin-left:-1024px;height:1px;position:relative;}
</style>
<![endif]-->
</head>
<body>
<div id="outer">
<div id="inner">
<div id="inner2">
<div id="content">
<h1>Min-width in Ie without scripting</h1>
<p>This layout is restricted to a minimum of 1024px pixels but will also
expand to 80% of the available space. This is useful if you have floats
that you don't want to drop or images that you don't want clipped.</p>
<p>Ie doesn't understand min-width and the usual way to restricts its
width is to use scripting or an expression, both of which rely on javascript
being enabled. This layout however just uses CSS for the effect and
in fact contains no hacks and would work in any browser, however I have
hidden the extra styles in conditional comments because other browsers
don't need them anyway as most of them understand min-width.</p>
<p>The concept is simple in that the min-width is achieved by nesting
an element that has a left border equal to the minimum width we require.
A further nesting is then used and the element is dragged across the border
with negative margins.</p>
<p>The main drwaback is of course the 2 non-semantic divs required to
do this. However its another choice that can be made if you want this
effect, it's just a shame that we have to go to such lengths for a simple
effect.</p>
<p>This is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : his is the
content : this is the content : his is the content : this is the content
: his is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : his is the
content : this is the content : his is the content : this is the content
: his is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : his is the
content : this is the content : his is the content : this is the content
: his is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : his is the
content : this is the content : his is the content : this is the content
: his is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : </p>
<p>This is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : his is the
content : this is the content : his is the content : this is the content
: his is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : his is the
content : this is the content : his is the content : this is the content
: his is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : his is the
content : this is the content : his is the content : this is the content
: his is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : his is the
content : this is the content : his is the content : this is the content
: his is the content : this is the content : his is the content : this
is the content : his is the content : this is the content : </p>
</div>
</div>
</div>
</div>
</body>
</html>

This test provided by Ryan was to produce shadowed text in all browsers and the answer was to simply overlay one piece of text on another.

Ryans Original:

Code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
html, body {
height:100%;
}
* {
margin:0;
padding:0;
}
body {
font-size:100%
}
h1 {
margin:0;
padding:0;
color:white;
position:absolute;
left:0;
right:0;
font-size:200%;
font-weight:bold;
}
h1.overlay {
color:darkgreen;
position:absolute;
left:1px;
top:1px;
}
h2 {
position:absolute;
top:150px;
}
</style>
</head>
<body>
<h1 class="overlay">This is the heading. It doesn't matter what font you use as long as you know this ltitle "trick" behind
it. A simple quiz if you understand the underlying concept. Must work in IE6-8, Opera, Safari, and FF.</h1>
<h1>This is the heading. It doesn't matter what font you use as long as you know this ltitle "trick" behind it. A simple quiz
if you understand the underlying concept. Must work in IE6-8, Opera, Safari, and FF.</h1>
<h2>This is a little textshadow which is supposed to be in CSS3...</h2>
</body>
</html>

The second part of this quiz was to use the html I provided which meant you couldn't use duplicate html to achieve the effect.

The answer was to use the :before pseudo class and place the text on top from the css rather than the html. Unfortunately Firefox didn't allow absolute positioning of the pseudo class which is why the extra span was added to the html and the text in the span was absolutely placed on top of the pseudo class content instead.

As Ie6 doesn't understand the :before pseudo class I used the proprietary drop-shadow filter to create IE specific shadowed text.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Quiz #24d / Erik J</title>
<style type="text/css">
body{
font: 400 120%/1.2 sanserif;
}
/* Double content */
h1{
position:relative;
color:black;
font-size:100%;
}
h1 span{
position:absolute;
top:-2px;
left:-2px;
color:silver;
}
/* CSS 2 and IEfilter */
h2{
position:relative;
height:99em;
overflow:hidden;
color:black;
font-size:100%;
}
h2:before{
display:block;
margin:2px 0 0 2px;
content:"Part 2, CSS 2 and IE filter) This is the heading. It doesn't matter what font you use as long as you know this little trick behind it. A simple quiz if you understand the underlying concept. Does work in IE6-8, Opera, Safari and FF.";
}
h2 span{
position:absolute;
top:0;
left:0;
color:silver;
filter:progid:DXImageTransform.Microsoft.DropShadow(OffX=2, OffY=2);
}
</style></head><body>
<h1>
Part 1, Double content) This is the heading. It doesn't matter what font you use as long as you know this little trick behind it. A simple quiz if you understand the underlying concept. Does work in IE6-8, Opera, Safari and FF.
<span>Part 1, Double content) This is the heading. It doesn't matter what font you use as long as you know this little trick behind it. A simple quiz if you understand the underlying concept. Does work in IE6-8, Opera, Safari and FF.</span>
</h1>
<h2>
<span>Part 2, CSS 2 and IE filter) This is the heading. It doesn't matter what font you use as long as you know this little trick behind it. A simple quiz if you understand the underlying concept. Does work in IE6-8, Opera, Safari and FF.</span>
</h2>
</body></html>

That about wraps it up and as I mentioned above I will be away until the 5th July so you cann have a rest from the quizzes until then as I think most of you are quizzed out at the moment

Thanks to all the contributors and participants and hope you enjoy the solutions anyway.

Quiz 2 (equal Spread): Once again, dastardly Erik came up with something totally off the wall! Because text-align:justify doesn't cause stretching on line boxes which are "too narrow" (such as the last line box of a block), most people would have abandoned hope there… but he carried on and forced there to be a second line box by placing a sufficiently large margin-right on the last LI so that it was guaranteed to wrap! However, because we don't actually want the text of the last LI to wrap with it, he needed to place some extra character after the real text so that the wrapping would occur at that point instead. (Replace his &nbsp;s with 'x's to see what's going on.) Note that the only critical $nbsp;/x is the very last one, which wraps onto the next line causing the text on the first line to justify as desired. He then added a few "cosmetic" extra &nbsp;s/x's: one at the start of the first LI and another at the end of the last LI to push their real text away from the sides; and one at the start of each other LI to ensure that the spacing between the LIs is greater than the spacing at the start and end of the line, which looks better. (Note, however, that it's not at all clear that browsers should treat &nbsp;s as "fixed"-width characters; after all, they're defined to be non-breaking, not non-stretching. It would be unwise to rely unconditionally on the "distribution" behaviour that we see in the well-known browsers!)

However, the "closest" CSS 2.1 solution to the problem is to use display:table as several people did. (display:table is the only other horizontal space-distribution mechanism which exists in CSS 2.1, although a more general "flex" concept looks set to arrive in CSS 3.) IE6/7 don't support the table display types, but we can always just use conditional comments to place a secret TABLE and TR around the UL and secret TDs around the LIs; these warty but robust old browsers can recover gracefully from the muddled markup. (This technique also happens to be my favourite method of vertical centering.)

That said, the display:table solution will overflow undesirably when the menu items don't want to fit on the line, whereas Erik's solution has the advantage of wrapping onto the next line (albeit with the last line uncentred), provided you get rid of the unnecessary overflow:hidden on the UL. It's almost tempting... but any solution involving content kludges has to be frowned upon in "real" webpages.

Quiz 3 (min-width for IE6): Yuri's approach is certainly ingenious, and revolves around the shrink-to-fit behaviour of floats whose width is 'auto'. But surely if border causes problems with really large min-widths, wouldn't you just use padding instead (as he does in his second solution) rather than going overboard with nesting?

(Incidentally, in Yuri's border solution, the position:relative on .minwidth and the z-index on both .minwidth and .container are unnecessary, although the postion:relative on .container is required as usual when pulling a child out of its parent's content area. In his padding solution, the middle .ie6minwidth2 div is not ordinarily necessary but was required here because he forgot to fix the IE6 double float margin bug on .ie6minwidth3 through the use of float:left; _display:inline;.)

However, alas, this float approach is not quite correct (whether using border or padding), as easily demonstrated using Yuri's border solution and placing a coloured background on the .container. Because of the slightly broken implementation of shrink-to-fit in IE6/7, the .container does not in general occupy the full width of the viewport (or the full 960px min-width for narrow viewports); instead, it shrinks a little bit too much to ensure that the right content edge is flush with the text content. It looks ok in Paul's solution — but that's just because the layout is centred so that the discrepancy is masked.

Moreover, the float approach seems rather convoluted given that IE6 already supports a kind of min-width as we know and <del>love</del><ins>hate</ins>: if you want min-width:something together with width:auto, just use width:something for IE6. The element is then hasLayout and will expand to enclose its oversize content rather than permit overflow (in violation of CSS 2.1), in a manner akin to min-width. This isn't enough for this quiz though, because we want a real min-width including the possibility of setting a distinct width (eg width:90%; min-width:500px). But building on what we have, a more "natural" solution to the quiz is simply to give the element the required width and place inside it an empty child "prop" element of width:something which will forcefully widen the parent if it would otherwise be too narrow. Now, the height of an empty hasLayout element is equal to the line-height rather than being zero as one might expect, which gives us unwanted space at the top of the parent; but this is easily overcome by forcing the prop to have zero height: set height:0; overflow:hidden;. This gives us a genuine replacement for min-width, irrespective of font-size.

Quiz 1 (width-dependent clipping): the most interesting of the quizzes, with some neat CSS 2.1 behind the solution, as demonstrated by Paul and Erik. The theory is to have a viewport-width, fixed-min-width, overflow-hidden wrapper holding a fixed-width, horizontally centred container from which the "adverts" are pulled outside (applying position:relative for IE6/7 as usual for pull-outs).

[Erik: beware those position:absolute advert columns! They've forced you to add a few unnecessary heavyweight styles to the mix, and yet you still can't scroll the viewport vertically to reach their bottom extent if they are taller than the viewport. Better to make them floated siblings of the (floated) main content and pull them to either side of the main content using negative margins, irrespective of whether you restrict the technique to the adverts alone (as Paul did) or apply it to the page container. Note that Paul shifted them using position:relative instead, but that only works if the main content is wide enough to allow both adverts to naturally sit side-by-side in their wrapper.]

However, centred layouts are the easy part! Harder is left-aligned layouts. Here we need to float the main content leftwards and then apply the horizontal prop idea from Quiz 3 to all browsers: this sibling prop keeps the main content away from the left viewport edge to force space for the left advert, but has less and less of an effect as the viewport is narrowed until it has no effect at all when the viewport is narrower than the main content (an effect achieved using a combination of width and max-width on the prop). The prop can be implemented via CSS alone using generated content in browsers with excellent CSS 2.1 support, whereas other browsers (such as IE6/7, Firefox<=3) need a physical prop element. And of course, to work in IE6 the technique requires a working combination of width and max-width which I believe can only be achieved through the use of scripting. [In my code below I've used coloured borders on the .inner div instead of having separate advert divs, to demonstrate the concept as minimally as possible.]

Several interesting questions arise from this. In the left-aligned layout, the right advert disappears first, followed by the left advert; whereas in the centred layout both adverts disappear simultaneously. Is there a way of changing the order of disappearance? What about right-aligned layouts? (My guess is "no"… except perhaps for the right-aligned mirror image of the left-aligned layout, and even then it's possibly not achievable given that right and left [and top and bottom] are not equivalent due to how browsers will try to scroll to right/bottom content.)

Of course, in reality, you shouldn't use any width-dependent clipping technique for adverts, or any other useful content. Since (of course!) we'd only ever place adverts that our readers would be interested in, they'd be very frustrated if this content was clipped and unreachable. The technique does have its place though, such as for viewport-width overlay strips or wide main images whose horizontal extremes are nice to have on wide viewports but unimportant for narrow viewports.

[And, as always, treat any use of overflow:hidden with extreme caution! Are you really sure that your main content is not going to overflow and get clipped at large font sizes?]

Quiz 2 (equal Spread):
...
He then added a few "cosmetic" extra &nbsp;s/x's: one at the start of the first LI and another at the end of the last LI to push their real text away from the sides; and one at the start of each other LI to ensure that the spacing between the LIs is greater than the spacing at the start and end of the line, which looks better. (Note, however, that it's not at all clear that browsers should treat &nbsp;s as "fixed"-width characters; after all, they're defined to be non-breaking, not non-stretching. It would be unwise to rely unconditionally on the "distribution" behaviour that we see in the well-known browsers!)
...

As you say, they were "cosmetic" and only added to equally space the items when some were commented out for testing, and to finally center the last item left.

In real life I would give ending space to the items at the list ends by e.g. a fluid padding on the list.

Quiz 3 (min-width for IE6):
...
Moreover, the float approach seems rather convoluted given that IE6 already supports a kind of min-width as we know and <del>love</del><ins>hate</ins>: if you want min-width:something together with width:auto, just use width:something for IE6. The element is then hasLayout and will expand to enclose its oversize content rather than permit overflow (in violation of CSS 2.1), in a manner akin to min-width. This isn't enough for this quiz though, because we want a real min-width including the possibility of setting a distinct width (eg width:90&#37;; min-width:500px). But building on what we have, a more "natural" solution to the quiz is simply to give the element the required width and place inside it an empty child "prop" element of width:something which will forcefully widen the parent if it would otherwise be too narrow. Now, the height of an empty hasLayout element is equal to the line-height rather than being zero as one might expect, which gives us unwanted space at the top of the parent; but this is easily overcome by forcing the prop to have zero height: set height:0; overflow:hidden;. This gives us a genuine replacement for min-width, irrespective of font-size.

If I understand you right here, an extra div placed as sibling to the content would give the container that minimum width.

If I understand IE behavior right, it is letting the overflow grow its container only to display the overflow, while other e.g. floated content still is restricted to the container's original fluid width.

So I think in this caes if you use a content sibling to push the container wider than the viewport width, still the content could (depending of its nature) be restricted to the viewport and wrap fluid at viewport edge, while its container stays wide with an empty scroll.

Quiz 1
...
[Erik: beware those position:absolute advert columns! They've forced you to add a few unnecessary heavyweight styles to the mix, and yet you still can't scroll the viewport vertically to reach their bottom extent if they are taller than the viewport.
...
]

My interpretation of Paul's attachment was that the ads should be clipped outside the content scroll. As you also noted, he hinted the solution could be used for an overlay of images to merge with background and not induce extra scrolling

If I understand you right here, an extra div placed as sibling to the content would give the container that minimum width.

and you answered it yourself. :P

still the content could (depending of its nature) be restricted to the viewport and wrap fluid at viewport edge, while its container stays wide with an empty scroll.

putting a sibling of specific width inside the content box to have that content box not shrink below that size in ie6, will not do the trick completely,
it will simply create a scrollbar, but will not stop the content in the container from shrinking in any way.

if you want min-width:something together with width:auto, just use width:something for IE6.

needs to expand depending on the exterior, not interior (expands with window, not on contents).

If I understand IE behavior right, it is letting the overflow grow its container only to display the overflow, while other e.g. floated content still is restricted to the container's original fluid width.

You're absolutely right of course! I'd forgotten all about that behaviour. How embarrassing: I must spend too much time with abstract test-cases, because I didn't think to actually put some real content in ;-)

Originally Posted by YuriKolovsky

if you want min-width:something together with width:auto, just use width:something for IE6.

needs to expand depending on the exterior, not interior (expands with window, not on contents).

Indeed! You've both got me thinking about why I don't usually run into this particular non-equivalence of min-width and _width. I think it's because I don't actually use min-width much on containers of free content. (I tend to be more concerned about max-width I want variable-width columns, to ensure that the line boxes don't get too wide.) I would appear to use min-width in very limited situations such as on buttons that I want to ensure are at least wide enough for their full background image to show (and I've just verified that button text does force the button to expand if the specified _width is too narrow, so I don't run into the problem in that particular case).