6 Replies - 1668 Views - Last Post: 02 November 2011 - 12:32 AM

#1 johnki  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 31-October 11

Background flowing across several <div>s

Posted 01 November 2011 - 07:45 PM

Right now, I'm overhauling my site, putting the effort in to make it look...at least decent. :)

As it is now, I've got little experience actually working with anything more than basic HTML when it comes to web scripting.

So what I've got is something like this:

<div id="container" style="color:#FFD700;width:1000px;background-image:url('background.jpg');">
   <div id="header" style="color:#FFD700;width:1000px;background-image:url('background.jpg');">
      Some stuff...
   </div>
   <div id="menu" style="height:350px;width:200px;float:left;background-image:url('background.jpg');">
      Some stuff...
   </div>
   More divs...
</div>




In the end, it looks something like...

MMMMMMMMMMMMMMMMMMM (header)
MMMMMIMMMMMMMIMMMMM (menu, content, login)
MMMMMIMMMMMMMIMMMMM (menu, content, shoutbox)
      MMMMMMM       (content)


With M's being where the divs show, and the I's being some sort of odd div-change representation.

Obviously, this doesn't give a good effect, and, in fact, it makes the whole thing look like some odd sort of checkered pattern.

I HAD originally had only the first div, the "container" have the background image, but it only showed up in the "header" div, as opposed to flowing across all of them.

The image itself is more than large enough to cover all of the divs. Is there a way to make it flow across all of them?

Thanks in advance!

Is This A Good Question/Topic? 0
  • +

Replies To: Background flowing across several <div>s

#2 Atli  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 3730
  • View blog
  • Posts: 6,017
  • Joined: 08-June 10

Re: Background flowing across several <div>s

Posted 01 November 2011 - 08:28 PM

Hey.

I'm guessing the problem with the background image is that all the divs, except the header, are floated. When you float an element you are taking it out of the "normal" flow of the site, which means that they flow right out of their parent element if you don't make it large enough to cover them.

To fix this you either need to know how high the divs are going to be and set the "height" style on the parent, or you need to add a non-floated block element after all the floated elements with the "clear" style set. For a dynamically sized layout you'd have to use the second method. It essentially restores the "normal" flow inside the parent element before it closes, making the browser adjust the parent's high to cover this new non-floated element, which in turn makes it cover all the floated elements as well.

There are two ways to do this:

  • Add an actual element to the HTML. This is the safe choice, as old IE versions can't render the CSS required for the other method. Basically, you do:
    <style type="text/css">
    #container {
        background-image: url(background.jpg);
    }
    .floated {
        float: left;
    }
    .clear_float {
        clear: both;
    }
    </style>
    <div id="container">
        <div class="floated">Stuff...</div>
        <div class="floated">Stuff...</div>
        <div class="floated">Stuff...</div>
        <div class="clear_float"></div>
    </div>
    
    


  • Use CSS to add an element after the other elements in the container. This only works in standards supporting browsers (Firefox, Safari/Chrome, Opera) and IE8+.
    #container:after {
        content: ".";
        clear: both;
        display: block;
        visibility: hidden;
        height: 0px;
    }
    
    

    This adds a block element as the last element inside "container", but it then hides it so it won't be visible to users. Regardless of that, this will cause the browser to expand the parent element to cover it's position.

Was This Post Helpful? 2
  • +
  • -

#3 johnki  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 31-October 11

Re: Background flowing across several <div>s

Posted 01 November 2011 - 08:40 PM

Yeah, they are floated, through the use of style="float:left;".

Thanks. :)

I'm suspecting I'll have to end up positioning them all separately, though. Trying the second method, it sort-of works. Of what's visible to me, it shows up fine for the header and the shoutbox, and I'm suspecting it only works for the shoutbox because it doesn't have an actual shoutbox element yet.

However, the content and login boxes are showing up as the background color and I suspect the menu is showing up that way, as well, though that one isn't as concerning because it's covered by menu buttons that cover all empty space.

