I've got a bunch of divs with background images like this:
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
...and so on (there are 20+ divs).
Each div has it's own background image.
Right now, on large screens I want to display 3 divs per line so I've got this:
#media screen and (min-width:768px) {
div {
width:33%;
}
}
What I would like is a 'gutter' that is 2ch wide between each div. When I use padding:2ch; it doesn't work (no space between divs) and when I use margin:2ch; then the 3rd div goes down to the next line (even with box-sizing:border-box).
What's the simplest solution to this? Here's an example of what I want the divs to look like (see each class image: http://www.platinumfitnessaz.com/classes/).
Thanks in advance.
Contrary to comments, percentage vs ch units has nothing to do with it. It's just the fact that you don't have enough room to fit things in a row.
If your page is 100% wide, then 3 divs in a row that are 33% wide will of course not leave any room for a margin. box-sizing only affects padding and borders, not margins, so that won't help you.
The solution is to use a calc() function.
If you want a 2ch space around your divs, use 2ch as the margin. Then, if you want three per row, you can use calc(33% - 2ch) to get the width of each one.
We only really need a right and bottom margin to achieve the effect you want:
div {
width: calc(33.333% - 2ch);
height: 150px;
float: left;
margin-bottom: 2ch;
margin-right: 2ch;
background-color: firebrick;
}
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
That's the simple version. It doesn't fully maximize our space, though, because there's a 2ch margin on the right of the third column of divs that could be reapportioned to the divs themselves.
To fully make use of all the space, we can do a little math to make our calc expressions a bit fancier, and then use nth-child to only apply the right margin to the divs in the first and second column:
div {
width: calc(calc(calc(calc(33.333% - 2ch) * 2) + 33.333%) / 3);
height: 150px;
float: left;
margin-bottom: 2ch;
background-color: firebrick;
}
div:nth-child(3n+1),
div:nth-child(3n+2) {
margin-right: 2ch;
}
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
<div>
<h1>Text</h1>
</div>
Related
If you’re trapped in a page wrap - say all the contents of the page are in a div whose width is 900px, then you want one div WITHIN that that’s the full page width. What’s the easiest way to do this?
I know you can end the 900px div, do the full width div, and then start another 900px div, but is there a way to style the inner div so you don't have to escape it? 100vw works for making it the right size but doesn't position it in the right spot.
So simplistic example:
<div style="width:900px;margin-right:auto;margin-left:auto;display:block;">
<p>text text</p>
<div style="width:100vw;">
<p>I want this section to be the full page width and centered</p>
</div>
<p>text text</p>
</div>
Thanks!
You can use negative left margin (-50vw + half parent width).
body {margin: 0;}
#a {background: red;}
#b {background: green; margin-left: calc(-50vw + 200px)
<div id="a" style="width:400px;margin-right:auto;margin-left:auto;display:block;">
<p>text text</p>
<div style="width:100vw;" id="b">
<p>I want this section to be the full page width and centered</p>
</div>
<p>text text</p>
</div>
For this code example I've added IDs (for cleaner CSS styles) and change parent div to 400px (because there is smaller window).
I don't recommend trying to make a child div "escape" its parent because going with that approach will require pointlessly complicated CSS. You can accomplish what you want with a container div and a couple nested children which is a much simpler solution:
.narrow {
width: 300px;
margin: 0 auto;
background-color: tomato;
padding: 16px;
}
.full {
background-color: gold;
padding: 16px;
}
<div>
<div class="narrow">
<p>text text text</p>
</div>
<div class="full">
<p>more text or image or whatever</p>
</div>
<div class="narrow">
<p>text text text</p>
</div>
</div>
I would argue that the way you are trying to solve the issue is not very helpful for an actual website. Normally, you would have a container, your top div, which contains its lower elements. Making a child element go outside its parent div like you seem to want goes against that mentality.
Of course, sometimes you may want to put an element outside its parent, and you can use pavel's answer. For example, maybe you want to animate a line moving. You would then offset that element by -100% and then change that offset to give it the impression of movement. But that would be a special case.
To solve your problem, I would use the following structure:
Here is a link to the example too.
<div class='container'>
<div class='thin'>
<p>text text</p>
</div>
<div class='full-width'>
<p>I want this section to be the full page width and centered</p>
</div>
<div class='thin'>
<p>text text</p>
</div>
</div>
.container{
text-align:center;
padding: 0 5vw; //padding of 5vw to the left and right
}
.thin{
width:80vw;
margin: 0 auto;
background-color:yellow;
}
.full-width{
background-color:green;
}
In the picture is what I am trying to achieve.
When resized, inner elements should stay as they are:
This is what I tried:
<div style="width:100%;text-align:center;">
<div style="width:80%;margin-left:auto;margin-right:auto;">
<div style="float:left;">
</div>
<div style="float:left;">
</div>
<div style="float:left;">
</div>
<div style="float:left;">
</div>
<div style="float:left;">
</div>
...
<div>
</div>
But when I resize it, it get like 2 in a row, or 5 in a row, depending on how I resize the screen. Should be 3 all the time, centered. Width of inner elements not to be changed.
Add classes if you can. HTML:
<div class="one">
<div class="two">
<div class="three">
</div>
<div class="three">
</div>
<div class="three">
</div>
<div class="three">
</div>
<div class="three">
</div>
...
<div>
</div>
...and CSS:
<style>
.one {width:100%;text-align:center;}
.two {width:Npx;margin: 0 auto;"}
.three {width:31%;margin:1% 10px;height:100px;float:left;box-sizing:border-box;}
.two .three:nth-of-type(3n + 1) {clear:left}
</style>
the inner div's need a fixed width (here, 1% on right and left) for a total width of 33%. Fixing height makes this work for variable content, otherwise, it looks off. The "nth-of-type) selector is a failsafe in case you can't use a fixed height.
Elaborating on using a fixed height, if you decide to parse your output with javascript to hide certain elements, they will still be counted in the "nth-child" iterative loop, which would break your layout. Using a fixed height and exact percentage widths should almost always work.
You'll note that there's 1% left over, but it's small enough not to be an issue.
EDIT:
Edited to add box-sizing:border-box;. Setting the box-sizing to border-box will include any added padding or border thickness to size, because if you add padding without it, your layout will break.
EDIT 2:
Reviewing OP's question, there is a requirement for the inner content to maintain a fixed width. The only way to do that is to declare a fixed with for .two or .three. Declaring a fixed width for .three will not center the content without additional css manipulation, so add a fixed width to .two.
Please note that a fixed width is a terrible idea for rendering in mobile, if your application needs that. I would suggest using a media query as follows, and swapping to the more popular two column layout for mobile:
<style>
#media screen and (max-width: 768px) { /* or whatever width... */
.two {width:auto;margin:auto;}
.three {width:46%;margin:2% 10px;}
.two .three:nth-of-type(3n + 1) {clear:none} /*cancels above */
.two .three:nth-of-type(odd) {clear:left} /* every two, clear left */
}
</style>
This will get you on the right track....
I have two divs on a page with the same height position. I'm trying to make them expandable, allot like what goes on in the WordPress dashboard area:
Now i've got the left div to expand but only with the right div staying at the same width. I need both to expand on zooming in and out.
any ideas how this is done?
I've been looking it up for the past hour but i cant find anything.
A link to a tutorial would be cool (good luck finding one).
EDIT:
Here guys, i found something similar: http://jsfiddle.net/Khez/2zLPF/embedded/result/
do you see how the two divs side by side expand? the green and blue ones...
If you want your divs to dynamically change depending on the width of their container, set the widths using percentages:
HTML:
<div class="column">
<div class="wrapper">
<p>Text</p>
</div>
</div>
<div class="column">
<div class="wrapper">
<p>Text</p>
</div>
</div>
CSS:
.column {
float: left;
width: 50%; }
.column div { margin: 0 20px; /* Set the spacing between the cells */ }
Preview: http://jsfiddle.net/Wexcode/F7h2C/
NOTE: Because you are setting the combined widths of the columns to 100%, you cannot add padding to .column if you want them to be on the same line. The inner div wrapper will allow you to add spacing between your two columns. You should apply all background attributes to .wrapper.
This is my html:
<div class="head" style="height: 100px;"></div>
<div class="wrapper">
<div class="col">col1</div>
<div class="col">col2</div>
<div class="col">col3</div>
</div>
css:
.col{
float: left;
width: 100px;
}
I'd like the three div.col have the same height, and the height is page-height - 100,
how to do that without JavaScript?(just css)
play with the fiddle: http://jsfiddle.net/mdDwY/
How about using absolute positioning and use top and bottom on the columns.
Have a look here: http://jsfiddle.net/JYnrp/4/
The other thing you could do is use any of the equal height techniques like the one linked by Sinan and put a padding-bottom on the body of 100px to keep the columns 100px away from the bottom.
One more faux solution is if the 3 columns have simple background colors, then giving the wrapper a 1px high strip image with the 3 background colors in it and repeat-y that and then the columns will be different heights but will appear to be the same height.
Matthew James Taylor's Equal Height Columns with Cross-Browser CSS is an old standby.
If I try to apply min-width, max-width to a floating div so that it expands to max-width when the right content is hidden does not work.
But, if I use table and 2 tds in it, the left td will expand to 100% if the right td is hidden.
Can I achieve this table effect with floated divs?
I don't think you can do what you are asking, but you can make it look like what you are asking.
Make it into two tds and put a max-width on a div inside the td. Would that work?
This isn't going to work with floats. Luckily we now have more tools at our disposal.
Here are two very simple methods to expand a div to 100% of the available width if a sibling horizontally to it is hidden or removed.
#1 – Using display: flex
Compatibility: Edge and all modern browsers. IE 10 and 11 support the non-standard -ms-flexbox.
The Basic Markup
<div class="container">
<div>
First Column
</div>
<div>
This second column can be hidden or not exist and the first column will take up its space
</div>
</div>
The CSS
The container div is given display: flex.
The containers children are give flex: 1 and they will be assigned equal width, can grow and can shrink.
.container {
width: 500px;
display: flex;
}
.container>div {
flex: 1;
background: #FF6961;
height: 200px;
margin-bottom: 20px;
}
.container>div:nth-child(even) {
background: #006961;
}
<div class="container">
<div>
Content
</div>
<div>
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when other divs are hidden.
</div>
<div style="display: none">
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when there is no other div.
</div>
</div>
Read this guide to flexbox
Read more about flexbox on the MDN
#2 – Using display: table
Compatibility: IE8+ and all modern browsers
The Basic Markup
<div class="container">
<div>
First Column
</div>
<div>
This second column can be hidden or not exist and the first column will take up its space
</div>
</div>
The CSS
The container is given display: table
The containers children are given display: table-cell and will act the same as cells in an HTML table. If a cell is hidden or is removed the other cell will take its space.
.container{
display: table;
width: 600px;
margin: 20px;
}
.container>div {
display: table-cell;
height: 200px;
background: #FF6961;
}
.container>div:nth-child(even) {
background: #006961;
}
<div class="container">
<div>
Content
</div>
<div>
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when other divs are hidden.
</div>
<div style="display: none">
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when there is no other div.
</div>
</div>
<div class="container">
<div>
Content takes up the remaining width if a cell has a fixed width.
</div>
<div style="width: 200px">
Content
</div>
</div>
Read more about CSS tables on the MDN