How to make: Box on Boxes

You don’t want all those non semantic images messing up the html as that’s going back to the bad old days of image spacers :smile:

Simply use percentage padding top for the same effect and get rid of all those images from the html.

e.g.

<!DOCTYPE html>
<html  lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>little boxes</title>
<style>
*, *:before, *:after {
	-moz-box-sizing:border-box;
	-webkit-box-sizing:border-box;
	box-sizing:border-box;  /* ie8+ */
}

body {
    background-color:#f0f0f0;
    font-family:verdana,arial,helvetica,sans-serif;
    font-size:100%;
 }
#container {
    position:relative;
    width:40%;
    min-width:230px;
    margin:auto;
    background-color:#fff;
    box-shadow:0.25em 0.25em 0.25em #999;
    overflow:hidden;
 }
.box {
    position:relative;
    float:left;
    width:50%;
		padding:50% 0 0;
    background-color:#fff; 
    box-shadow:inset 0 0 1em #999;
    border:1px solid #999;
 }
.center {
    position:absolute;
    top:25%;
    left:25%;
    border-radius:10px;
    box-shadow:inset 0 0 1em #999, 0.25em 0.25em 0.25em #999; 
 }
.link {
    position:absolute;
    width:100%;
    text-align:center;
 }
.top { top:27%;
 }
.bottom {
    bottom:27%;
 }
.middle {
    top:42%;
 }
.link a {
    color:#999;
 }
</style>
</head>
<body>
<div id="container">
		<div class="box"><span class="link top"><a href="#">Concept 1</a></span> </div>
		<div class="box"><span class="link top"><a href="#">Concept 2</a></span> </div>
		<div class="box"><span class="link bottom"><a href="#">Concept 3</a></span> </div>
		<div class="box"><span class="link bottom"><a href="#">Concept 4</a></span> </div>
		<div class="box center"><span class="link middle"><a href="#">Concept 5</a></span> </div>
</div>
</body>
</html>

Remember that percentage padding is based on the width of the element so we still keep it a perfect square when resized.

5 Likes

I got Nerd Sniped so I went ahead and piggy backed on Mr. PaulOB’s solution and created this demo in CodePen:

How to make: Box on Boxes: http://codepen.io/ricardozea/pen/d3e790d6add8501a6c1fa48292105fc2/

I’m going to mention some of the differences in my solution, but I want to clarify that I am not trying to compete with PaulOB nor am I saying my solution is better. Is not. My solution is just another way of solving the same problem. If it wasn’t for PaulOB’s solution I wouldn’t have been able to come up with mine. So, thanks Mr. PaulOB :slight_smile:

Aight, here are the differences:

  1. It uses Flexbox rather than floats.
  2. It uses an unordered list as the structure.
  3. It doesn’t use any ‘magic numbers’ for positioning. 27% and 42% feel like magic numbers to me :blush:
  4. If the content is a link, the links are blocks so they expand the whole width and height of their parent container.
  5. If the content isn’t a link, all the author needs to do is take out the <a> and leave the content and the box on boxes will still display as intended.
  6. I’m using Sass, albeit relatively simple Sass, which means that if you don’t know Sass it may be a bit daunting to understand. However, you can always see the compiled CSS and copy it from there if need to.
  7. I’m using a “desktop-first” approach with the media query and I feel proud about it :smiley:
  8. I included PaulOB’s solution in the demo so we can see both solutions working side by side.
  9. Following the “wireframe” the center box is smaller.
  10. I love you all.

lol no worries :smile:

I should point out that this was actually coothead’s solution and I just took out the spacer gifs and used percentage padding instead :wink:

1 Like

I was too busy at work to answer earlier. but i wanted to suggest this:

<html>
	<head>
		<style type="text/css" media="screen">
			.out{
				border: 1px solid;
				padding: 0;
				margin: 0;
				list-style: none;
				width: 50%;
				position: relative
				
			}
			.out:after{
				content:'';
				display: inline-block;
				height: 0;
				width: 0;
				margin-top:100%;
 			}
 			.out >li {position: absolute; top:0; left:0 ; bottom:50%; right:50%; outline: 1px solid;  overflow:auto;}
 			.out >li:nth-child(2n){ left:50%; right:0; }
 			.out >li:nth-child(n+3){ top:50%; bottom:0;  }
 			.out > li:last-child{   top:25%; bottom:25%;  left:25%; right: 25%; border: 1px solid red; background: pink}
			
		</style>
		<title></title>
	</head>
	<body>
		
		
		<ul class="out">
			<li>item 1</li>
			<li>item 2</li>
			<li>item 3</li>
			<li>item 4</li>
			<li>item5:center</li>
		</ul>
	</body>
</html>

automatically creates a fluid, square (1:1) container and children, placing the last element in the center. This is probably quite similar to pauls solution except I chose to use absolute positioning for the sake of controlling height of child elements.

hope that helps

2 Likes

Yes, this solution looks way more succinct.

Added this solution to the demo with a small addition: Made the text fully centered in the boxes. However, the box in the center overlaps the content. I’m sure this is easy to fix, but I’m going to leave it as is :smile:

Link to CodePen demo: http://codepen.io/ricardozea/pen/d3e790d6add8501a6c1fa48292105fc2/

Ok, well, there you go. One solution inspired by the one before. This is what collaboration is all about.

Great demos everyone :smile:

And one more just for fun :smile:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
*, *:before, *:after {
	-moz-box-sizing:border-box;
	-webkit-box-sizing:border-box;
	box-sizing:border-box;  /* ie8+ */
}
html, body {
	height:100%;
	margin:0;
	padding:0;
	width:100%;
	display:table;
	text-align:center;
}
body {
	display:table-cell;
	vertical-align:middle;
}
.boxes {
	width:50%;
	margin:auto;
	padding:0;
	list-style:none;
	border:1px solid #000;
	position:relative;
	overflow:hidden;
}
.boxes li {
	float:left;
	width:50%;
	border:1px solid #000;
	text-align:center;
}
.boxes li:before {
	content:"";
	display:inline-block;
	vertical-align:middle;
	width:1px;
	margin:0 0 0 -1px;
	padding:100% 0 0;
}
.boxes li:last-child {
	position:absolute;
	left:27%;
	right:27%;
	top:27%;
	bottom:27%;
	width:auto;
	margin:auto;
	z-index:2;
	background:#fff;
	border:2px solid #000;
}
</style>
</head>

<body>
<ul class="boxes">
		<li>item 1</li>
		<li>item 2</li>
		<li>item 3</li>
		<li>item 4</li>
		<li>item 5</li>
</ul>
</body>
</html>

Maybe not necessary, as he does not want a lot of text in the boxes, but just as a challenge. How would you handle it with a paragraph of text in each box? I mean making it wrap around box 5, like I mentioned in post #4

So you are taking a transparent 1x1 pixel image and stretching it out to fit the entire box (?) but the user can’t see the distorted image?

Yes - that’s how pixel perfect layouts were created back in the days before CSS when HTML tables for layout were the only option. It was usually a transparent gif though rather than a png as those browsers didn’t support png images.

I like challenges :smile:

You’ll have to view it full screen to see the effect properly.

BTW this was just for fun :wink:

6 Likes

Awesomely efficient, Mr. Paul . Beautiful.

I finished a “proof of concept” a short while ago using some earlier code in this thread. Fortunately, yours was already up. Mine looks sooo ugly in comparison.

What a difference a fresh approach can make.

Thanks Ron :smile:

Well done. I knew you would do it.

Dude! This is awesome.

Nerd Snipped at its best :slight_smile:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.