Rounded corners + 4 sides

Hi,

I come across a problem I can’t seem to figure out what to do. Before reading further, please look at the attached image.

How do I make a container that I can use over and over throughout the site with the rounded corners + shadow effects (have to work in older browsers, so css3 is not an option).

These are the requirements for the containers

  1. need rounded corners
  2. transparent corners
  3. each corner/side should not overlap
  4. should be as semantic as possible (can’t put certain corners/sides inside h1 or so because the container should be able to be placed any section - even those without headings)
  5. it’s for em based elastic layout

I achieved all the above with 4 divs (each taking up a corner and side), but the problem is that since each divs are nested - they overlap each other. Any suggestion how I can make this “all-purpose and reusable” container?

I checked out several examples and yet to find a solution. Thanks in advance. :slight_smile:

Assuming 10px of transparent/rounded area. (mind you this omits top, height, etc)

#borderTop { position:relative; margin-right:10px; }

#borderTop div { position:absolute; right:-10px; width:12px; }

The extra 2px on the width is for overlap because firefux and other gecko based browsers can be a bit idiotic when it comes to calculating what ‘right’ (or center/margin:auto) means. Sometimes it adds an extra px width, sometimes it adds one less… and if you use zoom it can become 2px, hence the extra overlap. Sometimes it even just jumps around randomly depending on how far from the right edge of the display the browser window is. (more pronounced under Linsux and other X11 environments)

You use the margin to make the gap, you use the negative right positioning to slide the nested div into place. Ideally we’d be using left:100%, but IE doesn’t report the width properly and in FF it can leave that 1 to 2px gap we have that extra width to ‘cover up’.

Just don’t forget #borderTop would need a haslayout trigger for IE so that the absolute positioning isn’t all screwy – in this case height would be the ideal choice.

Someone asked for something similar a while ago and I knocked this example up. It’s not particularly clever but does the job using only two sprite images.

As Jason said the extra hooks are needed whether you disguise them with existing elements or not so the most re-usable way is to add them from the start. There is no getting away from the fact that if you have eight images then you need 8 places to hang them. You can of course reduce this with clever image manipulation (e.g. two sides and one corner on one element) but that doesn’t allow for fully fluid elements as the images have a fixed dimension (albeit very large)

When dealing with transparent corners you have to move the corners outside the container otherwise the background will show through. It’s a bit fiddly as the dimensions have to match the images of course.

You can’t use absolute positioning if you want to support IE6 because it is 1px out for right and bottom on every odd width container.

That’s where my ‘eight corners’ shines. You can make that maximum width be 2048 or larger and the file size doesn’t really get bigger thanks to png being absurdly efficient at encoding long runs of the same color on the horizontal… all using just ONE image to build the entire thing.

Oh, and in mine for some reason that 1px gap never shows up. I’m not sure if it’s the haslayout, not sure if it’s some other trigger like my forcing font-size:1px - hell it could just be that I’m testing inside a VM… but it’s not an issue. I remember when I was writing it originally that problem cropped up, but damned if I can remember what I did to fix it. I think it was to NOT state a width and only position vertically off Top. It’s actually WIDTH that screws it up - if you let the element size itself it’s a non-issue… I think.

I guess minimizing markup is not always a good idea when it comes to achieving what you want. I’ll take extra markup as long as it’s reasonable, cross-browser, and no JavaScript any day.

Seven tag count is not that much higher than “CSS Liquid Round Corners” example’s six tag count.

The only problem (because it has to be liquid) with the markup is that:

<div class="borderTop"><div></div></div>

Lets assume borderTop has top left transparent corner + the top side and the nested div has the right corner - then wouldn’t the top side background image appear beneath the transparent right corner?

I can personally think of positioning the nested div that is inside borderTop outside through negative value, but how would you guys do it in this situation?

I’d like to add that transparent corners alone are hardly a problem, its transparent corners with 4 sides that is the trouble. I tweaked around and achieved the desired effect through relative positioning etc, but it makes positioning/spacing the over all container on page difficult.

I’m actually surprised that no one ever made a proper example for transparent rounded corners + 4 sides containers.

Dr John, thanks but I want to do this without java script.

Hi, I tried out the second one with my test design. It just won’t work well with transparent corners, overlapping occurs. Same with what I did with just 4 divs. I can see that the result will be same for “Eight Corners Under One Roof” example too based on the markup itself.

Guess it’s not possible to do a liquid “transparent rounded corners + 4 sides” container without excessive divs or so.

There was a nice discussion about this a few weeks ago, but I can’t find the link, I’m afraid. Anyhow, Jason, who did most of the work there, posted this very helpful tutorial summarizing what was done:

http://battletech.hopto.org/html_tutorials/eightcorners/template.html

See if that helps. :slight_smile:

EDIT: here’s another nice example:

