Aligning my thumbnails in CSS

I’m trying to align 50x50px linked image thumbnails next to each others in a 600px container. I want to have 4 thumbnails in each row.

My HTML code right now is something like this:

<div class="thumbnails">
   <a href="page.html"><img src="image.jpg" alt="thumbnail"></a>
   <a href="page.html"><img src="image.jpg" alt="thumbnail"></a>
   <a href="page.html"><img src="image.jpg" alt="thumbnail"></a>
   <a href="page.html"><img src="image.jpg" alt="thumbnail"></a>
   <a href="page.html"><img src="image.jpg" alt="thumbnail"></a>
</div>

I assigned a 10px margin-right to have some space between thumbnails, but when I added margin-bottom to them it had no effect.

I have two questions here:

  1. How do I control the margin around thumbnails? it seems to accept only left/right margins.

  2. How do I change the border around the image for each link state? (hover/visited/active)

Your help is appreciated :slight_smile:

Hi,

Vertical margins don’t apply to inline elements so you will need to float the images across the screen.

Something roughly like this.


<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<style type="text/css">
a img{border:none;}
ul.thumbnails{
    margin:20px;
    padding:0;
    width:600px;
    float:left;
    clear:both;
    list-style:none;
    border:1px solid #000;
    padding:10px;
}
ul.thumbnails li{
    float:left;
    width:52px;
    height:52px;
    margin:10px 49px;
    display:inline;
}
ul.thumbnails a{
    float:left;
    width:50px;
    height:50px;
    border:1px solid #000;
    text-decoration:none;
}
ul.thumbnails a:visited{border:1px solid blue}
ul.thumbnails a:hover{border:1px solid red}
ul.thumbnails a:active{border:1px solid green}



</style>
</head>
<body>
<ul class="thumbnails">
    <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
</ul>
</body>
</html>


Hope that was what you were looking for.

Thanks a lot Paul.

I tried to use your method in my layout, but it broke it. I have no idea why. Here’s the code:

<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Sample</title>
<style type="text/css">
#container {
width: 600px;
margin: 0 auto;
border: 1px solid #333333;
}

ul.thumbnails {
list-style: none;
float: left;
clear: both;
}

ul.thumbnails li {
width: 52px; height: 52px;
margin: 10px 10px;
float: left;
display: inline;
}

ul.thumbnails a {
width: 50px; height: 50px;
text-decoration: none;
float: left;
}

ul.thumbnails a:visited{border:1px solid blue}
ul.thumbnails a:hover{border:1px solid red}
ul.thumbnails a:active{border:1px solid green}


#box {
width: 500px; height: 100px;
margin: 10px;
background: beige;
}

</style>
</head>
<body>

<div id="container">
  <ul class="thumbnails">
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
  </ul>

<div id="box"></div>
</div>
</body>
</html>

Notice that it has three major issues:

  1. The hover effect isn’t working properly.
  2. Thumbnails aren’t organized properly (margins issue)
  3. The list of thumbnails go over the box after them. (hopefully I won’t have to usee an extra “clearer” div)

Did I implement your solution incorrectly?

Hi,

You seem to have removed the margins that spaced the thumbnails out which is why they aren’t spaced out correctly. You also didn’t address the default padding on the list and I’m not really sure what you were trying to do with #box either :slight_smile:

I’m guessing this is what you wanted.


<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Sample</title>
<style type="text/css">
a img{border:none;}
#container {
width: 600px;
margin: 0 auto;
border: 1px solid #333333;
overflow:auto;
}

ul.thumbnails {
list-style: none;
float: left;
clear: both;
background: #f5f5dc;
width:580px;
margin:10px;
display:inline;
padding:0 0 10px;
}

ul.thumbnails li {
width: 52px; 
height: 52px;
margin: 10px 46px 0;
float: left;
display: inline;
}

ul.thumbnails a {
width: 50px; 
height: 50px;
text-decoration: none;
float: left;
border:1px solid #f5f5dc;
}
ul.thumbnails a:visited{border:1px solid blue}
ul.thumbnails a:hover{border:1px solid red}
ul.thumbnails a:active{border:1px solid green}

</style>
</head>
<body>
<div id="container">
    <ul class="thumbnails">
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    </ul>
</div>
</body>
</html>


Hope it helps anyway :slight_smile:

Thanks Paul.

The reason I’ve put the box is to show you that anything beneath the thumbnails would go under it since the elements of the list are float to the left.

If I put a <div style=“clear:both”></div>, that will be fixed, but I’d like to keep my code as semantic as possible.

Any way around that?

No extra div is needed, just add clear in the ruleset for the first div that follows in the html. Then that div and all after will go below.

The problem is that those thumbnails would be anywhere in the contents, so I can’t predict which element will follow it. It could be a list, a paragraph, a heading, or any other element. I don’t think it’s practical to add “clear” to all elements. :slight_smile:

You can remove the float from the ul so it stay a static block, and all things after goes below.


ul.thumbnails {
overflow:hidden;
list-style: none;
}

Still the same issue. Try modifying my code above and you’ll see what I mean.

There should be no problem in doing as Erik suggested.


<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Sample</title>
<style type="text/css">
a img{border:none;}
#container {
width: 600px;
margin: 0 auto;
border: 1px solid #333333;
}

ul.thumbnails {
list-style: none;
background: #f5f5dc;
width:580px;
margin:10px;
overflow:hidden;
padding:0 0 10px;
}

ul.thumbnails li {
width: 52px; 
height: 52px;
margin: 10px 46px 0;
float: left;
display: inline;
}

