DIV width to content of other DIVs, floating and centering all - html

I would like to achieve something that initialy looked simple to me but turned out to be not.
My code is:
<html>
<head>
<style>
div {
border-top: 1px solid black;
margin: 10px;
}
div#all {
border: 0;
}
</style>
<body>
<div id=all>
<div class=first>First</div>
<div class=rowstarter>Row Starter</div>
<div class=content>Content</div>
<div class=content>Content</div>
<div class=content>Content</div>
<div class=content>Content</div>
<div class=content>Content</div>
<div class=rowstarter>Row Starter</div>
<div class=content>Content</div>
<div class=content>Content</div>
<div class=rowstarter>Row Starter</div>
<div class=content>Content</div>
<div class=content>Content</div>
<div class=content>Content</div>
<div class=content>Content</div>
</div>
</body>
</html>
What I'd like to get is all DIVs in "content" class are inline-blocks (or floats) set one after another from left to right.
The "rowstarter" class is the same but has to clear the before floats (start a new row).
The "first" DIV has to have a width equal to the content below (so if the window width allows the browser to display 5 "content" DIVs in a row, each having 100px width then "first" has 5 * 100px + 5 * (2 * 10px [margins]) = 600px if 6 "content" DIVs then "first" has 720px width...).
Is this possible without using Javascript, only with CSS?

As the number of content divs is going to be dynamic, you will need to use javascript in order to achieve what you want. There is no css that will allow you to do calculations to work out a percentage width based on number of child elements.
The alternative to javascript would be if you knew how many divs are in each row while you are generating your html, you can add inline styles for the widths
Here are some examples
Pure css (needs html layout change)
jQuery

I have posted a fiddle which I believe answers your question.
First, you have to give #all and each child div, except for .first, a left float:
#all,
#all div {
float: left;
}
#all .first {
float: none;
}
Then, clear .rowstarter on the left.
#all .rowstarter {
clear:left;
}
You actually don't need the "content" class at all (and I would recommend removing it, as it clutters the code and adds to the page weight).
Edit: If you add a .rowstarter div in front of the .first div, .rowstarter has to have a fixed width and the left margin of .first needs to increase by the sum of the width and margins of .rowstarter.
#all .rowstarter {
width: 100px; // arbitrary fixed width
margin: 10px; // you've given all divs inside #all this margin, just restating for emphasis
}
#all .rowstarter + .first {
margin-left: 130px; // width of .rowstarter, plus its left and right margins and .first's original 10px left margin
}
To achieve the centering of div#all you have to add a wrapper around it, then apply the following css trick:
.wrapper {
position: absolute;
left: 50%;
}
#all {
position: relative;
left: -50%;
}

I have set up a jsFiddle that probably answers your question. It now also contains the width but the added code is without any width so you are free to use what you want now
http://jsfiddle.net/agtFw/3
The HTML:
<div id="all">
<div class="first">First</div>
<div class="content rowstarter">Row Starter</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content rowstarter">Row Starter</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content rowstarter">Row Starter</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
<div class="content">Content</div>
</div>
it is no problem to give 2 or more classes to a div and it helps you a lot sometimes!
and the css:
div {
border-top: 1px solid black;
margin: 10px;
}
div.content
{
float:left;
}
div.rowstarter
{
clear:left;
}
div#all {
border: 0;
}

Related

How do I center left-floated elements?

I have a container of various width, and various number of boxes float inside it. All the boxes have same width and height.
This is a demonstration.
https://jsfiddle.net/kghvmjb6/1/
I am looking for pure CSS solution if possible. Otherwise pure javascript (no jQuery) and CSS solutions are fine.
This example works fine with one line of floating boxes but fail with multiple lines, which is not I want.
https://codepen.io/alexandredees/pen/ojaFr
Instead of using float left, use display inline-block and in the parent div add text-align center, that will center the boxes in the container
Modified Fiddle
HTML
<div class="container">
<div class="">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="clear"></div>
</div>
</div>
CSS
.container {
border: 1px solid red;
width: 480px; text-align:center;
}
.container.wider {
width: 530px;
}
.box {
float: none;
width: 80px;
height: 80px;
margin: 10px;
background-color: #ddd;
display:inline-block;
}

Content displaying issues

I am having an issue aligning two different elements to where they are parallel horizontally. I am wanting the second grid right_service_wrap to appear on the right side of the page just like the left_service_wrap. I am not sure what I am doing wrong that the float right is appearing below the left_service_wrap.
Anyone have any ideas??
.left_service_wrap {
}
.right_service_wrap {
float: right;
display: inline;
}
.title_left {
margin-left: 20%;
}
.title_right {
}
.service_wrapper {
border: 1px solid black;
margin: 15px;
width: 20%;
}
.service_list {
margin-left: 20%;
}
<div class="left_service_wrap">
<div class="title_left">A LIST OF OUR SERVICES</div>
<div class="service_list">
<div class="service_wrapper">
<div class="service_title">Flooring</div>
<div class="service_description">The best floors!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Roofing</div>
<div class="service_description">Your roof will be perfect!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Siding</div>
<div class="service_description">mmmm siding.</div>
</div>
<div class="service_wrapper">
<div class="service_title">Paint</div>
<div class="service_description">Fabulous paint!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Kitchen Remodels</div>
<div class="service_description">Pretty kitchen.</div>
</div>
</div>
</div>
<div class="right_service_wrap">
<div class="title_right">A LIST OF OUR SERVICES</div>
</div>
Set the width of both to 50% and do:
.left_service_wrap {
float:left;
width:50%;
}
.right_service_wrap {
float: left;
width:50%;
}
Working demo here: https://jsfiddle.net/usrce45v/
Consider that your requirement of an extra left margin to be applied to the left container requires you to rearrange the width of both left and right containers. So, for a left-margin of 20% the equation becomes:
whole parent width (100%) minus margin (20%), half the result (40%).
I am not sure if I fully understand your question, but if it is what I think, you have to add float: left to the .left_service_wrap class rule. (and define a width for it that allows the elements in it to be displayed as desired)

CSS DIV Alignment with dynamic content

My question is about CSS and DIV tags. I have a dynamic page, and I would like one container DIV. There are two scenarios: in one case, this container DIV will just have one DIV in it, with a width of 50%, and should be centered. In the other case, there will be two DIVs in it, and they should be side by side, each taking up 50%.
I have tried float:center (using overflow: hidden on the container DIV), and that works for 1 DIV in it, but with two, they are stacked on top of each other. If I use float: left, then the 2 DIVS appear correct, but the single DIV is left aligned, not centered.
Any help on how to achieve this effectively would be greatly appreciated!
<div style="width:800; margin: 2px; background-color:blue">
<div style="width:50%; background-color:orange;">
Text
</div>
<div style="width:50%; background-color:red;">
Text
</div>
</div>
jsFiddle
For the two-div scenario:
<div style="width:800; margin: 2px; background-color:blue; display: table;">
<div style="background-color:orange; display: table-cell;">
Text
</div>
<div style="background-color:red; display: table-cell;">
Text
</div>
</div>
Now for the one-div scenario:
<div style="width:800; margin: 2px; background-color:blue; display: table;">
<div style="background-color:orange; display: table-cell;">
Text
</div>
</div>
In each case, the inner divs, whether there are 1 or 2, will take up a combined 100% of the outer div. Essentially, it acts like the <table> element without having the semantics of a <table>.
check this fiddle
HTML
<div class="wrapper">
<div class="divholder">
<div style="background-color:orange;">DIV 1</div>
<div style="background-color:red;">DIV 2</div>
</div>
</div>
CSS
.divholder div{
display:inline-block;
margin:auto;
width:49%;
}
.divholder {
text-align:center;
margin: 0 auto;
position:relative;
}
.wrapper{
width:100%;
background-color:blue;
}
This perfectly deals with your need..While there is only one div, the div gets centered and if two divs come then both will be equally divided and floated left.Please see the fiddle..
Similar to chharvey's answer, this can be achieved nicely with display: table;
In my example it is centered horizontally and will work with any number of columns as they will fit themselves to the full width of div.wrap. The columns are currently given a height of 100%, this can be adjusted.
Have a jsBin example!
HTML
<div class="wrap">
<div class="column">
</div>
<div class="column">
</div>
</div>
CSS
html,body {
height: 100%;
}
.wrap {
display: table;
width: 800px;
height: 100%;
margin: 0 auto;
}
.column {
display: table-cell;
background: #FF0;
}
.column:first-child {
background: #F00;
}

