How to float boxs using CSS - html

I am creating a responsive grid layout but want to know how to float boxes and keep the last container floated right with no margin.
For example.
Full width desktop version will show 4 boxes.
Ipad will show 3 boxes
Phone will show 2 boxes. The last box will need to have 0 margin right.
here is my fiddle http://jsfiddle.net/SGy4R/2/
<div id="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box">the last box needs no margin right when full width and responsive</div>
<div class="clearfix"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box">the last box needs no margin right when full width and responsive</div>
</div>

Add:
.box:nth-of-type(4n){
margin-right:0
}

Change your markup like this:
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box">the last box needs no margin right when full width and responsive</div>
</div>
<div class="clearfix"></div>
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box">the last box needs no margin right when full width and responsive</div>
</div>
And set margin-right: 0; for last-child
.container > div:last-child{
margin-right: 0;
}

I actually think this topic is a bit more tricky as I am sure that you do not only want to remove the margin on the last box but you also want all boxes to have the same width.
It means that we need to know how many boxes are currently displayed and disregard the ones hidden by the media query, remove the padding (I worked with paddings on a wrapper rather than margins) on the last container and share the padding among all boxes to make them equal in width.
Check out the fiddle: http://jsfiddle.net/SGy4R/8/
I basically get the width of the #container and count all visible children inside the container. I then get the padding of the first box to calculate the padding share for each box. With the for loop I apply the calculated width to each box element while removing the padding from the last one.
I added a media query to the fiddle so you can see how it works when there are 3 or 4 boxes inside the #container. Just resize the result pane and run the fiddle again.
// Get width of container
var cont_width = $('#container').width();
// Count box divs in container
var cont_children = $("#container > *:visible").length;
// Get box padding from first child
var box_padding = $('.box:first-child').innerWidth();
// Share last "non-existent" padding with all 4 boxes
var padding_share = box_padding / cont_children;
// Calculate box size
var box_width = (cont_width / cont_children) + padding_share;
// Set width for each box, remove padding for last box
for ( var i = 0; i <= cont_children; i++ ) {
if (i === cont_children) {
$(".box:nth-child(" + i + ")").css({
'width':box_width - box_padding,
'padding-right': '0px'
});
}
else {
$(".box:nth-child(" + i + ")").width(box_width-box_padding);
}
}

$(".clearfix").prev().css("float","right").css("margin","0px");
AND
$($($(".clearfix").nextAll())[3]).css("float","right").css("margin","0px");
Will do what you need.

see this DEMO
EDIT
you can remove #container width and add #container padding-right:20px;
.box{
float:left;
width:100px;
height:100px;
background:red;
margin-left:20px;;
margin-bottom:20px;
color:white;
}
.clearfix{
clear:boh;
}
#container{
border:1px solid black;
float:left;
padding-right:20px;
}

You could use a media query:
// Normal
.box:nth-child(4n) { margin-right:0; }
#media (max-width: 3boxThreshold) {
.box:nth-child(3n) { margin-right:0; }
}
#media (max-width: 2boxThreshold) {
.box:nth-child(2n) { margin-right:0; }
}
However, the n-th child selector isn't a valid selector for older browsers so you would need to add some jQuery instead:
$(document).ready(function(e) {
removeMargin();
$(window).resize(function() {
removeMargin();
});
function removeMargin() {
var wW = $(window).width();
// Resets the boxes
$('.box').css("margin-right", "insertDefaultValueHere");
if (wW < 3boxThreshold)
$('.box:nth-child(3n)').css("margin-right", 0);
else if (wW < 2boxThreshold)
$('.box:nth-child(2n)').css("margin-right", 0);
else
$('.box:nth-child(3n)').css("margin-right", 0);
}
});

Use negative margins on the container and get rid of your clearfix divs:
http://codepen.io/cimmanon/pen/dwbHi
#container {
margin: -20px 0 0 -20px;
overflow: hidden;
}
#container .box {
margin: 20px 0 0 20px;
}

