CSS Float multiple left-floated elements and one right floated - css

I'm having a bit of trouble with floats. I'm playing with a site that I want to make a bit responsive using media queries for varying browser widths. As it sits, the page displays with the flow of the HTML, but when the browser is widened, I want the blockquote to wrap up onto the right of the img, but it only wraps as far as the p element immediately before it.
Here's the HTML:
<ul>
<li>
<h3>Title</h3>
<img src="images/image" />
<p>This is some text.</p>
<p>Here's some more text.</p>
<p>And heres yet another block of text.</p>
<blockquote>This is a quote.</blockquote>
<a>A link</a>
</li>
</ul>
Here's an example of how my HTML and CSS look: http://jsfiddle.net/tempertemper/MZWD9/12/
The site that I'm looking to make wider is here: http://tempertemper.net/portfolio
I'm sure I'm missing something obvious but I can't work out what it is and I'm starting to wonder if float only floats two adjacent elements. I suppose I could put a div around the img and p tags, but I want to keep my HTML nice and clean.
All elements have a width and the blockquote definitely fits in the containing element (ie. the width of the li is sufficient to contain all of the elements and their padding, borders, margins, etc.). I've tried floating all of the elements left, bar the blockquote which I've floated right. Tried using clear:left for the elements preceding the block quote. No joy.
Can anyone put me right?
Thanks,
Martin.

With the HTML you have, this is not possible.
The flow of a document happens in HTML order. This means that, under normal circumstances, an element can only affect elements that come after it in the HTML, as far as positioning goes.
float: right, for example, will move the element to the right and any elements following it will flow around it to the left. clear: left will prevent elements from flowing to the left of the element it is applied to.
I might suggest breaking your HTML into blocks, and floating those.
You could then remove the h3, img, p selector and rule from your CSS, and replace it with a similar rule for .content
In general, I would recommend reading up on document flow, float, clear, and position. They tend to be over-used properties, and it seems you were over-using them here.
Here is the code:
ul {
width: 200px;
}
.content {
float: left;
width: 100px;
}
blockquote {
float: right;
width: 50px;
}
a {
float: left;
clear: both;
}
<ul>
<li>
<h3>Title</h3>
<div class="content">
<img src="images/image" />
<p>This is some text.</p>
<p>Here's some more text.</p>
<p>And heres yet another block of text.</p>
</div>
<blockquote>This is a quote.</blockquote>
<a>A link</a>
</li>
</ul>
Oh, and a fiddle for you: http://jsfiddle.net/2bedr/1/

The solution is quite simple. Even more simple then you thought.
change:
<ul>
<li>
<h3>Title</h3>
<img src="images/image" />
<p>This is some text.</p>
<p>Here's some more text.</p>
<p>And heres yet another block of text.</p>
<blockquote>This is a quote.</blockquote>
<a>A link</a>
</li>
</ul>
To this:
<ul>
<li>
<h3>Title</h3>
<blockquote>This is a quote.</blockquote>
<img src="images/image" />
<p>This is some text.</p>
<p>Here's some more text.</p>
<p>And heres yet another block of text.</p>
<a>A link</a>
</li>
</ul>
By stating the blockquote first (and float it right) you first TELL the element to float right. I know this is not logical, but it is the right answer... Had this multiple times myself.

You can float all of your elements left to line them all up horizontally. Check this example.
You can also give the <ul> a width and float the last element right so it will remain right no matter the width of the parent element. Another example.
If there's more I can help with, I will update :)
After your comments, you should revise the HTML structure to have the blockquote directly after the img or title. Then it will behave as you wish. Example.

Related

How to clear only those CSS floatings of blocks that are within the clearing element's parent?

