Chrome and Edge floating middle image below first and last, is this correct? - html

It seems that in Microsoft's edge and google chrome the floating doesn't rearrange the divs properly, if you have three divs floated left and the page is scaled in a width between 444 and 436 px the third div goes to the second div's position instead of going below it. This "bug" does not occur in firefox.
I made a JSFiddle to be tested http://jsfiddle.net/e47jckrh/
HTML
<div id="d1">
<p>1</p>
</div>
<div id="d2">
<p>2</p>
</div>
<div id="d3">
<p>3</p>
</div>
CSS
div{
float: left;
}
Down below there is a visual representation of how it should behave
Full page Layout
Correct div floating when page width is more than 444px
Wrong div floating order when page width is between 444 and 436px
Correct div floating when page width is less than 444px
It may be just me thinking there is something wrong, but i assume the firefox behavior to be the correct one.

I've edited your fiddle here: http://jsfiddle.net/e47jckrh/5/
You didn't float all your elements as you'd suggested in the question. So I added float: left; to the div numbered 3 and set all 3 to display: inline-block;. And using display: table; and display: table-cell; with vertical-align: center; is a really old way to get something to align vertically.
These 3 lines work for most things:
position: relative;
top: 50%;
transform: translateY(-50%);

Okay. So #d3 shouldn't be on the right side at all because it isn't floated, but you used display:table. This gives it the effect of being floated with the other two divs for some reason.
Since it uses display: table #d3's margins are off the page but don't count as "not fitting" and don't force it to the next line.
#d2 is floated though so its margins DO affect it. So in the small range you're experiencing this #d1 + #d2 won't fit because of their margins contributing to an overall larger size width but #d1 + #d3 will because #d3 is not being affected by its margin on the right side giving the combo an overall smaller size width.
Simple solution is to float #d3 as well:
#d3 {
background-color: #ede4ad;
border: 3px dotted #6e5b3c;
clear: right;
float: left;
}

The behavior is caused by margin-right.
When div 2 reaches its containers right limit it overflows. In this case you control his limit by margin-right. BUT margin-right is only effective if there is succeeding element ( its calculated base on a succeeding element ). In this case div 3.
After it overflows in new line the div 3 takes its spot. But in this case margin-right has no effect since its the last element in this flow.
EDIT : I just realized you haven't floated all element , I don't know if that was your initial idea. If it was I won't delete this answer.

Related

padding within in a div