If you are absolute positioning them, what’s stopping the entire content are background from showing through the transparencies?

@cssExp, suck it up and use the extra markup :wink:

Done properly it’s MAYBE 215 bytes per box extra — if you are worried about savings they can usually be found elsewhere in your document. It seems like people are taking this minification of code TOO far… So long as you aren’t nesting a few hundred deep, using empty tags (ignored) or tags that apply no semantic meaning to their content (B, I, DIV, SPAN), big honking deal!

I mean looking at your attached example, is this REALLY that big a deal code-wise?



<div id="sideBar">

	<div class="borderTop"><div></div></div>
	<div class="borderFirstSide"><div class="borderSecondSide">
	
		<ul id="mainMenu">
			<li><a href="\\">Home</a></li>
			<li><a href="\\about">About Us</a></li>
			<li><a href="\\services">Services</a></li>
			<li><a href="\\support">Support</a></li>
		</ul>
		
	<!-- .borderSecondSide, .borderFirstSide --></div></div>
	<div class="borderBottom"></div></div></div>
	
<!-- #sideBar --></div>

<div id="content">
	<div class="borderTop"><div></div></div>
	<div class="borderFirstSide"><div class="borderSecondSide">

	<h2>Welcome to Test Page</h2>
	<p>
		Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
	</p><p>
		Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
	</p>
	
	<!-- .borderSecondSide, .borderFirstSide --></div></div>
	<div class="borderBottom"></div></div></div>
	
<!-- #content --></div>

430 bytes extra code isn’t a big deal, your code to content ration would still be well under 2:1, unlike the 10:1 most other approaches would give you (especially when you get the dumbasses who are going to tell you to use jquery or javascript for that). It’s funny, I used to be the guy who obsessed about removing unneccessary markup, but much like making hardware smaller there is such a thing as too small, too thin, and too lightweight to be practical/maintainable/etc.

P.S. Who do we *****-slap for adding the buggy broken lightbox BS to attachments? As if vBull wasn’t fat enough a bloated pig to begin with…

[QUOTE=deathshadow60;4667704]If you are absolute positioning them, what’s stopping the entire content are background from showing through the transparencies?

Don’t absolute them, relative them and play with negative margins and position.

No problem and nice demo by the way :slight_smile:

This javascript claims to do many of the things that you want.
http://www.ruzee.com/blog/shadedborder
not used it myself though.

It is possible:

Think your layout to be a cross +. In the middle of that cross is where the content will be. In the 4 corners of the cross you absolute position the transparant rounded corners.

Just draw a cross on some paper and add content in the middle, you will understand.

Ok, it was testing XP in a VM with IE7 installed that ‘fixed’ that 1px issue, not anything I did. It still does it in my win2k with nothing else but IE6 on it VM.

BUT, easy enough to deal with. Float it, then slide it into the gap made by margin using position:relative – now the parent doesn’t need the position:relative AND it kills the FF bug. (thanks Paul for getting me thinking on that problem again)

I made a quick gutted testcase to test it without images.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
	xmlns="http://www.w3.org/1999/xhtml"
	lang="en"
	xml:lang="en"
><head>

<meta
	http-equiv="Content-Type"
	content="text/html; charset=utf-8"
/>

<meta
	http-equiv="Content-Language"
	content="en"
/>

<style type="text/css"><!--
/* null margins and padding to give good cross-browser baseline */
html,body,div {
	margin:0;
	padding:0;
}

body {
	background:#000;
}

.borderTop {
	overflow:hidden; /* wrap floats */
	height:16px; /* also trips haslayout, floats wrapped in IE */
	margin:10px 26px 0 10px;
	font-size:1px; /* prevent IE height bug */
	background:#FFF; /* url(images/border.png) 0 0 no-repeat; */
}

borderBottom {
	background-position:0 -16px;
}

.borderTop div,
.borderBottom div {
	position:relative;
	left:16px;
	float:right;
	width:16px;
	height:16px;
	background:#F00; /* url(images/border.png) -2032px 0 no-repeat; // position = 2048-width */
	
	/* opacity lets us check for overlap, any pink is bad! */
	opacity:0.8;
	-moz-opacity:0.8;
	filter:alpha(opacity=80);
}

.borderBottom div {
	background-position:-2032px -16px;
}
--></style>

<title>
	Quick positioning test
</title>

</head><body>
	<div class="borderTop"><div></div></div>
</body></html>

I used opacity so that I could test for overlap as well as gaps after commenting out the images. Float it, relative position it based on where the float lands it.

Now I just have to revise my ‘eight corners’ page to reflect that. I think I didn’t use this version before because Opera hated it, but it looks like it’s fine in 10.6. A lot of Opera’s old rendering quirks are finally biting the dust now that they have introduced a whole bunch of new ones!