If you directly want to go to the fiddle, here it is: http://jsfiddle.net/AGVFn/9/
I'm currently working on a web design whose structure should look somewhat like this:
As you can see, the grey blocks (I'll call them "content blocks") will contain some text as well as images (or other blocks) that need to be floated to the right inside their container.
The height of the content blocks should always be large enough for the content block to display the whole text content as well as all images.
The navigation box on the right should also adjust to the size of its content accordingly.
HTML-wise I want to have a (mostly) semantic structure - so I started with this:
<div class="mainContentContainer">
<nav>
<div>
<h2>Navigation</h2>
<ul>
<li>Article #1</li>
<li>Article #2</li>
<li>Article #x</li>
[...]
</ul>
</div>
</nav>
<article id="one">
<div>
<img src=".." />
Lorem ipsum...
<img src=".." />
More lorem ipsum...
</div>
</article>
<article id="two">
<div>
Lorem ipsum...
<img src=".." />
More lorem ipsum...
</div>
</article>
[...]
</div>
I then started to create CSS definitions for my design. I added float: right; to the navigation bar on the right as well as to the images inside my content blocks.
However, I ran into the following problem: In order for the content blocks to adjust its height to the text AND to the floated images accordingly, I need an (empty) element at each content block with clear: right;. (This can of course be done with an :after rule.) However, this clearing element will make the first content block expand so far that it is too large (i.e. large enough to possibly also contain the navigation block). This not what I want.
I set up a small demonstration in this fiddle: http://jsfiddle.net/AGVFn/9/
My question boils down to: How do I clear only those CSS floatings of blocks that are within the clearing element's parent?
If this happens to be impossible in CSS: Is there another way to create to create the sketched design with none or only slight changes in the HTML structure? (If the HTML structure has to be changed, the changes should not 'destroy' the semantics!)
EDIT 2014-06-26 12:35 UTC
A solution proposed by ajm suggested dropping the clearing :after element for content blocks and simply adding overflow: hidden; to the content block rule.
This won't work since content blocks might also contain explicit clearing elements. (Example: Sometimes the start of a new paragraph should be aligned with the associated floating element. In such a case the paragraph needs to have clear: right;.)
Assuming you don't need visible overflow, overflow: hidden; will expand the height of your articles without clear:
article {
background-color: #9a9a9a;
margin-bottom: 1.5em;
margin-left: 1em;
margin-right: 1em;
padding: 0.5em;
overflow: hidden;
}
That snaps the height of your first box to its content.

ol within ul and make certain list items extend to the width of parent element

I am kind of new to css and trying to create a layout that presents a list of books. Therefore I want to display a cover image (represented by a fixed width div in the fiddle) at the left side of a two column layout. To the right of the cover I want to present information about the book: The title and an ordered list which has property-value items.
These items should fill the remaining part of the width. The property and its corresponding value should be placed on the same line.
One of the property value items also contains a button, which is just represented by a span here. The button should be placed in the same line right after the property.
I have run into several problems, which I couldn't sort out so far:
The property list is not formatted correctly. I guess that is because I haven't been able to configure the containing list item to extend to the full width. In the end a property value item should be displayed on the same line.
The Title is underlined and I would like to see that underline extend to the full width of the body. Currently it is truncated and I haven't been able to figure out a way to make that happen.
I have created a fiddle, which should show the problems: http://jsfiddle.net/7Xeb7/3/
This is my basic html structure:
<body>
<ul class="book">
<li>
<div class="cover"></div>
</li>
<li class="bookdetail">
<div class="title">Title</div>
<ol class="attributes">
<li>
<span class="property">property <span>btn</span></span>
<span class="value">value</span>
</li>
<li>
<span class="property">property</span>
<span class="value">value</span>
</li>
</ol>
</li>
</ul>
</body>
Short Answer
Your HTML is somewhat more complicated than necessary and makes unorthodox use of list elements for things that aren't really lists. Simplifying it would make styling the page easier. I have done so in this jsFiddle, where I think your problems have been taken care of by absolutely positioning .cover and adding appropriate padding to .bookdetails: http://jsfiddle.net/7Xeb7/10/. (Edit: new jsfiddle reflects comments)
Long Answer
As much as possible, the HTML tags you use should be semantically-related to the content they represent. So use ul or ol for lists of things, use img for images, and use heading tags (h1, h2, etc.) for headings. There's no need to use tables here (which are generally frowned upon for layout since they violate this semantic logic). Here I've preserved your structure and CSS classes but used more logical tags:
<div class="book">
<img class="cover" src="" alt="Book Title Here" />
<div class="bookdetail">
<h2 class="title">Title</h2>
<ol class="attributes">
<li>
<span class="property">property</span> <!-- this span wasn't closed before! -->
<span class="button">btn</span></span>
<span class="value">value</span>
</li>
<li>
<span class="property">property</span>
<span class="value">value</span>
</li>
</ol>
</div><!-- /.bookdetail -->
</div><!-- /.book -->
Once the HTML has been cleaned up you can more easily make the necessary CSS changes. Your main issue is getting .bookdetail in the right place. It's hard at the moment because you're trying to balance a fixed-width element (.cover) with a variable-width element (.bookdetail) that you want to take up the whole of its container - except for the fixed-width element.
This can be solved fairly easily by absolutely positioning .cover, so it no longer has any effect on the positioning of other elements in .book. Then you can just set the padding of .bookdetail to 0 0 0 140px - which is automatically relative to the most recent parent element with a specified position, which I've made .book. So .bookdetail expands to fill book like you want, but the right padding (or margin, if you prefer) means that it doesn't overlap with the cover image.
I've also made a few other CSS changes, visible in the jsFiddle, to make .title display better and to accommodate my HTML changes, but they're not directly relevant to solving your main issue so I'll leave them there.
I have changed your layout accordingly using div and tables
<div class="leftColumn">
</div>
<div class="rightColumn">
<div class="header">
Title
</div>
<div class="content">
<table width="100%">
<tr><td>Property1<td><td>Value</td>
<tr><td>Property2<td><td>Value</td>
<tr><td>Property3<td><td>Value</td>
<div>
</div>
and css
.leftColumn
{
float:left;
width:30%;
height:250px;
background-color:red;
}
.rightColumn
{
float:right;
width:70%;
height:250px;
background-color:green;
}
.header
{
font-size:25px;
padding:15px;
height:30px;
verticle-align:middle;
border-bottom:1px solid #ccc;
}
have a look here
you are missing width attribute for dimensions but not sure if this is how you want to see it:
http://jsfiddle.net/Riskbreaker/7Xeb7/4/
I added width: 100% on you bookdetail class
.bookdetail {
vertical-align:top;
display: inline-block;
width: 100%;
}

Why List item going to Image?

Why gose to image's flow
This is code:
<p><img class="left" width="95" height="64" src="#" />
some text here some text here some text here some text here some text here some text here
</p>
<ul>
<li>some text here some text here some text here some text here some text here some text here some text here
</li>
</ul>
Probably because
the image is float: left
either the <ul> or the <li> or both is display: inline
I assume you want to keep the left float of the image. To get the <ul> onto its own line,
you could give it a display: block; clear: left; to sort it out.
Because you're floating the image left. That's what happens. The bullet is behind the picture.
Presumably because a CSS rule-set that applies to the element includes the rule float: left
Remove class="left" :)
If you have control over the .left class, add some padding or margin to the right side of the image.
.left {float:left;padding-right:2em;}
or
.left {float:left;margin-right:2em;}
The exact amount of padding/margin you need depends on how the list is styled - you want to add enough so that the list bullet doesn't overlap the image, but the paragraph and other stuff doesn't go too far to the right.
Which of padding-right or margin-right to use depends on what else is going on in the page, what browser(s) you are using, and somewhat also on personal preference. Try each and see which one works better in your situation.

