Basic Float Help

I can use css to apply colors, borders and fonts with the best of them. Selectors? No problem. But I still can’t get my head around basic floats.

For a banner I want an image all the way to the left and another all the way to the right with a div in between for some content. Trivial right?

This works:


<header id="banner">
  <img                              src="NatlGames_Logo_2012_sm.jpg" height="50" width="50" alt="Logo Left"/>
  <img style="float: right; src="NatlGames_Logo_2012_sm.jpg" height="50" width="50" alt="Logo Right"/>
  <div 
    style="position: absolute; left: 60px; top: 5px; color: red; background-color: LightBlue;"
  >Header Line 1<br />Header Line 2</div>
</header>

And even validates. But it uses absolute positioning of the div which is fine but it just seems like I should be able to float the division next to the left image and then the float the right image after it.

What am I missing?

HI,

Just float the images left and right respectively and then use overflow:hidden on the content to form a rectangular block in the middle.

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=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
img {
    display:block;
    border:none
}
#header {
    width:100%;
    background:#fcf;
    overflow:hidden;/* contain floats*/
    padding:5px 0;
    min-width:320px;
}
#header img{background:red;}
#header h1 {
    margin:0 0 1em;
    text-align:center;
    font-size:140%;
}
#header p {
    margin:0 0 1em
}
.logo1 {
    float:left;
    margin:0;
}
.logo2 {
    float:right;
    margin:0;
}
.inner {
    overflow:hidden;/* make a rectangular block between floats */
    zoom:1.0;/* same effect for IE7 and under*/
    padding:10px;
    color: red;
    background:LightBlue;
}
</style>
</head>
<body>
<div id="header">
    <p class="logo1"><img src="NatlGames_Logo_2012_sm.jpg" height="50" width="50" alt="Logo Left"/></p>
    <p class="logo2"><img src="NatlGames_Logo_2012_sm.jpg" height="50" width="50" alt="Logo Right"/></p>
    <div class="inner">
        <h1>Heading here</h1>
        <p>heading content here heading content here heading content here heading content here heading content here heading content here  </p>
    </div>
</div>
</body>
</html>


Thanks. So much magic. I read the docs over and over but still makes little sense.

Question: Why did you wrap the img element in p’s? Just to inherit the styling or is there some deeper reason? Putting the class directly in the img seems to work.

Images are inline elements and it is bad practrice to run them straight into a block element. Everything should be at the right level. It’s not invalid to have the images by themselves but its not semantic either and indeed will cause whitespace bugs (and more) in IE.

Not wrapping an image in a block element is akin to doing something like this.


<div>
  [B]hello[/B]
  <div>
    <p>hello again</p>
   </div>
</div>

The first hello is just hanging in mid air in no structure. It is however still valid but looks odd and not semantically correct. The browser will automatically construct an anonymous block box so that it will see it as:


<div>
  [B]<div>hello</div>[/B]
  <div>
    <p>hello again</p>
   </div>
</div>

In your example if there was a not a div next to the image then you wouldn’t have needed another wrapper for the image because all that parent div contained would have been inlline elements and so everything is fine at the same level.

Just don’t mix inline elements and block elements at the same level - make sure block boxes adjoin block boxes and inline elements are contained within the block boxes. It’s not invalid to mix them but not semantically correct and does often trip IE up.

Excellent. Only apply block operators to blocks. Makes sense.

New question: background:LightBlue;
I guess the latest css defines a bunch more named colors. Naturally IE8 doesn’t support them.

Does css have some ability for mapping color names to actual value? Some sort of macro replacement thing? No javascript please.

I actually run my css through a server side script to accomplish this. But always wondered if there was a better solution.

IE8 supports LightBlue ok and so does ie6 and 7 in my tests. I always use hex anyway (apart from occasionally using the basic standard color keywords).

Does css have some ability for mapping color names to actual value? Some sort of macro replacement thing? No javascript please.

I actually run my css through a server side script to accomplish this. But always wondered if there was a better solution.

No scripting is the only option but there are a number of tools around to make life easier but I don’t use them personally. I find them harder to use than just using basic css.

Does css have some ability for mapping color names to actual value? Some sort of macro replacement thing? No javascript please.

Well if you’re looking at code of a live site in a browser, and you see a #colour and wonder what colour it is, debugging tools like Firebug often will show you the colour if you can hover the mouse over that part of the code.

I use the Gimp… it’s almost always open on my machine anyway, so I just type the colour in there to see what I get… also when I have to convert to rgb.

Thanks. So much magic. I read the docs over and over but still makes little sense.

It’s good to read the specs but it’s also normal that they don’t make sense.

The overflow thing is actually rather brilliant. I don’t know if Paul knew this back when he found that overflow-other-than-auto worked, but apparently when a static container is told it has to deal with any possible overflowing children, the rules change and it’s able to “see” its floated children… else, how could it deal with overflow if it doesn’t know what’s overflowing?

And once it “sees” these children, it encloses them the way it would any non-floated children.

Okay, so it’s magic. But all magic has rules, and all we have to do to become wizards is learn the rules.

Or, as someone said, when technology is sufficiently complex or advanced, it is pretty much indistinguishable from magic anyway.

Here’s a tip for when you’re dealing with floats: give each float and any other involved boxes ugly background colours. If a box doesn’t appear, give it a border (usually you’ll see the border if it’s collapsed to zero-height). This helps you debug them better because then you can see (mostly) what’s going on.