Items grid with inner padding only

What techniques are there for creating a products grid that has padding between each item, but only within the grid? For example, what I am trying to achieve is the below:
Sample markup:
<div id="container">
<div class="item">
<!-- content -->
</div>
</div>
CSS:
#container { width: 100%; min-width: 960px; }
.item { float: left; width: 300px; height: 100px; }
(in the above, .item is going to be output 9 times).
The solution would need to be IE8+ compatible and preferably using a technique that isn't a hack. I have tried using display: table with border-spacing property - but this outputs the padding on the outer sides too.
I know I can also add specific classes to items to control whether the padding is shown for that item, but I was hoping for a more 'automated' solution.
Edit: The padding width should be calculated dynamically, so for example if the container is 960px, the padding is going to be 30px wide.
Secondly, if there are less than 3 items on the last row, these should not appear centered on the row, i.e. if there are only two items then the last 'cell' should just be empty.
EDIT: All the solutions so far insist on specfying the width of the gap/padding. I want to have the padding calculated dynamically. The only width I need to specify is that of .item, which is currently a fixed with of 300px.
Responsive grid with :
fluid width items
inner fluid gaps between them
IE8+ support (at least)
DEMO
add a general percent margins to the items with percent widths, make sure elements widths + left/right magins = 100%;
compensate the outer margins (between container and items) by setting a negative margin of the same value on the container
add a general wrapper with overflow:hidden;
This is simple and doesn't use any properties unsuported by IE8. I am pretty sure it can have a decent output in IE7 if you remove the borders and the box-sizing property.
Just to make sure, negative margins are not a "hack" :
Negative values for margin properties are allowed source : w3.org
HTML :
<div id="wrapper">
<div id="container">
<div class="item"></div>
<div class="item"></div>
...
</div>
</div>
CSS :
#wrapper {
overflow:hidden;
}
#container {
margin: -1.5%;
background:lightgrey;
}
#container:after {
content:'';
display:block;
clear:both; /* clear the floats */
}
.item {
margin:1.5%;
width:30.3333%;
padding-bottom:10%; /* to simulate height on the empty items */
background:grey;
border: 1px solid #000;
float:left;
/* following only if you want to add borders to the items */
box-sizing:border-box;
}
After, you just need to change the width of the .items with media query to rearange the number of elements in one row on the desired breakpoints.
Example :
#media screen and (max-width: 600px) {
.item {
width:47%;
}
}
Please don't consider this a formal answer. Josh's is clearly elegant.
I like these types of questions because it gives me an opportunity to think of a variety of ways to approach a problem. I've used tables and floated divs to give a total of 4 other ways to do this. If I can think of any more, I'll add them.
The FIDDLE.
The first table in HTML, just to fulfill the SO requirements.
HTML
<table class='table1'>
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
</table>
"Tables are inelegant" -(except for tabular data)
Here is one approach using :nth-child. (example)
Just give each element a top/left border, then remove the top border for the first three and then remove the left border for the first, fourth, and seventh elements.
.item {
float: left;
width:300px;
height: 100px;
background:lightgrey;
border-left: 30px solid #fff;
border-top: 30px solid #fff;
}
.item:nth-child(-n+3) {
border-top:none;
}
.item:nth-child(3n + 1) {
border-left:none;
}
The padding width should be calculated dynamically, so for example if the container is 960px, the padding is going to be 30px wide.
You could use calc() for that.
Something like width:calc(33.333% - 20px) would work. This would limit the support to IE9 though.
Full Screen Example
Secondly, if there are less than 3 items on the last row, these should not appear centered on the row, i.e. if there are only two items then the last 'cell' should just be empty.
This should work as expected - example with the ninth item removed.
I thought I'd throw in a quick responsive example for usage in Bootstrap.
Using Bootstrap's grid system, the following CSS will remove any margin on the outer touching columns of a 3-column (per row) grid:
.tight-grid div[class*='col-']{
margin-top:15px;
margin-bottom:15px;
}
.tight-grid .row:first-child div[class*='col-'] {
margin-top:0;
}
.tight-grid div[class*='col-']:nth-child(3n+3){
margin-right:0;
}
.tight-grid div[class*='col-']:nth-child(3n + 1) {
margin-left:0;
}
.tight-grid .row:last-child div[class*='col-'] {
margin-bottom:0;
}
Keep in mind that columns already have left and right padding applied by bootstrap (15px worth). So if this is not the desired amount, override it in the first style rule of the above css snippet.
DEMO | CODE
NOTE: I know OP didn't ask for bootstrap, specifically. I just wanted to provide a simple way to do is using bootstrap for fun :)
Following your specification, this is:
Grid of items based on Divs;
Dynamically calculated spacing between items;
Cross Browser;
Specific item and container widths;
No hardcoded item classes to specific to the grid layout.
You can achieve that with this set of styles:
/* ensures the height correctness for the parent of .item, the #products. */
.clearfix{ clear:both }
#products{ border:1px solid gray; width:960px;}
.item{
float:left;
background-color:silver;
border:1px solid blue;
width:300px;
height:100px;
margin-left:2.5%;
margin-top:2.5%;
}
/* fixes top margin. */
.item:first-child, .item:first-child + *, .item:first-child + * + *{
margin-top:0px;
}
/* fixes margin of first divs on the left. */
.item:first-child,
.item:first-child + * + * + *,
.item:first-child + * + * + * + * + * + *,
.item:first-child + * + * + * + * + * + * + * + * + * {
margin-left:0px;
}
HTML
<div id="products">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="clearfix"></div>
</div>
You can watch this on JSFiddle.
Assumptions
I've added a div to the end of the container to ensure that it's height as in consideration the floated div's height. You can adjust this based on your specific overall disposition of html elements.
The margin-left fix implemented through this kind of rules .item:first-child + * + * + * is due to the cross browser requisite. I used the first-child selector with the '*' selectors, because it is supported by all main browsers (IE6+, FF, Chrome, SF, Opera). It's in fact hardcoded, but my idea about it, is that, if you want something less hardcoded then you can replace those rules by a rule targeting .item-head (the class that should be on all items next to the left border).
Anyway, I think that based on my simple solution, you can very easily evolve it to your desired solution. Have Fun!
I have somewhat of a solution, but it's not exactly what you're looking for, because I don't think what you want can be done without a solution that makes use of :nth-child (either natively or with a JS polyfill).
Take a look at my sample: http://jsfiddle.net/ncA64/1/
I've built product grids just like this many times. It gives you a fixed margin of 30px around each tile, and the width of each tile flexes to accommodate the width of the parent.
Code, for reference. HTML:
<div id="container">
<div class="item">
<div class="inner">
<!-- -->
</div>
</div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
<div class="item"><div class="inner"></div></div>
</div>
and CSS:
/* basic box model reset */
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
margin: 0;
border: none;
}
#container {
min-width: 960px;
margin: -30px -15px 0;
overflow: hidden;
}
.item {
width: 33.333333%;
float: left;
background: #fff;
}
.item .inner {
min-height: 100px;
margin: 30px 15px 0;
border: 1px solid #000;
background: #ffc;
}
text-align: justify for the container and display:inline-block for the items with no float (it float anyway... it's inline now).
Simple, responsive and works on lot of older browsers
EDIT: Forgot to say "and a additional div, to clear at the end, also display-inline, but 100% width"
http://jsfiddle.net/qFEB7/1/
Test this code:
body {
margin:0;
padding:0;
}
#wrapper {
overflow:hidden;
width:1200px;
margin:100px auto;
padding:10px;
display:table;
}
#container {
display:table-row;
}
.item {
width: 33.3333%;
min-height: 20px;
height: auto !important;
max-height: 200px;
word-wrap: break-word;
border-right:1px solid #ddd;
display:table-cell;
padding:10px;
border-bottom:1px solid #ddd;
border-top:1px solid #fff;
}
#container .item:first-child{
border-left:1px solid #ddd;
}
#container:first-child .item{
border-top:1px solid #ddd;
}
// use the html
<div id="wrapper">
<div id="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div id="container">
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div id="container">
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
<div id="container">
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
</div>
</div>

