HTML:
<div id='container'>
<p>This is some text contained within a small-ish box. I'm using it as an example of how placing your floated elements in different orders in your HTML can affect your layouts. For example, take a look at this great photo placeholder that should be sitting on the right.</p>
<img src='image.gif'>
</div>
CSS:
#container {
width: 280px;
margin: 0 auto;
padding: 10px;
background-color: #aaa;
border: 1px solid #999;
}
p {
width: 100px;
}
img {
float: right;
}
Result: https://jsfiddle.net/y9Lqjm1f/
Why if the paragraph's width is small enough does the floated right element not appear at the top of the container div?
Because the img element is placed below the p element which follows the normal flow as a block element.
img's separate flow, which results from it having a float style applied, only begins below the p.
If you added another p below the img it would follow normal layout flow as if the img did not exist, like so: https://jsfiddle.net/mkarajohn/y9Lqjm1f/1/
In short, in order for the img to appear to the top, it has to be placed first in the markup, like so: https://jsfiddle.net/mkarajohn/y9Lqjm1f/2/
Also see this about float and block elements
In general:
Floated elements respect previous block elements' layout flow, meaning they appear below the previous block element
Block elements following the floated element disregard the floated element, and keep their normal layout flow as if the floated element did not exist.
p and img tags are block level elements. They create new line for next element. So, float: right; property in img apply in new line.
You can use display: inline-block; for both p and img tags.
codepen
Related
In the following example, the <div> is smaller then its content.
Why? And how do I fix it?
.switcher {
border: 1px dashed green;
}
.switcher a {
padding: 30px;
background: orange;
}
<div class=switcher>
<a href=#>first</a>
<a href=#>second</a>
</div>
From the specs:
9.4.2 Inline formatting contexts - In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned.
Although padding can be applied to all sides of an inline element, but only left and right padding will have an effect on the surrounding content.
The <a> tag is an inline element by default. You can set it to inline-block, so that both horizontal and vertical padding will be respected. As an inline-block element is placed as an inline element (on the same line as adjacent content), but it behaves as a block element.
.switcher {
border: 1px dashed green;
}
.switcher a {
padding: 30px;
background: orange;
display: inline-block; /*new*/
}
<div class=switcher>
<a href=#>first</a>
<a href=#>second</a>
</div>
You can contain the the a elements by placing a overflow: hidden or overflow: auto to the switcher class
You can make <a> tags display block ... as anchor tags are not by default similar as <div> p h1 h2
<a> tag and span tag are inline tags. these elements remain inline until you apply some property to display as block.
so both display: inline-block and display: block will work.
W3C states that:
Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. However, the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.
This work as expected with divs:
#a
{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
#b
{
width: 200px;
height: 200px;
display: block;
border: 1px solid black;
background-color: red;
}
<body>
<div id=a></div>
<div id=b></div>
</body>
Here the red div is block-level element, therefore it's ignoring the floating one. (if I changed red one to display: inline-block it would appear next to floating one)
But, if I apply display: block to an image ,it won't ignore the floating div, Why?
#a
{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
#b
{
width: 200px;
height: 200px;
display: block;
border: 1px solid black;
}
<body>
<div id=a></div>
<img id=b src="https://www.gravatar.com/avatar/5cb44dcd4ebddfea3ede8c6d46b02795?s=328&d=identicon&r=PG&f=1">
</body>
Several paragraphs after the one you quote, the spec says:
The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap the margin box of any floats in the same block formatting context as the element itself.
Although you've applied display: block to your image, being an image it's a replaced element, and therefore the float cannot intrude into its bounds.
Only non-replaced block boxes that don't establish block formatting contexts and are in the same flow as a float may ignore the float.1 A block-level replaced element is not a block box, because a replaced element cannot be a block container box.2
1 You're probably thinking, that's a ridiculously specific statement, and it is. It's why terms like "block element" are considered extremely vague in CSS parlance. Then again, it doesn't help that CSS itself defines almost equally vague terms like "block box" to specifically refer to boxes that are both block-level boxes and block container boxes.
2 This does imply that "non-replaced block box" is somewhat of a tautology, which reinforces just how ridiculously specific that statement is.
W3C
These are the two things that stuck out to me when viewing the W3C. It's considering it as a line box.
A floated box is shifted to the left or right until its outer edge touches the containing block edge or the outer edge of another float. If there is a line box, the outer top of the floated box is aligned with the top of the current line box.
A line box is next to a float when there exists a vertical position that satisfies all of these four conditions: (a) at or below the top of the line box, (b) at or above the bottom of the line box, (c) below the top margin edge of the float, and (d) above the bottom margin edge of the float.
I've used "margin: 0 auto" on <p>, <a>, and <img> elements inside a float div but it doesn't seem to affect them. Therefore, I manually aligned them by "margin-left." It looks ok but I'd rather apply a uniform rule to all elements in the div. Thank you.
The float div:
#side {
float: left;
width: 300px;
height: 630px;
background-color: white;
border-radius: 10px;
}
If I understand you correctly, you are trying to centrally align all the elements (p, img, and a) inside the floated div.
Out of the 3 html elements you specified, <p> is a block level element, but <img> and <a> are inline elements. In order for you to use margin: 0 auto all the elements should have a width specified. And the width can only be specified for the block level elements.
So you can use the property display: block for the inline elements like a and img which will convert them to a block level element. And then you can specify the width property for all the elements inside the div (including p, a, and img). Once the width for all the elements are specified, now you can use margin: 0 auto and it should work perfectly fine.
If you want the text inside the div to be centrally aligned all the time, then you can use the css property called text-align: center on the div.
The layout inside a container is not affected by whether the container is float or not. That only affects where the container is positioned, not how the child elements inside the container are positioned.
The elements you are trying to use margin on are inline elements, not block elements.
With things like margin: 0 auto, the auto applies to block elements that would normally go full width, not inline elements which will normally be only as wide as their content.
For inline elements, you may want to use text-align: center, but we'd really have to see your exact HTML and the desired layout in order to know exactly what to recommend.
I have provided below marginfix which is a block level element and one and two are also block level, but these are floated. That is the reason why they are on same line of layout, but marginfix is not floated either, and block level element should go below the element as the following
+--------------------+ +--------------------+
| | | |
+--------------------+ +--------------------+
+--------------------------+
| |
+--------------------------+
But it works like this
+--------------------+ +--------------------------+ +--------------------+
| | | | | |
+--------------------+ +--------------------------+ +--------------------+
This is the HTML
<div class="wrap">
<div class="one">one</div>
<div class="two">two</div>
<div class="marginfix">three</div>
</div>
CSS
.wrap{
width: 500px;
background-color: red;
position: relative;
margin: 0 auto;
}
.one{
width: 200px;
float: left;
}
.two{
width: 200px;
float: right;
}
.marginfix{
margin: 0 210px;
}
UPDATE NOTE
Someone may say marginfix contain the remaining space of the floated elements. If so, why it wouldn't work if we change the order of the html element. This html won't work as above html
<div class="wrap">
<div class="one">one</div>
<div class="marginfix">three</div>
<div class="two">two</div>
</div>
So how does the margin value work?
That's how floats work - they are removed from the normal flow of content. If you want to force .marginfix to sit below the others, add .marginfix{clear: both;} to your styles.
When you float any element to left then other elements go in the same line of layout if you haven't cleared the floats and that's why marginfix is set exactly after the float left even if you haven't set a margin value to marginfix and the remaining of the elements go toward the left edge from line (when one height is achieved) and likely to two if your one and two is not enough height as marginfix but here you have set marginfix a margin value so it remains in the same pillar.
Play with this fiddle
That happened because both the class .one and .two were floated, leaving 100px space between them. That's where the .marginfix will fill in. If you want the .marginfix to be placed below them and is aligned center, assign clear:both; to place it below them and use margin:0 auto; to make it centered.
Interaction of Margins and Floated Elements
Demo HTML and CSS: http://jsfiddle.net/audetwebdesign/2Hn7D/
In this example, .wrap is the parent, containing block element with a fixed width
of 600px and centered horizontally using a standard method, margin: 0 auto.
Within the parent block, there is an block level element, div.marginfix with some text
(for illustation purposes). As such, div.marginfix is in normal flow and in a
block formatting context. Its width will extend to fill the width of the parent
container.
The parent block also contains two floated elements, div.one and div.two,
floated left and right respectively, both having width: 200px.
A CSS compliant browser will follow the CSS block formatting model to lay out the
content in the following manner:
(1) Ignore the floated elements and then compute the layout for the remaining
in-flow elements (.marginfix) adjusting for margin, padding, line-height,
inline elements and so on.
(2) Determine the space required to place the floats such that the left floated
element is flush with the left edge of the parent, the right floated element is
flush with the right edge of the parent, and both have their top edges adjacent
to the top edge of the parent element.
(3) Adjust the width of the line boxes (the imaginary boxes around the text in
the child div's) as needed to allow the text of the normal flow elements to
wrap around floated elements.
Basic Example
In the simplest case, the text within .marginfix wraps around the two floated
elements and extends to the left and right edges of the parent element once the
text has cleared the floats.
Example 2 - Add Margins
If you add left and right margins to .marginfix, the width of the in-flow div
is computed to be {width of parent - left margin - right margin}, so the text
is constrained to the center of the layout. A similar effect would result from
using padding.
It is important to note that the text formatting in this example would be the
same even if one or both of the floated siblings were removed.
Example 3 - Changing the Order of the Elements
When using floats, the order of the elements makes a difference.
Consider the following variation, place .marginfix between the two floated div's:
<div class="wrap ex3">
<div class="one mark">one - add some text to make it taller for effect.</div>
<div class="marginfix">three - Nulla vehicula libero... </div>
<div class="two mark">two - single liner</div>
</div>
In this case, the text from .marginfix will wrap around the left floated element.
However, the right floated element now appears after the in-flow block, and for this
reason, the .two element is flushed to the right (as expected) and to the bottom
edge of the nearest block level element, in this case, .marginfix.
Any margins or padding applied to .marginfix would simply extend the height of
the inflow element and div.two would still be positioned after it (see Example 4).
Example 5 - Establishing a New Block Formatting Context
It you apply overflow: hidden to .marginfix, the CSS formatting model starts a
new block formatting context, which means that .marginfix will not extend
beyond any edges of any any adjacent floated elements.
In this example, the text from .marginfix no longer wraps around the left floated
element.
As before, the right floated div is still positioned after .marginfix since
.marginfix is still a block level element.
re: your edit - the css "clear" property makes the current element sit below any floated elements that come before it in your HTML. Therefore, if you change your HTML to the following:
<div class="wrap ex3">
<div class="one mark">one - add some text to make it taller for effect.</div>
<div class="marginfix">three - Nulla vehicula libero... </div>
<div class="two mark">two - single liner</div>
</div>
div class="one" will be "cleared" but div class "two" will not.
Play with the jsfiddle. I have converted your code to the fiddle. And for each div there is different background color. Play with various float values. And the change in the layout will be clear to you from the different colors of the boxes.
inherit
left - floats the box to the left with surrounding content flowing to the right.
right - floats the box to the right with surrounding content flowing to the left.
none (default)
If you do not want the next box to wrap around the floating objects, you can apply the clear property:
clear: left will clear left floated boxes
clear: right will clear right floated boxes
clear: both will clear both left and right floated boxes.
Refer html dog tutorial on page layout for more details about layout using css
Floats are removed from the normal flow of content. When you apply floats to a div margins do not see the floated div as an actual element that is till you apply a clear: both.
see jsfiddle
.one{
width: 200px;
float: left;
clear: both;
}
.two{
width: 200px;
float: right;
clear: both;
}
.marginfix{
margin: 0 210px;
}
Now it sounds like you are trying to achieve a positioning where the marginfix pushes the div to the middle. If that is the concept, place display: block on marginfix.
See jsfiddle
.one{
width: 200px;
float: left;
}
.two{
width: 200px;
float: right;
}
.marginfix{
margin: 0 210px;
clear: both;
}
Margins push elements around an element. Since floats are outside of the normal flow, margins push from the edge because it doesnt see the element as a boundary. Think of the boundary as element that has clear: both with float as well. Now it will see it as an element.
Here is the even stranger issue. When both of the float left and right have clear both the float right gets pushed down. But if you attach clear: both to marginfix it pushes it down like in your first example.
I think first answer by Chapurlink makes sense, have modifies his fiddle, see the answer,
that works as you have explained/expected, white box is div three with clear:both
See the fiddle
I hope this is in context to your question.
This is HTML:
=================
<div id="container">
<div id="one"><h1>hello world1</h1></div>
<div id="two"><h1>hello world2</h1></div>
<div id="three"><h1>hello world3</h1></div>
</div>
CSS
====
#container
{
height: 1024px;
width: 760px;
position: fixed;
}
#one
{
margin-left: 10px;
position: relative;
border: 2px solid red;
width: 220px;
}
#two
{
margin-left: 272px;
position: absolute;
border: 2px solid Blue;
width: 220px;
float: right;
}
#three
{
border: 2px solid Green;
float: right;
margin-top: -86px;
position: relative;
width: 220px;
}
I often find that I want an element to adjust its width to the size of the elements it contains. inline-block acheives this. However, I do NOT want the inline part of inline-block -- i.e., I still want the next inline-block element to appear below it.
Is there a simple way to achieve this in CSS? I know I can't always but <br> tags after the element in my HTML, but that's annoying.
You can do that with two elements:
<div>
<div class="element">
content...
</div>
</div>
With the CSS rule:
.element { display: inline-block; }
Treat .element as the "real" element that you're adjusting the width of. The enclosing <div> is just there to force each element into its own inline flow.
there are many solutions, the most common one is to use float
<div class="float">
<div class="child">here is content</div>
</div>
.float{float: left;}
if you want enforce that an element is in the new line you add clear: both (or left or right, depending on your needs)
please take into account, that display: inline-block does not work in IE7. The only problem with float is when you want this div to adjust to the width of a child AND to position it at the middle of the page horizontaly
one more note, remember that overflow: hidden property is your best friend whenever you encounter any issues with floated divs :)
Here is a fiddle that achieves what you describe: http://jsfiddle.net/PhilippeVay/VwCgJ/
It uses floating elements (thus width is ajusted to content), a class on the last element you want on a line and the clear property on the next element, with the help of the adjacent selector .rightmost + span
HTML:
<p>
<span>lorem</span>
<span class="rightmost">ipsum</span>
<span>third item: below please</span>
<span>fourth and last</span>
</p>
CSS:
span {
display: block;
float: left;
padding: 20px;
background: lightblue;
border-right: 2px solid white;
}
.rightmost {
background: red;
color: white;
}
.rightmost + span {
clear: both;
}
Inline content (as for inline-block) will occupy the whole width of its container and you've to force a new line with the br element.
On the other side, floating elements can be cleared (and with adjacent selector, you can clear the element after a particular one).