Keep space / padding between Divs - html

How would I be able to keep the space between my inlined div elements without counting the space as 'pixels'?
For example, currently i'm using margin-right (as my padding between my elements) but is eventually counting that as pixels (the result shows off ugly, see JsFiddle, div element gets pushed down).
#parent .child
{
position: relative;
display: inline-block;
height: 100%;
width: 16.5%;
background-color: green;
margin-right: 15px;
}
JsFiddle
Basically, I just like to have the first item floaten left and the last item floaten right. Now I know many of you guys are thinking, why not just use the feature 'justify'? I've tried using it, but it isn't a really good option since the amount of elements can be everything (10, 5, 8, etc).
Help would be appericiated!
EDIT: This basically is the feature i'd like to achieve but for multiple elements (instead of having only 1 row, there could be 2-16 rows.

You can use text-align: justify. It won't justify the last line, but you can force a new line with a pseudo-element:
#parent {
text-align: justify;
background-color: red;
}
#parent:after {
content: '';
display: inline-block;
width: 100%;
}
#parent .child {
display: inline-block;
height: 100px;
width: 16.5%;
background-color: green;
margin-right: 15px;
margin-bottom: 10px;
}
<div id="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

If I understand it properly, you want to set an internal margin between the children, but not between the edge children and the parent. Something like
.child { margin-right: 15px; }
.child:last-of-line { margin-right: 0; }
Currently there is no way to do that, but you can add an additional wrapper with a negative margin:
#inner-wrapper {
margin-right: -15px;
margin-bottom: -10px;
}
.child {
margin-right: 15px;
margin-bottom: 10px;
}
#parent {
background-color: red;
overflow: hidden;
}
#inner-wrapper {
margin-right: -15px;
margin-bottom: -10px;
}
.child {
vertical-align: top;
display: inline-block;
height: 210px;
width: 16.5%;
background-color: green;
margin-right: 15px;
margin-bottom: 10px;
}
<div id="parent">
<div id="inner-wrapper">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>

Related

CSS Flex items vertically and then horizontally