Instead of floating the .boxes, you can use display: inline-block and
add text-align: justify to #container.
But it still wouldn't work as expected yet, so you take the extra div you used for clearfix and relegate it to the bottom of the #container in the markup.
Then you change the name of the class from .clearfix to something like .spacer;
the spacer class will have: display: inline-block and width: 100%.
You will also need to give .boxes vertical-align: top; otherwise the horizontal alignment can break if inline elements like text exists in the boxes.
You'll notice now that the boxes are arranged with proper spacing in between and the first and last boxes in a line stick to the edges.
JSFIDDLE
Markup:
<div id="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box">the last box needs no margin right when full width and responsive</div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box">the last box needs no margin right when full width and responsive</div>
<div class='spacer'></div>
</div>
CSS:
* {
box-sizing: border-box; /* www.paulirish.com/2012/box-sizing-border-box-ftw/ */
}
#container {
width: 480px;
border:1px solid black;
text-align: justify;
}
.box {
display: inline-block;
vertical-align: top;
width: 100px;
height: 100px;
background:red;
margin-bottom:20px;
color:white;
}
.spacer {
display: inline-block;
width: 100%;
}
Here's an article which explains more about this method http://www.barrelny.com/blog/text-align-justify-and-rwd/.

Related

Div width is like width of page for some reason

I have a page with some divs there.
HTML:
<div class="utilitiesHeader">
<div id="utilitiesLogo"></div>
<div id="utilitiesFIO">Name of user</div>
</div>
<div class="utilitiesContent">
<div class="utilitiesCommon">Comon</div>
<div class="utilitiesArchive">Archive</div>
<div class="utilitiesReadings">Readings</div>
</div>
CSS:
div#utilitiesLogo {
width: 226px;
height: 101px;
background: url("../images/feelinhome-logo.png") no-repeat 0 0;
margin: 0;
}
div#utilitiesFIO {
float:right;
font-size: 30px;
}
div.utilitiesHeader {
display:inline;
}
As you can see in fiddle div with Name for some reason is on the other string and logo div is in width of all page, however I give it certain width. What's the reason?
The problem is that you set the utilitiesHeader with display:inline but: width does not apply to an inline element! - so the utilitiesHeader won't confine the elements according to the width of the utilitiesLogo (which has a set width)
See the spec regarding the width property:
Applies to: all elements but non-replaced inline elements, table
rows, and row groups
To fix this set display:inline-block on the utilitiesHeader.
FIDDLE

5 same size elements, on the same line, with margin

I have an issue and I can't find the right keywords on Google.. But it seems prettry "classic".
I have a webpage, let's say with a max-width of 1500px;
I want to add a line, with 5 "boxes" (div) of the same size each, separated with a margin.
So I set a width of 20%, and a margin-right of 10px. My issue is that my last div always goes down to the next line, because of the margin. (Because with the margin, the width of my line is higher than the max-width of the page).
If I remove the margin, all the boxes are correctly on the same line.
What should I do to make it work ? (Except using outerWidth of jQuery, it is my next step if I can't do it easily with css)
Here is my code the code I have now :
<div id="page">
<div id="numbers">
<div class="numberwrap">
<div class="number">
Number
</div></div>
<div class="numberwrap">
<div class="number">
Number
</div></div>
<div class="numberwrap">
<div class="number">
Number
</div></div>
<div class="numberwrap">
<div class="number">
Number
</div></div>
<div class="numberwrap">
<div class="number">
Number
</div></div>
</div>
</div>
#page
{
max-size: 500px;
background-color:grey;
}
.number
{
background-color:white;
}
.numberwrap
{
float:left;
width:20%;
padding-right:10px;
}
I also made a fiddle, to test : http://jsfiddle.net/jKMp5/
Thank you !
Solution : I just have to set the padding property on the .number, not the wrapper !
Or use box-sizing !
Thanks to everybody
Div's with a width percentage adds margins and paddings width on to that.
Meaning a div with width 50% amd margin-right: 20px; will be 50% + 20px.
You can do the following.
<div style="width: 20%;">
<div style="margin-right: 20px;"></div>
</div>
That will sort it out.
or just the following
.number
{
background-color:white;
padding-right:10px;
}
.numberwrap
{
float:left;
width:20%;
}
The problem is (as you already said) that the margin is affecting to each div making it bigger than that 20%, so one solution could be to tell to that div that the margin is included in the total width with the property box-sizing
So add:
.numberwrap {
box-sizing: border-box;
}
See jsFiddle example: http://jsfiddle.net/jKMp5/2/
In the default box modal,
The padding area extends the content area with the empty area between the content and the eventual borders surrounding it.
You can change this behavior using box-sizing property by applying box-sizing:border-box
border-box:
The width and height properties include the padding and border, but not the margin.
.numberwrap
{
box-sizing:border-box;
/*other styles*/
}
Demo
You can use disaply:table and display:table-cell:
css
#page
{
max-size: 500px;
background-color:grey;
}
.number
{
background-color:white;
}
.numberwrap
{
float:left;
width:20%;
padding-right:10px;
display:table-cell;
/*border: 1px solid black;*/
}
#numbers{
display:table;
}
fiddle