Floats in CSS - Gap/space left on top when floated to the right?

This is a little difficult to describe, but basically there is undesired space left by a floated div on my page. Here are pictures describing the problem. The black boxes are divs.
Before floating:
After floating:
Desired effect:
And I'm not sure if it makes a difference, but I also have an empty div with "clear: both" placed immediately after the floated div.
How can I achieve this?
If possible, put the float: right div before the unfloated div in the HTML.
<div class="a1">a1</div>
<div class="a2">a2</div>
.a1
{
background-color:Red;
width:200px;
height:200px;
float:left;
}
.a2
{
background-color:Green;
width:200px;
height:200px;
float:left;
}
=======try this
Remove the clearing div. Also check the padding/margin on those divs and ensure that the containing div (parent div) is wide enough to accommodate the two child divs.
The first div should have float: left set. Else the first div, which is a block element, will take up all the vertical space for itself.
HTML
<div id="container">
<div id="main">
blah blah blah blah blah
</div>
<div id="aside">
this goes to the side
</div>
<div id="clear"></div>
</div>
CSS
div#container
{
width : 80%;//your preference
height : auto;
margin : 0 auto;//Centers the page
}
div#main
{
width : 70%;
height : auto;
display : block;//to wrap it up inside its width
float : left;//float it towards left
}
div#aside
{
width : 30%;//take up rest of the width size
height : auto;
display : block;
float :right;//float towards right
}
#clear
{
clear : both;//this will do the job
}
The issue is youre only floating one div. You need to make the margin-right on the non foated div the same width as the total space (width+paddding+margin) of the floated div.
Or alternatiely you can float both divs.
Examples:
<div id="container" style="width: 410px;">
<div style="float: right; width: 200px;">
<p> Right div</p>
</div>
<div style="width: 200px; margin-right: 210px;">
<p> Left Div</p>
</div>
<div style="clear:both;"></div>
</div>
OR:
<div id="container" style="width: 410px;">
<div style="float: left; width: 200px; margin-right: 10px;">
<p> Left Div</p>
</div>
<div style="float: left; width: 200px;">
<p> Right div</p>
</div>
<div style="clear:both;"></div>
</div>
Both divs should float left and make sure they equal or are less than the width of the container they are in.
If a1 is to appear floated to the right of a2, then you have to put a1 FIRST in the html, and float it right. A bit counter intuitive, but its how floats work.
<div class="container">
<div class="a1">a1</div>
<div class="a2">a2</div>
</div>
<style>
div
{
border: solid 2px #000;
background-color: #eee;
}
.a1
{
background-color:Red;
width:200px;
height:200px;
float:right; /* the trick is, a1 appears BEFORE a2 in the html, yet
we are floating a1 right . if you do it the other way around
( try and float a2 ) then it will work like you showed
(separate line)*/
}
.a2
{
background-color:Green;
width:200px;
height:200px;
/* don't float this one */
}
</style>
There's a white space issue with floats. That's why the second box is slightly lower.
<div style="float:left">a1</div><div style="float:left">a2</div>
will work.
<div style="float:left">a1</div>
<div style="float:left">a2</div>
won't work