If container has fixed width and height, is it possible to move child elements to next line until there is enough space vertically and then, when there it no more vertical space, make last line child element take width space.
It is hard to verbally expain what I want to achieve, so here is JsFiddle of what I currently have: JsFiddle
.parent {
width: 400px;
height: 300px;
background: white;
border: 1px solid black;
display: flex;
flex-wrap: wrap;
overflow: hidden;
}
.child {
width: 160px;
height: 80px;
margin: 4px;
background: red;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Image of what I would like to achieve:
You can have something similar if you use a column direction. In this case, the overflow will occur on the right and not on the bottom:
.parent {
width: 400px;
height: 300px;
background: white;
border: 1px solid black;
display: flex;
flex-direction:column;
justify-content:flex-end;
flex-wrap: wrap;
overflow: hidden;
}
.child {
width: 160px;
height: 80px;
margin: 4px;
background: red;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

Flex-wrap property not responsive when parent has a set width

In the example below, when I set a width for a wrapper, the parent flex container can no longer use the flex-wrap property. The top two boxes won't wrap, but the bottom ones will.
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
.wrapper {
width: 700px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}
The 'issue' you raise is by design; you're specifying a width for the parent that is wide enough for your children to be wholly contained within (a 700px container for two 300px children). flex-wrap only causes elements to overflow when there's not enough space for the container to hold them. In your example, there is.
To force an overflow responsively, you could either specify a narrow width on the parent(which will cause an overflow for all viewports):
.wrapper {
width: 400px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
Or use max-width instead(which will only overflow on narrow viewports):
.wrapper {
max-width: 700px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>

Is there a way, othen than inline-block, for elements to don't break line?

I have elements wrapped into a parent div, and they're all floated to left. The parent element has overflow: scroll and when the parent become thinner than the children, i don't want the children to break line, but the parent to overflow them horizontally.
I've discovered that i can do this by using: display: inline-block for the children to behave text-like and then, set the parent to white-space: nowrap. This way, they will not break.
But i want a solution with the children floated. Can someone help me?
Working example
HTML
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
CSS
.parent{
padding: 3px;
width: 100%;
height: 200px;
background-color: green;
overflow: scroll;
/*does the trick*/
white-space: nowrap;
}
.child{
display: inline-block;
height: 190px;
width: 80px;
background-color: gray;
margin-left: 10px;
}
[edit] - Since Paulie asked in the comments, i've got to say that no, they don't have to be floated for working. I know this. But I want to know if there is another way to accomplish that and I think that there is no better place for this but the SO community
Flexbox can do that and it doesn't even need the white-space:nowrap.
.parent {
padding: 3px;
height: 200px;
background-color: green;
overflow: auto; /* or scroll */
display: flex;
}
.child {
height: 190px;
flex: 0 0 80px;
background-color: gray;
margin-left: 10px;
}
.parent {
padding: 3px;
height: 100px;
background-color: green;
overflow: scroll;
display: flex;
}
.child {
height: 90px;
flex: 0 0 80px;
background-color: gray;
margin-left: 10px;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
JSfiddle Demo
display: table does do that too, though flex is a more appropriate way to do layout than table, unless you need it to work on for example IE8/9, which flex doesn't, but then again, your inline-block is more appropriate than table
.parent{
padding: 3px;
max-width: 100%;
height: 200px;
background-color: green;
overflow: scroll;
display: table;
}
.child{
display: table-cell;
height: 190px;
min-width: 80px;
background-color: gray;
padding-left: 10px;
border: 1px solid white
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

Flexbox: 4 items per row

I'm using a flex box to display 8 items that will dynamically resize with my page. How do I force it to split the items into two rows? (4 per row)?
Here is a relevant snip:
(Or if you prefer jsfiddle - http://jsfiddle.net/vivmaha/oq6prk1p/2/)
.parent-wrapper {
height: 100%;
width: 100%;
border: 1px solid black;
}
.parent {
display: flex;
font-size: 0;
flex-wrap: wrap;
margin: -10px 0 0 -10px;
}
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 10px;
flex-grow: 1;
height: 100px;
}
<body>
<div class="parent-wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>
You've got flex-wrap: wrap on the container. That's good, because it overrides the default value, which is nowrap (source). This is the reason items don't wrap to form a grid in some cases.
In this case, the main problem is flex-grow: 1 on the flex items.
The flex-grow property doesn't actually size flex items. Its task is to distribute free space in the container (source). So no matter how small the screen size, each item will receive a proportional part of the free space on the line.
More specifically, there are eight flex items in your container. With flex-grow: 1, each one receives 1/8 of the free space on the line. Since there's no content in your items, they can shrink to zero width and will never wrap.
The solution is to define a width on the items. Try this:
.parent {
display: flex;
flex-wrap: wrap;
}
.child {
flex: 1 0 21%; /* explanation below */
margin: 5px;
height: 100px;
background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
With flex-grow: 1 defined in the flex shorthand, there's no need for flex-basis to be 25%, which would actually result in three items per row due to the margins.
Since flex-grow will consume free space on the row, flex-basis only needs to be large enough to enforce a wrap. In this case, with flex-basis: 21%, there's plenty of space for the margins, but never enough space for a fifth item.
Add a width to the .child elements. I personally would use percentages on the margin-left if you want to have it always 4 per row.
DEMO
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 2%;
flex-grow: 1;
height: 100px;
width: calc(100% * (1/4) - 10px - 1px);
}
Here is another apporach.
You can accomplish it in this way too:
.parent{
display: flex;
flex-wrap: wrap;
}
.child{
width: 25%;
box-sizing: border-box;
}
Sample:
https://codepen.io/capynet/pen/WOPBBm
And a more complete sample:
https://codepen.io/capynet/pen/JyYaba
I would do it like this using negative margins and calc for the gutters:
.parent {
display: flex;
flex-wrap: wrap;
margin-top: -10px;
margin-left: -10px;
}
.child {
width: calc(25% - 10px);
margin-left: 10px;
margin-top: 10px;
}
Demo: https://jsfiddle.net/9j2rvom4/
Alternative CSS Grid Method:
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
Demo: https://jsfiddle.net/jc2utfs3/
For more detail you can follow this Link
.parent{
display: flex;
flex-wrap: wrap;
}
.parent .child{
flex: 1 1 25%;
/*Start Run Code Snippet output CSS*/
padding: 5px;
box-sizing: border-box;
text-align: center;
border: 1px solid #000;
/*End Run Code Snippet output CSS*/
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
<div class="child">7</div>
<div class="child">8</div>
</div>
I believe this example is more barebones and easier to understand then #dowomenfart.
.child {
display: inline-block;
margin: 0 1em;
flex-grow: 1;
width: calc(25% - 2em);
}
This accomplishes the same width calculations while cutting straight to the meat. The math is way easier and em is the new standard due to its scalability and mobile-friendliness.
.parent-wrapper {
height: 100%;
width: 100%;
border: 1px solid black;
}
.parent {
display: flex;
font-size: 0;
flex-wrap: wrap;
margin-right: -10px;
margin-bottom: -10px;
}
.child {
background: blue;
height: 100px;
flex-grow: 1;
flex-shrink: 0;
flex-basis: calc(25% - 10px);
}
.child:nth-child(even) {
margin: 0 10px 10px 10px;
background-color: lime;
}
.child:nth-child(odd) {
background-color: orange;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
</style>
</head>
<body>
<div class="parent-wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>
</html>
;)
Flex wrap + negative margin
Why flex vs. display: inline-block?
Flex gives more flexibility with elements sizing
Built-in white spacing collapsing (see 3 inline-block divs with exactly 33% width not fitting in parent)
Why negative margin?
Either you use SCSS or CSS-in-JS for the edge cases (i.e. first element in column), or you set a default margin and get rid of the outer margin later.
Implementation
https://codepen.io/zurfyx/pen/BaBWpja
<div class="outerContainer">
<div class="container">
<div class="elementContainer">
<div class="element">
</div>
</div>
...
</div>
</div>
:root {
--columns: 2;
--betweenColumns: 20px; /* This value is doubled when no margin collapsing */
}
.outerContainer {
overflow: hidden; /* Hide the negative margin */
}
.container {
background-color: grey;
display: flex;
flex-wrap: wrap;
margin: calc(-1 * var(--betweenColumns));
}
.elementContainer {
display: flex; /* To prevent margin collapsing */
width: calc(1/var(--columns) * 100% - 2 * var(--betweenColumns));
margin: var(--betweenColumns);
}
.element {
display: flex;
border: 1px solid red;
background-color: yellow;
width: 100%;
height: 42px;
}
you can try this
.parent-wrapper {
height:100%;
width:100%;
border: 1px solid black;
}
.parent {
display: grid;
font-size: 0;
grid-template-columns: 25% 25% 25% 25%;
}
.child {
background:blue;
flex-grow: 1;
height:100px;
margin: 10px;
margin-bottom: 0;
}
.child:last-child {
margin-bottom: 10px;
}
<body>
<div class="parent-wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>
https://jsfiddle.net/samet19/gdntwLhb/
Here's another way without using calc().
// 4 PER ROW
// 100 divided by 4 is 25. Let's use 21% for width, and the remainder 4% for left & right margins...
.child {
margin: 0 2% 0 2%;
width: 21%;
}
// 3 PER ROW
// 100 divided by 3 is 33.3333... Let's use 30% for width, and remaining 3.3333% for sides (hint: 3.3333 / 2 = 1.66666)
.child {
margin: 0 1.66666% 0 1.66666%;
width: 30%;
}
// and so on!
That's all there is to it. You can get fancy with the dimensions to get a more aesthetic sizes but this is the idea.

Having the floating children elements determine parent width

Here is an example
http://jsfiddle.net/BringMeAnother/LwXhE/
// html
<div class="container clearfix">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
// css
.container {
background: red;
padding: 10px;
}
.child {
width: 100px;
height: 100px;
float: left;
}
.child:nth-child(even) {
background: green;
}
.child:nth-child(odd) {
background: blue;
}
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
The container with the red background seem to always stretch to 100%. What I'd like to do is to make its width depend on the floating children, so in this case, 3 times 100px.
The reason I'd like to have this is as follow. In a flexible layout, I have a container that contains several child elements of different sizes. The width and amount of those children can vary. The children always float. The goal is to have the floating children centered. So, if I always have one child element, I'd simply set its margin-right and margin-left to auto. However, there are several children which I wish to put next to each other, but after they have been ordered horizontally, I'd like that row to be centered on the page. I cannot give a fixed width to the container since the amount of children and each of their width are not determined in advance.
I think I might be able to do this with javascript, but I wonder if there is a pure css solution. Thanks
Besides Adsy suggestion (to set the container's position to fixed), you could:
1) Use position absolute on the container:
HTML:
<div class="container">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
CSS:
.container {
background: red;
padding: 10px;
position:absolute;
}
.child {
width: 100px;
height: 100px;
float: left;
}
.child:nth-child(even) {
background: green;
}
.child:nth-child(odd) {
background: blue;
}
http://jsfiddle.net/tKz8b/
2) Set a float on the container, which is good if you need it with relative / static positioning:
HTML:
<div class="container">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="clearfix"></div>
<div>Next</div>
CSS:
.container {
background: red;
padding: 10px;
float: left;
}
.child {
width: 100px;
height: 100px;
float: left;
}
.child:nth-child(even) {
background: green;
}
.child:nth-child(odd) {
background: blue;
}
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
http://jsfiddle.net/LYrWx/1/
By wrapping your container div in another wrapper div, you can centre your red container div, and the red div will only be as wide as its floating children.
HTML
<div class="centered">
<div class="container">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
CSS
.centered {
text-align: center;
}
.container {
background: red;
padding: 10px;
display: inline-block;
}
.child {
width: 100px;
height: 100px;
float: left;
}
.child:nth-child(even) {
background: green;
}
.child:nth-child(odd) {
background: blue;
}
Fiddle: http://jsfiddle.net/SbPRg/
Late to the party here, but all you really need is to add display: inline-block. And to center the .container div, just apply text-align: center to whatever contains it.
JSFiddle: http://jsfiddle.net/LwXhE/24/
Add position:fixed; to container
.container {
background: red;
padding: 10px;
position:fixed;
Fiddle