Neatly centering a div between one floated left and one floated right

If I have a div which I want to center between two other divs, one floated left and one floated right, giving it a margin of exactly 10 pixels on either side (between it and the div on that side), how would I give it a fluid width, such that it would get wider or narrower as the window size is changed, but always maintain a distance of exactly 10 pixels between it and the divs on either side?
Try this fiddle. Solution works with pure CSS.
The trick is: width: 230px; /* 10 more width than column size */
http://jsfiddle.net/ngdS9/1/
Here's a fiddle of my answer:
http://jsfiddle.net/utThB/
If your left and right div elements are of variable witdh, the only way I can see this done is to dynamically get the width of the left and right divs via jQuery (or pure JavaScript, ask me for this version) and then adding the margin style to the centered div.
jQuery:
$(document).ready(setWidth);
function setWidth(){
var $left_width = $(".left").width() + 10;
var $right_width = $(".right").width() + 10;
$(".center").css("margin-left",$left_width + 'px');
$(".center").css("margin-right",$right_width + 'px');
}
HTML:
<div class="container">
<div class="left">Variable width DIV</div>
<div class="right">Another.</div>
<div class="center">Centered Div</div>
</div>
CSS:
.container{width:100%;}
.left{
float:left;
background-color:green;
}
.center{
text-align:center;
background-color:blue;
width:auto;
}
.right{
float:right;
background-color:red;
}
Try this. Here's a fiddle
HTML
<div id=wrapper>
<div id=leftdiv>left</div>
<div id=rightdiv>right</div>
<div id=main>
Lorum Ipsum
</div>
</div>
CSS
#main {
padding-right:60px;
padding-left:60px;
}
#leftdiv {
float:left;
width:50px;
background-color:#ddd;
}
#rightdiv {
float:right;
width:50px;
background-color:#ddd;
}

Position 3 divs

I have 3 divs, 'left div', 'right div' and 'bottom div'. I have been hopelessly trying to position them in a certain way but it just doesn't work. This is how I would ideally like them to be:
The main problem is the fact that 'left div' and 'right div' are of different heights so how would I sort this mess out?
EDIT: I would also like to add that the left and right divs need to be centered within the content area.
<div id="content">
<div class="left">
Left
</div>
<div class="right">
Right
</div>
<div class="bottom">
Bottom
</div>
</div>
css:
#content{
width:1000px;
margin:0 auto;
}
.left{
width:495px;
float:left;
margin-right:10px;
}
.right{
width:495px;
float:left;
}
.bottom{
clear:both;
margin-top:10px;
}
then if you want the left and right to match:
(using jquery)
$(document).ready(function(){
var leftdiv = $('.left').height();
var rightdiv = $('.right').height();
if(leftdiv > rightdiv)
$('.right').css('height', leftdiv + 'px');
else
$('.left').css('height', rightdiv + 'px');
});
Statically set their heights or use javascript to match them if the height is dynamic based on content.
Here's the HTML for the divs, remove the #container if you don't want to center them:
<div id="container">
<div class="left">Left</div>
<div class="right">Right</div>
<div class="bottom">Bottom</div>
</div>
Here is the CSS:
#container {
width: 200px;
margin: 0 auto;
}
.left {
float: left;
width: 100px;
background: silver;
}
.right {
float: right;
width: 100px;
background: red;
}
.bottom {
clear: both;
background: aqua;
}
I just used the colors to highlight the position. You can of course change the widths of the divs, but remember that the #container width has to be the width of .left + .right.
Read this to find out more about floats.
You can find a demo of the code here: http://jsfiddle.net/teaJb/
float the left and right div's to their respective directions. set identical padding right and left on the containing div. on the bottom div apply "clear:both" to clear the float and "margin:0 auto" to center it relative to the container.
if you don't match the heights, obviously the bottom div would appear after the higher div. you can match height using jquery's .height() method to compare the actual heights and set the higher value for both divs. Alternatively, you can just set a CSS rule for a constant height or a dynamic min-height.