ul.thumbnails a {
width: 50px; 
height: 50px;
text-decoration: none;
float: left;
border:1px solid #f5f5dc;
}
ul.thumbnails a:visited{border:1px solid blue}
ul.thumbnails a:hover{border:1px solid red}
ul.thumbnails a:active{border:1px solid green}

#box {
width: 500px; height: 100px;
margin: 10px;
background: beige;
}

</style>
</head>
<body>
<div id="container">
    <ul class="thumbnails">
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
    </ul>
    <div id="box"></div>
</div>
</body>
</html>


The element can follow underneath with no problems :slight_smile:

Now I have tried; to test the function I also made the container fluid. Seems to work. :slight_smile:

<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Sample</title>
<style type="text/css">

#container {
width: 60&#37;;
margin: 0 auto;
border: 1px solid #333333;
}
ul.thumbnails {
overflow:hidden;
list-style: none;
}
ul.thumbnails li {
width: 52px; height: 52px;
margin: 10px 10px;
float: left;
display: inline;
}
ul.thumbnails a {
width: 50px; height: 50px;
text-decoration: none;
float: left;
}
ul.thumbnails a:visited{border:1px solid blue}
ul.thumbnails a:hover{border:1px solid red}
ul.thumbnails a:active{border:1px solid green}
#box {
height: 100px;
margin: 10px;
background: khaki;
}
</style>
</head>
<body>
<div id="container">
  <ul class="thumbnails">
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
      <li><a href="page.html"><img src="image.jpg" width="50" height="50" alt="thumbnail" /></a></li>
  </ul>
<div id="box"></div>
</div>
</body>
</html>

Edit) Sorry, didn’t see your post Paul. :slight_smile:

No problems and thanks for jumping in as I’ve been busy today and haven’t had much time :slight_smile:

Just trying to give SitePoint some in return for what I learn here. :smiley:

Thanks a lot erik.j and Paul. I really appreciate your patience and efforts. :slight_smile:

Two more questions though just so I can understand the code instead of just using it:

  1. How does ‘overflow: hidden’ fix the float issue in the code? (remove it to know what I’m talking about)

  2. Logically, why should float links as well if they’re contained within an already floated element?

Here’s the final code again for your reference:

<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Sample</title>
<style type="text/css">
a img{border:none;}
#container {
width: 600px;
margin: 0 auto;
border: 1px solid #333333;
}

ul.thumbnails {
list-style: none;
background: #f5f5dc;
width:580px;
margin:10px;
overflow:hidden;
padding:0 0 10px;
}

ul.thumbnails li {
width: 90px; 
height: 90px;
margin:9px 12px;
float: left;
display: inline;
}

ul.thumbnails a {
width: 90px; 
height: 90px;
text-decoration: none;
float: left;
border:1px solid black;
background-color: white;
padding: 2px;
}
ul.thumbnails a:visited{border:1px solid blue}
ul.thumbnails a:hover{border:1px solid red}
ul.thumbnails a:active{border:1px solid green}

#box {
width: 500px; height: 100px;
margin: 10px;
background: beige;
}

</style>
</head>
<body>
<div id="container">
    <ul class="thumbnails">
        <li><a href="page.html"><img src="image.jpg" width="90" height="90" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="90" height="90" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="90" height="90" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="90" height="90" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="90" height="90" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="90" height="90" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="90" height="90" alt="thumbnail" /></a></li>
        <li><a href="page.html"><img src="image.jpg" width="90" height="90" alt="thumbnail" /></a></li>
    </ul>
    <div id="box"></div>
</div>
</body>
</html>

Overflow: hidden is a sort of voodoo magic that just works. If that container had had a set height, the extra content would have first tried to overflow, but then would be hidden : ) However, there is no set height (a good thing) so the container tries to wrap around all its children (the floats) instead of hiding them. Apparenlty, “hidden” only only refers to hiding content when the browser knows where to start hiding it.

I kinda don’t get the second question, a grammar thing… do you mean, why do you have to float the links (the <a>'s) when they’re already in a floating container?

Because otherwise, the <a>s would be back to inline, meaning you’d have that same original problem with the setting of margins on the bottom. A floated thing automagically becomes a block thing, and so as such you get all these goodies/benefits that come with being a block, like being able to set a height and width (images are the exception, as well as “area” I think in an image map), and top/bottom margins. But if you had set the <a>s to display: block, they’d all sit underneath each other, forming a column. Float gives you the benefit of block, but lets you stack from side to side like inlines.

Hi,

To clarify a little about overflow :slight_smile:

Overflow (other than visible) will cause a parent to take note of so called invisible content which means that it will recognize that it has floated children and therefore enclose them within its grasp. This is the same behavior that IE6 will observe when the element is in “haslayout” mode and one of the reasons that people thought IE cleared floats automatically.

Using overflow to clear floats works well in simple situations but can cause problems in some complicated layouts. In complicated cases I would prefer using the ‘PIE clearfix method’ of adding content after the float using the pseudo class ‘:after’ which means no extra mark up is required in the html. See the FAQ on floats for more info on this.

IE has problems with lists and whitespace and if you float the list it’s also better to float the anchor as well and the layout becomes more solid. As mentioned in the post above you need to make the anchor block level anyway if you want it fully clickable so you may as well float it which does just that and fixes whitespace issues at the same time.

What site is this for? I want to see for my own reference.

Stomme poes and Paul: Thanks a ton for your explanations. I understood it clearly now. :slight_smile:

Alonski, I’m afraid I can’t show you the site, because I’m still designing it locally in my computer. :slight_smile: