tags:

views:

301

answers:

4

I'll start with an ASCII art illustration of what I want to achieve:

   Category title

  Title       Title
+-------+   +-------+
|       |   |       |
|       |   |       |
| Image |   | Image |
|       |   |       |
|       |   |       |
+-------+   +-------+
 Subtitle    Subtitle

   Category title

  Title       Title
+-------+   +-------+
|       |   |       |
|       |   |       |
| Image |   | Image |
|       |   |       |
|       |   |       |
+-------+   +-------+
 Subtitle    Subtitle

So I have these categories which contain items. Each item consists of a Title, a Subtitle and an Image. The images are of different sizes. Their widths are constant 150px, but heights range from 150px to 252px. And I cannot predict what sizes there will be in the future, although they should be somewhere around this size. You can assume that width is constant 150px, and height can vary between 150px and 300px.

The count categories and items in each category, of course, is arbitrary. Althought in each category there will be at least one item (otherwise I don't show the category). The lengths of titles and subtitles are also variable, although mostly they are pretty short.

The effect that I want to create is the following:

  • Item title and subtitle are rendered right next to the image (above and below) without any significant whitespace inbetween.
  • When the items in a category are too many, they start wrapping and create more rows. There is no horizontal scrolling. The rows should be clearly beneath each other. As the window width changes, the items rearrange themselves automatically.
  • If the item title or subtitle are a bit longer, they should wrap. They should not extend significantly beyond the image width;
  • The category header should have a clear whitespace between it and the item rows above and below.
  • Category title is centered in the page; Item titles and subtitles are centered relative to their images.

I don't care if the effect is achieved by TABLEs, DIVs or The Force. I just want it to look like that. :) Is this possible and if yes, how to do this?

If not, can anyone suggest an alternate layout which would encapsulate the same information and would look good on different browser sizes?

+1  A: 

UPDATE: This code works and is tested in Opera 9.51, FF 3.0 and IE7.

Do I get paid for doing this? ;)

There are many ways to achieve this. One thing is certain. You cannot have different heights. If you have different heights on your images, your divs will not align properly. Here is the HTML code:

<div id="outerContainer">
  <div class="container">
    <div class="categoryTitle">Category title here</div>    
    <div class="itemTitle">Square image </div>
    <div class="myImage"> <img class="myImage" src="http://upload.wikimedia.org/wikipedia/commons/thumb/archive/8/85/20060705145122!Smiley.svg/120px-Smiley.svg.png" /> </div> 
    <div class="subTitle">Subtitle here </div>
  </div>

  <div class="container">
    <div class="categoryTitle">Category title here</div>    
    <div class="itemTitle">High Image</div>
    <div class="myImage"> <img class="myImage" src="http://www.norwegianfashion.no/wp-content/uploads/fashion_shows/2009/Moods%20-%20feb/_SPS7281.jpg" /> </div> 
    <div class="subTitle">Subtitle here </div>
  </div>

  <div class="container">
    <div class="categoryTitle">Category title here</div>    
    <div class="itemTitle">High Image </div>
    <div class="myImage"> <img class="myImage" src="http://www.norwegianfashion.no/wp-content/uploads/Fashion_week/spring_09/regine_mowill/_SPS7094.jpg" /> </div> 
    <div class="subTitle">Subtitle here </div>
  </div>

  <div class="container">
    <div class="categoryTitle">Category title here</div>    
    <div class="itemTitle">Wide Image </div>
    <div class="myImage"> <img class="myImage" src="http://www.norwegianfashion.no/wp-content/uploads/Fashion_week/spring_09/pling/_SPS7181_copy.jpg" /> </div> 
    <div class="subTitle">Subtitle here </div>
  </div>   
</div>

The css:

#outerContainer {
  width: 350px;
  border: solid 1px #777;
  overflow: auto;
  text-align: center;
}

.categoryTitle {
  font-weight: bold;
}
.container {
  float: left; 
  border: solid 1px #ccc;
  height: 270px;
  width: 150px;
  margin: 10px 5px 10px 5px;
}

#outerContainer .myImage {
  max-height: 200px;
  max-width: 150px;
  height: expression(this.height > 200 ? 200 : true);
  width: expression(this.width > 150 ? 150 : true);    
}