How to set auto-margin boxes in flexible-width design using CSS?

I have DIV with flexible width set e.g. min-width:800px and max-width:1400px. In this DIV, there are many boxes with fix width 200px and display:inline-block. So depending on parent DIV width, these boxes fill the entire space.
My problem is the blank space on the right side which is caused by variable width of the parent div. Sometimes this blank space is small and looks fine, but with different widths of the parent div, this blank space is almost 200px.
I don't know, if I described my problem in enough detail, I hope this picture will help to describe my actual situation:
And this is what I would like to have:
This auto-margin could be easily achieved by using TABLE. However, I don't know the exact number of columns, since it depends on user's screen resolution. So I can't use table and rather stick with CSS.
Anyone has an idea how to solve this ? Thank you in advance for your comments and answers.
EDIT: I don't need support of IE6. I would like to support IE7, but IE7 is optional as I know there are limitations so I will probably use fixed width of "div.wrapper" in IE7
EDIT2 I need to handle multiple rows of these boxes, so they don't exceed the "div.wrapper" box and wrap correctly in multiple lines of boxes, not just in one long line.
EDIT3 I don't know the number of "columns" as this is very variable depending on user's screen resolution. So on big screen there could be 7 boxes in one row, and on small screens there could be just 4 boxes in one row. So I need solution that doesn't set fixed number of boxes in one row. Instead, when the boxes don't fit in one row, they should just wrap to a next row.
This is as close as IE7-compatible CSS can get: http://jsfiddle.net/thirtydot/79mFr/
If this still isn't right, it's time to look at using JavaScript and hopefully also jQuery. If you define your requirements properly, it should be trivial to get this perfect with JavaScript.
HTML:
<div id="container">
<div></div>
<div></div>
..
<span class="stretch"></span>
</div>
CSS:
#container {
border: 2px dashed #444;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
min-width: 800px;
max-width: 1400px
}
#container > div {
margin-top: 16px;
border: 1px dashed #f0f;
width: 200px;
height: 200px;
vertical-align: top;
display: inline-block;
*display: inline;
zoom: 1
}
.stretch {
width: 100%;
display: inline-block;
font-size: 0;
line-height: 0
}
The extra span (.stretch) can be replaced with :after.
This still works in all the same browsers as the above solution. :after doesn't work in IE6/7, but they're using distribute-all-lines anyway, so it doesn't matter.
See: http://jsfiddle.net/thirtydot/79mFr/2/
There's a minor downside to :after: to make the last row work perfectly in Safari, you have to be careful with the whitespace in the HTML.
Specifically, this doesn't work:
<div id="container">
<div></div>
<div></div>
</div>
And this does:
<div id="container">
<div></div>
<div></div></div>
You need to make .box inline-blocks, and justify text in .wrapper. .wraper:after is needed to justify the last line. Older IEs don't understand after, but in IE text-align-last:center will take care of the last line.
.wrapper{
text-align:justify;
max-width:1400px;
min-width:800px;
text-align-last:center;
}
.wrapper:after{
content:'';
display:inline-block;
width:100%;
height:0;
font-size:0;
line-height:0;
}
.box{
display:inline-block;
*display:inline;
vertical-align:top;
width:200px;
height:50px;
background:red;
}
Here's a jsfiddle.
You can float them and just apply a wrapper to the .box which will allow you to margin:auto; the .box relative to the floated wrapper.
CSS:
div.wrapper {
width:100%;
border:3px solid red;
}
div.clear {
clear:both;
}
div.box-wrapper {
float:left;
margin:10px 0;
height:100px;
width:20%;
}
div.box {
border:1px solid black;
width:80px;
height:100px;
margin:auto;
}
HTML:
<div class="wrapper">
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="box-wrapper"><div class="box"></div></div>
<div class="clear"></div>
</div>
Demo: http://jsfiddle.net/2avwf/
I didn't make them 200px wide for the sake of the fiddle window. Just swap that width:80px out with the width you desire.
If you want to make this a dynamic solution, in which the number of boxes in a row will vary from user to user based off their screen size, etc., simply make 3 or 4 width-defining box-wrapper classes:
.box-wrapper-25 {
width:25%;
}
.box-wrapper-33 {
width:33%;
}
Then with JQuery you can easily detect the width of .wrapper and assign an override class to the box wrappers:
$('.box-wrapper').each(function(){
$(this).removeClass().addClass('box-wrapper box-wrapper-25'); // only need 4 per row
});
Something like this: http://jsfiddle.net/RcDky/
Try this jsFiddle: http://jsfiddle.net/MKuxm/
Just make the window larger and smaller to size the div, you'll see that the margin between the red boxes will size accordingly. I am aware that the red boxes are no longer 200px wide, but I'm afraid that isn't possible with pure css because you should not mix percentage widths and fixed pixel width.
HTML
<div>
<span>TEXT</span>
<span>TEXT</span>
<span>TEXT</span>
<span>TEXT</span>
</div>
CSS
div {
width: 95%;
}
span {
float: left;
background: red;
width: 20%;
margin-left: 2.5%;
margin-right: 2.5%;
}
I answered a similar question here
This is possible in pure css3 using media queries and the css calc() routine.
Of coarse this will only work on modern browsers. IE9+,Chrome,Firefox,
See this WORKING DEMO
The basic idea is to set up a media query for each #columns states, where I then use calc() to work out the margin-right on each of the elements (except the ones in the last column).
On my project I have faced with the same problem and I came to the next decision - the best way for me is to go with js, in my case you can have xxx count of block inside container, if there is enough space in 1st row the block from 2nd row goes up to the 1st row, and so on.
here is an example http://jsfiddle.net/gVAjN/11/
$(function() {
// Call function when DOM is ready
settingsAlignment();
$(window).resize(function() {
// Call function on window resize
settingsAlignment();
})
$('#new_div').click(function() {
box_number = $('.element').size();
box_add = box_number + 1;
$('.container').append($('<div class="element">Box'+ box_add + '</div>'))
settingsAlignment();
})
function settingsAlignment() {
// calculation of ul's padding-left and li's margin-right
var settingsUl = $('.container');
settingsLi = $('.element');
ul_width = settingsUl.outerWidth(true);
item_width = settingsLi.width();
min_gap = 7;
effective_item_width = item_width + min_gap;
items_in_row = Math.floor((ul_width - min_gap) / effective_item_width);
gaps_sum = ul_width - items_in_row * item_width;
new_gaps = gaps_sum / (items_in_row + 1);
item_margin = Math.floor(new_gaps);
row_width = (item_width + item_margin) * items_in_row - item_margin;
console.log(row_width + '= row_width');
console.log(ul_width + '= ul_width');
ul_left_padding = Math.ceil((ul_width - row_width) / 2);
console.log(ul_left_padding + '=ul_left_padding');
settingsUl.css('padding-left', ul_left_padding + 'px');
settingsLi.css('margin-right', item_margin + 'px');
console.log(settingsLi);
}
});
quite old but worth trying since multiple rows and text-align: justify; in the #container creates gaps when last row has less divs. I wanted everything to be floated left. So my idea was to use 2 wrappers.
<div class="wrapper">
<div class="wrapper2">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="clear"></div>
</div>
</div>
as well as overflow: hidden; in css
.wrapper {
width:620px;
border:3px solid red;
margin:0 auto; overflow:hidden;
}
.wrapper2 {
width:630px;
}
div.clear {
clear:both;
}
.box {
width:200px; background:#000; height:100px; margin-bottom:10px; float:left; overflow:hidden; margin-right:10px;
}
drawback: margins are not auto set...
DEMO: http://jsfiddle.net/hexagon13/2avwf/52/
Try this:
div.wrapper {
display: flex;
align-items: stretch;
width: 100%;
height: 100%;
justify-content: space-between;
/* justify-content will give the auto margin you looking for
it will place the auto margin only between each div.box
make sure the div.wrapper has "display: flex;"
*/
}
div.box {
display: inline-flex; /* inline-flex will make the boxes all in the same line */
width: 200px; /* notice you don't need width to be a % for this to work */
height: 100%;
margin: auto; /* gives you the auto margin for the first and last box from the border of your wrapper */
}