CSS: What does clearing INSIDE a floated div do?

Quick question!
Does putting a "clear" element INSIDE a floated div do anything?
Like:
<div style="float: right">
blah blah
<div style="clear: right"></div>
</div>
Somewhere somehow I got the impression that this helps the div expand to contain the content inside of it. What does it actually do? Anything?
Thanks!
An element which contains nothing but floats will collapse in height, because the floated elements are no longer in the normal document flow. In such a case, clearing after the floats will allow the containing element to retain its height.
<div id="container">
<div id="float1" style="float:left;"></div>
<div id="float2" style="float:right;"></div>
<!-- if you use a clearing element, it should go here -->
</div>
Note that there are other ways to clear than using clearing elements, such as adding overflow:hidden; to the container styles.
In your example, since the div with clear: right is nested, it doesn't clear anything. Float applies to elements at the same level. If the divs were at the same level, the second div would appear below the div that has float: right. This page has some good explanations/examples of how float works: float tutorial
In your case, not much effect. the enclosed div (clear: right) is as good as redundant.
<div style="float: right; background: red;" >
blah blah
<div style="clear: right; background: blue;"></div>
</div>
With this, you can visually see if you enclosed div made a difference.

What is the best way to position a div in CSS?

I'm trying to place this menu on the left hand side of the page:
<div class="left-menu" style="left: 123px; top: 355px">
<ul>
<li> Categories </li>
<li> Weapons </li>
<li> Armor </li>
<li> Manuals </li>
<li> Sustenance </li>
<li> Test </li>
</ul>
</div>
The problem is that if I use absolute or fixed values, different screen sizes will render the navigation bar differently. I also have a second div that contains all the main content which also needs to be moved to the right, so far I'm using relative values which seems to work no matter the screen size.
float is indeed the right property to achieve this. However, the example given by bmatthews68 can be improved. The most important thing about floating boxes is that they must specify an explicit width. This can be rather inconvenient but this is the way CSS works. However, notice that px is a unit of measure that has no place in the world of HTML/CSS, at least not to specify widths.
Always resort to measures that will work with different font sizes, i.e. either use em or %. Now, if the menu is implemented as a floating body, then this means that the main content floats “around” it. If the main content is higher than the menu, this might not be what you want:
float1 http://page.mi.fu-berlin.de/krudolph/stuff/float1.png
<div style="width: 10em; float: left;">Left</div>
<div>Right, spanning<br/> multiple lines</div>
You can correct this behaviour by giving the main content a margin-left equal to the width of the menu:
float2 http://page.mi.fu-berlin.de/krudolph/stuff/float2.png
<div style="width: 10em; float: left;">Left</div>
<div style="margin-left: 10em;">Right, spanning<br/> multiple lines</div>
In most cases you also want to give the main content a padding-left so it doesn't “stick” to the menu too closely.
By the way, it's trivial to change the above so that the menu is on the right side instead of the left: simply change every occurrence of the word “left” to “right”.
Ah, one last thing. If the menu's content is higher than the main content, it will render oddly because float does some odd things. In that case, you will have to clear the box that comes below the floating body, as in bmatthews68's example.
/EDIT: Damn, HTML doesn't work the way the preview showed it. Well, I've included pictures instead.
I think you're supposed to use the float property for positioning things like that. You can read about it here.
All the answers saying to use floats (with explicit widths) are correct. But to answer the original question, what is the best way to position a <div>? It depends.
CSS is highly contextual, and the flow of a page is dependent on the structure of your HTML. Normal flow is how elements, and their children, will layout top to bottom (for block elements) and left to right (for inline elements) inside their containing block (usually the parent). This is how the majority of your layout should work. You will tend to rely on width, margin, and padding to define the spacing and layout of the elements to the other elements around it (be they <div>, <ul>, <p>, or otherwise, HTML is mostly semantic at this point).
Using styles like float or absolute or relative positioning can help you achieve very specific goals of your layout, but it's important to know how to use them. As has been explained, float is generally used to place block elements next to each other, and it really good for multi-column layouts.
I won't go into more details here, but you might want to check out the following:
SitePoint CSS References - probably the most straightforward and complete CSS reference I've found online.
W3C CSS2.1 Visual Formatting Model - Yes, its a tough read, but it does explain everything.
You should use the float and clear CSS attributes to get the desired effect.
First I defined styles for the called left and right for the two columns in my layout and a style called clearer used to reset the page flow.
<style type="text/css">
.left {
float: left;
width: 200px;
}
.right {
float: right;
width: 800px;
}
.clear {
clear: both;
height: 1px;
}
</style>
Then I use them to layout my page.
<div>
<div class="left">
<ul>
<li>Categories</li>
<li>Weapons</li>
<li>Armor</li>
<li>Manuals</li>
<li>Sustenance</li>
<li>Test</li>
</ul>
</div>
<div class="right">
Blah Blah Blah....
</div>
</div>
<div class="clear" />
you can use float
<div class="left-menu">
<ul>
<li> Categories </li>
<li> Weapons </li>
<li> Armor </li>
<li> Manuals </li>
<li> Sustenance </li>
<li> Test </li>
</ul>
</div>
in css file
.left-menu{float:left;width:200px;}

Resources