I might as well ask, I've tried messing with CSS positioning before, but it came out really skewed and all over the place, using the top and left attributes I tried relative, absolute, etc, but my objectss went everywhere. Would I benefit from using margin-top and margin-left instead?
Was This Post Helpful? 0
  • +
  • -

#4 johnki  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 31-October 11

Re: Background flowing across several <div>s

Posted 01 November 2011 - 09:52 PM

(Is there an Edit button?)

So, I changed the CSS's tag from script to style and it works a lot better. However, it covers the entire container div, which I probably should have expected. :P

Is there any way to not get it to cover the two bottom corners of the container div, and rather only cover where other divs are also present, but cover in the same uniform manner?
Was This Post Helpful? 0
  • +
  • -

#5 Atli  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 3730
  • View blog
  • Posts: 6,017
  • Joined: 08-June 10

Re: Background flowing across several <div>s

Posted 01 November 2011 - 11:17 PM

View Postjohnki, on 02 November 2011 - 04:52 AM, said:

Is there any way to not get it to cover the two bottom corners of the container div, and rather only cover where other divs are also present, but cover in the same uniform manner?

What immediately sprung to mind was absolutely positioning the elements and setting the position of the background on each element accordingly. I've used that method before a number of times, and while it's a little less "dynamic" than using floats, that's usually not a problem when you have a fixed size layout.

(See the example below.)

View Postjohnki, on 02 November 2011 - 03:40 AM, said:

I might as well ask, I've tried messing with CSS positioning before, but it came out really skewed and all over the place, using the top and left attributes I tried relative, absolute, etc, but my objectss went everywhere. Would I benefit from using margin-top and margin-left instead?

There is a big difference between using absolute positioning and using margins. Margins are used to offset the position of elements while still maintaining the normal flow of the elements, whereas absolute positioning takes elements out of the flow altogether and positions them manually. - That is not to say you can't use margins with absolutely positioned elements. In fact, it can be quite useful to use both at times.

Basically, there are four ways to position your elements:

  • Static. The default position, where the element is positioned relative to the other elements using the normal box model. Here you can use margins to offset the element's position. Unlike the top, left, bottom and right styles on relative and absolutely positioned elements, the margin styles on static elements affect the positions of the elements around them.

  • Relative. Very much like static positioning, with two differences.

    First, you can use the "left", "right", "top" and "bottom" styles to offset the position of the element without it affecting the normal flow. That is, the element is rendered in a different position but every element around it is still positioned as if it was still in it's original position.

    Second, and arguably more useful, is that absolutely positioned elements within relatively positioned elements will refer to the position and size of the parent element when calculating their positions, using the top, left, bottom and right values of the parent as the 0 values for those same styles. This means that you can use absolute positioning within relative elements to position child elements only within that container.

  • Aboslute. This removes the element from the normal flow completely, positioning it as defined by the top, left, bottom and right styles. By default those values refer to the borders of the whole page, but as I explained above that changes when they have relatively positioned parents, in which case they refer to the borders of that parent element.

  • Fixed. Like absolute positioning except that this fixes the element to the borders of the browser window rather than the page. Meaning that if you fix an element to the bottom of the window by doing bottom: 0px;, it will stay visible at the bottom of the window even while the page is scrolled around.


So, you could set your "container" to be positioned relatively but without offseting it's position. That would let you center it using margins, which is what I assume you want? This would also let you absolutely position the other elements within it to put them in the place you want, and to set the background on each of them and offset it's position to make it appear as if the background is actually covering all the elements continuously, while not covering the whole area behind them.

For example, consider if you had this HTML:
<DOCTYPE html>
<html>
<head>
	<title>Example</title>
	<meta charset="UTF-8"/>
	<link rel="stylesheet" type="text/css" href="test.css">