I simply can't figure this out: I have a div that is centered on screen with a width of 60%. Inside this div I have 3 more divs that float left with the width of 33% and have a gray bg color. The divs are filled with text and one image per div. Each div should now take 1/3 space inside the "maindiv". This works fine but as soon as I give my 3 "contentdivs" a padding so the text gets seperated a bit the third div wanders below the others. I also want a margin around my 3 divs so there is a gap between all the divs. But this only works if I give the divs a width of like 31%. As soon as I shrink my browser though, the third one pops up below the others again.
How it looks now:
How it looks with a width of 33.33%
How can fix this? I mean I set the divs to a relative width by setting the size in %. So the divs should just shrink as soon as I shrink my browser window. I tried to surround all the divs by other divs and messed around with margins and paddings but it just won't work.
Most likely it’s box model’s fault. Paddings, margins and borders can be added together in different ways. Add box-sizing:border-box to the container and its elements. Most certainly this brings about what you intended to do, and width:33.3333% wil work out as expected.
Adding margin still breaks the item? There’s another great thing called calc(). Assumed you have a margin of 8px, that’s just a few pixels too much. With calc(), you can subtract the additional margin like this:
.item{ width:calc(33.3333vw - 8px); }
Note that there must be whitespace around the minus. Try it and include your margin.
Apply box-sizing: border-box to all related elements (or the entire document, as Bootstrap does). http://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
Then, rather than margin, use padding for the outer spacing. This eliminates the need to do mental math altogether.
div {
box-sizing: border-box;
}
.one-third, .inner, .full-width {
padding: 8px;
}
.one-third {
float: left;
width: 33.333%;
}
.inner {
background-color: pink;
}
<div class="full-width">
<div class="inner">Full-width div</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
Fiddle demo
Your best bet would be to get the three columns and margins to equal 100%. This is fairly easy if you know you are only having three columns:
.item {
width:32%;
margin-left:2%;
}
.item:first-child {
margin-left:0;
}
As long as there is only three it will always add up to 100% as you are overriding the first .item. If you don't override the first item then you will have a space before your columns and the last column won't fit. Mixing pixels and percentages will give you issues in a grid (unless they're paddings and you are using box-sizing). Margin is not included in the box-sizing as it is not part of the main box model.

Make div fill remaining space of parent

I need some help with positioning divs. The HTML structure is as follows:
<div class="container">
<div class="item">
<div class="left">
lorem lorem
</div>
<div class="right">
<p>right</p>
<p class="bottom">bottom</p>
</div>
</div>
</div>
And I have the following CSS:
.container {
float: left;
padding: 15px;
width: 600px;
}
.item {
float: left;
padding: 15px;
width: 570px;
}
.left {
float: left;
padding: 40px 20px;
margin-right: 10px;
}
.right {
position: relative;
float: left;
}
.bottom {
position: absolute;
bottom: 0;
}
The width and height of the left div is dynamic.
What I want to achieve is:
Make the height of the right div equal to height of the left div.
Make the width of the right div fill the rest of the div with class item.
The paragraph with class bottom should be at the bottom of the right div.
Here is a simple image that represents my goal:
And a link to a JSFiddle demo.
Getting the correct position and width of .bottom appears to be the biggest hurdle for a cross-browser, CSS solution.
Options
1. Floats
As #joeellis demonstrated, the flexible widths can be achieved by floating only the left column, and applying overflow:hidden to the right column.
The position of .bottom cannot be achieved in any browser. There's no CSS solution for floated columns with equal, variable height. An absolutely positioned .bottom element must be inside the right column div, so that 100% width would give it the correct size. But since the right column won't necessarily be as tall as the left column, positioning .bottom with bottom:0 won't necessarily place it at the bottom of the container.
2. HTML tables and CSS tables
The flexible widths can be achieved by giving the left cell a width of 1px and not specifying a width for the right cell. Both cells will grow to fit the content. Any extra space will be added to the right cell alone.
If .bottom is inside the right table cell, the position can't be achieved in Firefox. Relative position has no effect in a table cell in Firefox; absolute position and 100% width would not be relative to the right table cell.
If .bottom is treated as a separate table cell in the right column, the correct heights of the right and bottom table cells cannot be achieved in any browser other than Firefox. Table cells aren't flexible in height the same way they are in width (except in Firefox).
3. CSS3 flexbox and CSS3 grids
Flexbox and grids are the promising layout tools of the near future. But flexbox isn't supported by IE9 or earlier, and grids aren't supported by any browser other than IE10. Haven't tested if either can achieve this layout, but browser support may prevent them from being an option at present.
Summary
Floats don't offer a solution for any browser.
HTML tables and CSS tables don't offer a cross-browser solution.
Flexbox doesn't offer a potential solution for IE9 or earlier (and may or may not offer a solution to other browsers).
Grids only offer a potential solution to IE10 (and may or may not offer a solution there).
Conclusion
There doesn't appear to be an adequate CSS solution at present, one that would work in enough relevant browsers, with the possible exception of flexbox (if support for IE9 and earlier isn't required).
jQuery
Here's a couple modified demos that use jQuery to force the columns to have the same height. The CSS and jQuery for both demos is the same. The HTML only differs by how much content is in the left and right column. Both demos tested fine in all browsers. The same basic approach could be used for plain JavaScript.
Taller content on the left
Taller content on the right
To keep things simple, I moved the internal padding for the left and right div to a child element (.content).
Sibling elements of same height and staying on the same row can be achieved by displaying them as table-cell and parent as display: table.
Working fiddle: http://jsfiddle.net/SgubR/2/ (which also display the overflow: hidden along a floating element technique for creating a column. The latter needs a clearfix)
Table-cell in CSS uses any HTML element you want (section, div, span, li, whatever), its semantics is unrelated to table, tr and td elements used for table layout (except that the visual result is the same, that's what we want).
display: table is set on a parent
display: table-row may be used on an element in-between but if it works without it, fine
display: table-cell is set on each child
a width is set on none, some or all these "cells". Browser will adapt both to content and widths set in order to calculate their widths (and total width of parent, obviously)
table-layout: fixed will tell browsers to switch to the other table layout algorithm where they don't care about the quantity of content, only to widths set by CSS
vertical-align: top will be needed in most cases (but you may set other values, great for complex layouts)
margins aren't applied on "cells", only padding. Margins only apply on table itself. Though you still can separate "cells" with border-collapse: separate and/or border-spacing: 4px 6px
Compatibility: IE8+
Fallback for IE6/7 if needed is exactly the same as for inline-block
Longer explanations in previous answers: here and there with also the good old method of faux-columns (your design must be thought with this technique in mind)
Just add an oveflow to the right column and don't float it.
.right {
position: relative;
overflow: hidden;
}
This will make right to fill the rest of the width.
Something like this might work:
http://jsfiddle.net/PCvy9/2/
The main key of what you're looking for lines in the:
.right {
overflow: hidden;
background-color: #C82927;
}
This is due to something called the "block formatting context." Great reasoning and tutorial as to why here: http://colinaarts.com/articles/the-magic-of-overflow-hidden/#making-room-for-floats
However, their heights are not completely linked; in this example, your left side block's height would still need to be manually set (as it's a floated container)