Originally I was using it because it worked to contain floats but without a full understanding of block formatting contexts which is the real key. I also knew that floats and absolute elements contained child floats but never tied it to the real concept until later on.

I was also using the overflow:hidden trick to create rectangular blocks between floats without using margins a long long time ago and was often told this was a trick (just like the float containment) but it turns out I was right and all the doom sayers were wrong. Mind you overflow was a bit buggy back then so there may have been a case for avoiding it. Browsers have improved their behaviour of overflow and is now very stable (apart from when you add margins to an element that has overflow:hidden in safari and is between floats).

Ok, need some more majic. Same problem, two image on either side of the screen with a div for content in the middle. But this time use css table/row/cell to solve and html 4.01. Got it working in Chrome and IE8 but have a problem with firefox.

The html:



    <div id="layout-header-table">
      <div id="layout-header-row">
        <p class="layout-header-logo-cell" >
          <img src="NatlGames_Logo_2012_sm.jpg" height="50" width="50" alt="Logo Left"  >
        </p>
        <div id="layout-header-center-cell">
          <p id="layout-header-center-cell-top"   >Header Line Along the Top</p>
          <p id="layout-header-center-cell-bottom">Header Line Along the Bottom</p>
        </div>
        <p class="layout-header-logo-cell">
          <img src="NatlGames_Logo_2012_sm.jpg" height="50" width="50" alt="Logo Right" >
        </p>
      </div>
    </div>

And the css


/* margin = padding = border reset to 0 for all applicable elements */

img
{ 
  display: block;
  border:  none;
}

body {
  background-color: LightGreen;
}
#layout-header-table
{
  display:    table;
  width:      100%;
  background: red;
}
#layout-header-row
{
  display: table-row;
}
.layout-header-logo-cell
{
  display: table-cell;
}
#layout-header-center-cell
{
  display: table-cell;
  background-color: LightBlue;

  width:   100%;  /* To expand the center node */
  
  vertical-align: top; /* Key to getting the content pushed up */

  position: relative; /* To allow positioning text along bottom of division */
  
  margin:       0;
  padding-left: 5px;
  padding-top:  3px;
}
#layout-header-center-cell-top
{
  font-size: 1.2em;  /* Make text a bit bigger */
}
#layout-header-center-cell-bottom
{
  position: absolute;  /* Position along bottom of cell */
  bottom:   0px;       /* Firefox 3.6 goes to bottom of screen */
}

w3c validator says it is fine.

Everything works except I’d like to have the second row of text in the center division to be along the bottom of the division. Using absolute position inside of a relative division. Works fine in IE8 and Chrome but for Firefox 3.6 the bottom line comes out on the bottom of the screen.

Usually IE8 is the problem child but I see from googling that Firefox had some position issues. My Nook Color (Android OS) also renders the line at the bottom.

I know I could fake it by using a bit of padding the push the row down but would just as soon do it the right way.

The page is here: http://zayso.org/ngames/

Hi,

That’s a bit of a monstrosity :slight_smile: What happened to the succinct code I gave you?

Didplay:table doesn’t work in IE7 and under so you can’t really use it yet unless you are going to offer alternative code for ie7 and under.

Absolute positioning is unreliable where tables are concerned anyway and you probably should have created a two row css table in the middle with the content in the bottom row aligned to the bottom. As it is your content overlaps should the top line wrap so what you are asking for isn’t a workable idea anyway.

You also have much too much code and ids that are much too long and unmanageable and too descriptive to be useful. You have about 40 characters of actual content and about 600 characters of mark up!!

I would so it more simply like this with a 70% reduction in css and html.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type"     content="text/html; charset=utf-8" >
<meta http-equiv="Content-Language" content="en" >
<title>Master Index</title>
<style type="text/css">
/* ============================================
 * Your basic reset
 */
html, body, div, span, h1, h2, h3, h4, h5, h6, p, a, img, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
img {
    display: block;
    border:  none;
}
body {background-color: LightGreen;}
#header {
    background:#add8e6;
    padding:0 55px;
    position:relative;
    zoom:1.0;
    min-height:50px;
}
* html #header {height:50px}
#header h1 {
    font-size:1.2em;
    line-height:20px;
    padding:0 0 10px;
}
#header h1 img{
    position:absolute;
    left:0;
    top:0;
}
#header p{line-height:20px;}
#header p img{
    position:absolute;
    right:0;
    top:0;
}
#main {clear:both;}
</style>
</head>
<body>
<div id="header">
    <h1><img src="http://zayso.org/ngames/NatlGames_Logo_2012_sm.jpg" height="50" width="50" alt="Logo Left">Header along the top Header along the topHeader along the top </h1>
    <p>Header Line Along the Bottom<img src="http://zayso.org/ngames/NatlGames_Logo_2012_sm.jpg" height="50" width="50" alt="Logo Right" ></p>
</div>
<div id="main">
    <h2>Main content</h2>
</div>
</body>
</html>


I would even remove those images to the background as they look more like decoration than logos as such.

The text on the bottom line is in the flow rather than absolute and should the top line wrap then the text will move down as appropriate and not overlap as in your example.

Firefox has always been derp-derp about positioning stuff inside tables… this carries on to display: table too I think.

Earlier I said

I don’t know if Paul knew this back when he found that overflow-other-than-auto worked,

That should be
overflow-other-than-visible
whoops.