</head>
<body>
	<div id="container">
	
		<div id="header">
			<h1>Site name.</h1>
		</div>
		
		<ul id="menu">
			<li><a href="/">Home</a></li>
			<li><a href="/about/">About</a></li>
		</ul>
		
		<form id="login">
			<!-- Etc... -->
		</form>
		
		<div id="shoutbox">
			<!-- Whatever that is... -->
		</div>
		
		<div id="contents">
			<!-- Your contents here... -->
		</div>

	</div>
</body>
</html>



You could use these (heavy over-commented :)) styles to create the layout your first post indicated:
/* Best not to let the browsers decide the margins and
 * paddings for use. They tend not to agree on how to
 * set these for different elements. 
 * This sets them to 0 for all elements. */
* {
	margin: 0;
	padding: 0;
}

#container {
	/* So we can position the other elements relative
	 * to the container. */
	position: relative;
	
	/* Sets the width and centers it. */
	width: 1000px;
	margin: 10px auto;
}

#header {
	/* This will position the header to cover the top
	 * 50px of the container element. */
	position: absolute;
	top: 0px;
	left: 0px;
	right: 0px;
	height: 50px;
	
	/* And this will set the background to show for
	 * those 50 pixels. */
	background: url(background.jpg) 0px 0px;
}

#menu {
	/* Remove the dot from the list elements */
	list-style: none;
	
	/* Position this  200px wide and 350px high,
	 * starting 55px from the top-left side of
	 * the contiainer. */
	position: absolute;
	top: 55px;
	left: 0px;
	width: 200px;
	height: 350px;
	
	/* Set the background to that same area. */
	background: url(background.jpg) 0px -55px;
}

#contents {
	/* Position this 590px wide without a set height,
	 * 55px from the top and 205px from the left.
	 * The lack of a height will allow this to grow
	 * with it's contents so the browser will scroll
	 * normally.
	 */
	position: absolute;
	top: 55px;
	left: 205px;
	width: 590px;
	
	/* Set a minimum height, in case the contents of
	 * the element are missing or to low. */
	min-height: 500px;
	
	/* Set the background so that it's position will
	 * start at the corrent spot to match the other
	 * elements, but let it repeat down if the contents
	 * expand beyond the size of the image. */
	background: url(background.jpg) -210px -55px  repeat-y;
}

#login {
	/* Position this like the others, except this time set the
	 * "right" style instead of "left", positioning it relative
	 * to the right side of the container. */
	position: absolute;
	top: 55px;
	right: 0px;
	width: 200px;
	height: 150px;
	
	background: url(background.jpg) -800px -55px;
}

#shoutbox {
	/* Place this below the login box. Note that this only works
     * if the login box has a fixed height. Otherwise there would 
	 * be no way to position these two below each other without a
	 * much more complex layout, and setting the background position 
	 * would be even more complex. */
	position: absolute;
	top: 210px;
	right: 0px;
	width: 200px;
	height: 150px;
	
	background: url(background.jpg) -800px -210px;
}


Which will give you something like this:

Attached Image

The main "contents" area has a flexible height so it can expand as far down as the contents require, and you could do the same with the menu. The "login" and "shoutbox" areas on the right, however, have a fixed height, and each box you add to that side must also have a fixed height so you can position them correctly.
Was This Post Helpful? 2
  • +
  • -

#6 johnki  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 31-October 11

Re: Background flowing across several <div>s

Posted 02 November 2011 - 12:10 AM

Looking at the picture, yeah, that's a lot closer to what I was looking for.

I'll mess around with it and see if I can't get optimal results. :)
Was This Post Helpful? 0
  • +
  • -

#7 johnki  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 31-October 11

Re: Background flowing across several <div>s

Posted 02 November 2011 - 12:32 AM

(Bleh missing edit button)

Thanks a ton! With some minor edits, that did exactly what I wanted it to, and on top of that, gave me a better idea of how to use CSS. The content actually doesn't seem to want to extend downwards, but that wasn't really a huge concern. Just the corners. :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1