.imgContainer {
  overflow: hide;
}
Steven
You could actually put the innerContainer in another wrapper with a fixed height to get around the dreaded "empty cell" effect, but if most of the items take up less than the entire height, the effect will be a lot of extra vertical whitespace (if your max height is 300px and the average height is closer to 150px, that'd mean you'd mostly have almost an entire empty row in between the items).
Alan
You can have different heights as long as the browser(s) you are targeting support inline-block display mode. Remove the float left from .innerContainer and give it a vertical-align:top and it will have the same effect as floating without the nasty wrap issues.
Joel Potter
inline-block isn't cross-browser friendly. For FF2 you need -moz-inline-box, for IE the element has to be naturally an inline element like SPAN instead of DIV (a div will ignore the property). Then, of course, ditch the float left.
rpflo
Alan: Yes, that is the drawback of of this method and is clearly demonstratd in my exmple. Some divs have lot of white space, others has no whitespace. But if you remove fixed width of the container, the conatiner will float very oddly. One solution is to have max-width on images, and a fixed height on the div that raps the image. Then you set overflow: hidden on this div.
Steven
Joel: vertical-align:top will only stack images below each other. It does not simualte float:left
Steven
rpflo: Yes, you are correct. My pseudocode mistake :)
Steven
+1  A: 

Steven beat me, but I'll charge a little more ;-). Here's the markup for a quick solution that matches your requirements (CSS should be a in a separate file). Open issues:

  • Cross-browser? Try forcing browsers into strict mode to have to deal with only one box model (especially important on IE6)
  • As Steven pointed out, image height will have to be fixed (or container height), but the bigger problem is your requirement to wrap longer titles. The markup and CSS I provided don't deal with that well, but getting this to work right means you have to decide on a max height for the titles or drop your requirement to automatically wrap items (so that we can use a table). I suggest to instead put everything underneath the images, with a fixed container height.

markup and CSS:

<style type="text/css">

 h3.category { clear: both; }
 div.item { float: left; width: 83px; margin-right: 20px; }
 div.item img { width: 83px; height: 125px; }
 div.item h4 { margin-bottom: 3px; }
    div.item h5 { margin-top: 3px; }

</style>

<h3 class="category">Category <strong>title</strong></h3>

<div class="item">
 <h4>Title</h4>
 <img src="http://www.freefoto.com/images/15/19/15_19_54_thumb.jpg" title="tree" />
 <h5>Subtitle</h5>
</div>

<div class="item">
    <h4>Longer Title</h4>
    <img src="http://www.freefoto.com/images/15/19/15_19_54_thumb.jpg" title="tree" />
    <h5>Longer Subtitle</h5>
</div>

<div class="item">
    <h4>Very Long, Wrapping Title</h4>
    <img src="http://www.freefoto.com/images/15/19/15_19_54_thumb.jpg" title="tree" />
    <h5>Very Long, Wrapping Subtitle</h5>
</div>

<div class="item">
    <h4>Title</h4>
    <img src="http://www.freefoto.com/images/15/19/15_19_54_thumb.jpg" title="tree" />
    <h5>Subtitle</h5>
</div>

<h3 class="category">Category <strong>title</strong></h3>

<div class="item">
    <h4>Very Long, Wrapping Title</h4>
    <img src="http://www.freefoto.com/images/15/19/15_19_54_thumb.jpg" title="tree" />
    <h5>Very Long, Wrapping Subtitle</h5>
</div>

<div class="item">
    <h4>Longer Title</h4>
    <img src="http://www.freefoto.com/images/15/19/15_19_54_thumb.jpg" title="tree" />
    <h5>Longer Subtitle</h5>
</div>

<div class="item">
    <h4>Title</h4>
    <img src="http://www.freefoto.com/images/15/19/15_19_54_thumb.jpg" title="tree" />
    <h5>Subtitle</h5>
</div>
Thomas Jung
A: 

Props to rpflo for the span comment. This works in ie7/8, ff3 and chrome/safari.

<div class="cat">
  <h2>Category 1</h2>
  <span class="img">
    <h3>Title 1 with a long title wider than 150px</h3>
    <img src="yourimage.png" />
    <h4>Subtitle 1</h4>
  </span>
</div>

And the CSS:

div.cat { 
  overflow:auto;
  margin-bottom:15px; 
}
div.cat span.img { 
  display:inline-block;
  vertical-align:top; 
  width:150px;
  margin-right:15px;
  text-align:center; 
}
div.cat span.img h3, div.cat span.img h4 { 
  margin:0; 
}
Joel Potter
If outer container is 350px wide, this solution will only stack images below each other.
Steven
@Steven: Simply reduce the margin on the img span to make two images fit side by side.
Joel Potter
A: 

Hi,

i think the easiest way for this kind of layout is to use a css framework. Best choice for simple grid layouts is http://960.gs/

Easy to use, and no problems with browser compatibility.

ArneRie