Making a button element fill available width

There are a lot of "fill available space" questions on this site, but my issue is a bit particular in that I've already gotten a solution, but it doesn't work for buttons. I'd like to understand why this doesn't work for buttons, and how I can make it work. I imagine it's just some browser-style for the button element that I need to override.
I have two floating elements within a (fixed-width, if that matters) wrapping div. The right element has fixed width, and the left element should take up whatever width remains.
I can accomplish that by setting the right element to have fixed width and float: right, and leaving the left element without any special styling. This works perfectly for divs. It also works for spans, but only if I set display: block on them. For buttons, I can't get it to work at all. I tried block, inline-block, and every obscure width value I could find on the MDN.
http://jsfiddle.net/wjFbD/2/
I don't know why I didn't think of just wrapping the buttons in divs earlier. Here's what I've come up with:
http://jsfiddle.net/SkczB/2/
This involves the overflow: hidden box formatting context trick (which I suspected was going to make an appearance here, but couldn't quite see where to fit it in). Highlights:
The two buttons are wrapped in divs with class buttonWrapper.
Those divs are formatted according to the trick I outlined in the third paragraph, above. The right div has float: right and a fixed width, the left div has no special styling.
We now apply the box formatting context trick. The left div is given overflow: hidden, which causes it to make space for the right-floated div.
We can now apply a left margin to the right div, and change its width, and the left div will always be the right size.
The divs create the desired "fill available width" effect for us, now we just have to put the buttons inside the divs and give them a height and width of 100%.
If it's the left button you wanted to have a fixed width, then basically repeat the above steps with left and right swapped.
This may not be exactly what you're looking for here, but here's an option that seems to have worked out for me with your fiddle.
If you've got a fixed width div that the elements are contained in, you could split get the remaining width of the div after button A has been set to fill up, say, 100 pixels and then set button 2 to be the remaining size.
Alternatively, another option would be to run it as percentages 20%/80%, 30%/70%, that kind of thing. Here's a fiddle that achieves what you're looking for on just the button wrapper at the bottom. I've applied specific classes for it and added divs around each button for a bit more control. The button wrapper divs are set to 20% and 80% respectively, while the button is set to fill 100% of the containing space.
Here's the modified fiddle and the modfied HTML/CSS. Hope it helps for what you're looking for...
http://jsfiddle.net/wjFbD/7/
HTML
<div class="btnWrapper">
<div class="buttonWrapperB">
<button class="left">
button Left
</button>
</div>
<div class="buttonWrapperA">
<button class="right">
button Right
</button>
</div>
</div>​
CSS
.btnWrapper
{
width: 100%;
background-color: #FEE;
border: 2px solid black;
margin-bottom: 10px;
height: 50px;
}
.buttonWrapperB{
float: left;
width: 20%;
}
.buttonWrapperB button{
width: 100%;
height: 50px;
}
.buttonWrapperA{
float:left;
width: 80%;
}
.buttonWrapperA button{
width: 100%;
height: 50px;
}
​
I adjusted the background opacity of your .right elements to see what was going on below them. It looks like the .left elements are not only taking up the remaining space-- they're also taking up the entire row. Weirdly, the text inside these elements is centered as if it were only taking up the remaining space.
If you want the same to work for the buttons, it seems like the only solution involves a little hack. Buttons are quite complex indeed.
button.left {
margin: 0;
position: absolute; /*this seems to be the only way to get the button to stay on the same row - floating it left won't even work*/
z-index: -1; /*hides the "overflowing" part below the right button*/
width: 100%; /*make the button stretch to the full width of the row*/
padding-right: 400px; /*add a padding-right hack so that text will be centered correctly - should be same size as fixed width .right element*/
padding-left: 0;
display: block;
}
See updated fiddle: http://jsfiddle.net/wjFbD/6/
starting with
One element has fixed width, and the other element should take up
whatever width remains.
here is my general solution:
<div class="container">
<div class="two">125 €</div>
<div class="one">my favorite provider</div>
</div>
(stylus syntax, in your mind just add {,},;)
.one // red
border none
height auto
overflow hidden
white-space nowrap
text-overflow ellipsis
.two // green
float left
white-space nowrap
text-overflow ellipsis
You can set the one green thing to a fixed width, but indeed, you do not even have to! Things full up nicely. And String get's truncated with an ellipsis, if it gets too long.
Things get a bit more complicated, when one of them is a <button> rather than a <div> (and I can't figure out, which style property differenciates them, so I would need to style away), but anyway, with a wrapper, that also works:
→ See full codepen here. (Feedback appreciated.)

Float right without changing order, forced shrink

This problem is probably quite easy to solve but I'm not sure what I do wrong.
I have the following code:
HTML:
<div class='absolute'>
<div class='container'>
<span>blabla</span>
unknown number of spans..
</div>
</div>
CSS:
.absolute{
position: absolute;
bottom: 0px;
right: 0px;
}
.container{
float: right;
}
span{
display:block;
float: left;
}
Basically what I want is to have all the spans in one straight line at the bottom right. The absolute div works perfectly and container div float right exactly like I want. The problem is that the spans refuse to line up in one row. I get the following look:
The red is absolute div, the blue the container div and the green the spans. Well you see my problem..
I have tried to give the container div a width. This result in a straight horizontal line, like the one I want, except that the spans float to the left as far as the width of the blue container div. And I can't calculate the width because I don't know the number of spans.
So how do I solve this without changing any order and without setting a width to the container div? Or rather, why does the container div shrink at all and not just stay as wide as the floats wants it to be?
Thanks for any answer!
change display:block to display:inline-block?
Change you span to:
display: inline-block;
should make them go next to each other.
This isn't supported in IE7 or earlier though, if that's important to you, you can do this:
display: inline-block; *display: inline;
Oh and remove the float left on the span.

css floating and iexplorer

i have two divs, that float correctly in chrome, ff and safari but not iexplorer, the right div appears below the left div floated to the right- the two divs are wrapped by an outer div with a width of 800px;
<div class="b_left">
</div>
<div class="b_right">
</div>
.b_left{
width:350px;
margin-left:80px;
float:left;
display: block;
}
.b_right{
float:right;
width:350px;
height:280px;
background-color:#c8c8c8;
display: block;
}
when using divs for columns, which I assume is what you are intending for this, it is better to only float one of the divs.
Say i have a div called content which is 600px wide and inside it two 300px divs inside, leftblock and rightblock. Instead of floating leftblock left and rightblock right I instead float the leftblock left and put a 300px margin-left on the rightblock. This pushes the rightblock to the right and ensures room for the leftblock to fit in beside it while preventing IE from displaying weirdly.
Hope this helps
it is a bug of ie, it doubles the margins. you must add display inline to the .b_left.
display: inline
I created a quick jsFiddle here: http://jsfiddle.net/6JWq9/
And it shows up just fine. I suspect you have other code that adds padding or a margin.
Review my example, let me know what is different from yours and I can update my answer.
Just put margin: 0; padding: 0; on all three divs and go from there to check. Also reset styles are a MUST for IE, I use Eric Meyer's. (easy to Google).
Also, display: inline; on the one with margin will fix it for IE6 I suspect.