CSS fixed size margin only between elements - css

This keeps coming up on certain projects and I wanted to see if anyone may have a better solution.
Essentially, I'm trying to have a group of div elements of which all have an equal amount of spacing between them but not around. The snippet below is an example of what I'm looking for, my hope is someone may have a cleaner solution.
My question here is if anyone has a better solution that may use less css or less HTML elements. The important things to maintain:
Localization compliant - Since we aren't using margin left or right there aren't any weird localization issues in rtl
Alignment - It shouldn't size to the whole window if it doesn't need to but it should wrap if needed. (see example)
Spacing - Should be a fixed amount of space between the elements
If you have any ideas I'd love to hear them!
body {
background-color: black;
padding: 30px;
}
.inner {
overflow: hidden;
margin: 20px 0px;
}
.innerMargin {
background-color: white;
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: -10px;
}
.innerMargin > div {
flex: 0 0 20px;
background-color: red;
margin: 10px;
height: 20px;
width: 20px;
}
.fixedWidth {
width: 180px;
}
<div class="inner">
<div class="innerMargin">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<div class="inner fixedWidth">
<div class="innerMargin">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>

I think it should be noted this is trivial with CSS Grid.
body {
background-color: #000;
}
.container {
display: grid;
grid-template: 20px/repeat(auto-fit, 20px);
grid-gap: 20px;
background-color: #FFF;
margin: 20px;
}
.container div {
background-color: red;
}
.fixed-width {
width: 180px;
}
.container > div {
background-color: red;
}
<div class="container">
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
</div>
<div class="container fixed-width">
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
</div>
CodePen here

Necromancing, but I'd like to add that a pretty quick way to accomplish this if you're just dealing with a row/column is to use a last-child pseudoselector to override margin to 0. Like so:
.column-item {
width: 5px;
height: 5px;
background-color: red;
margin-bottom: 20px;
}
.column-item:last-child {
margin: 0;
}
beginning
<div id="column">
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
</div>
end

If you know you will always have 5 boxes in the fixedwidth box, you could do something like:
HTML (Slim)
.container
- 5.times do
.box
.container.container--thinner
- 15.times do
.box
CSS (SCSS)
$width : 36;
body {background-color: #000;}
.container {
display:flex;
flex-wrap: wrap;
background-color: white;
margin-bottom: 2em;
width: $width + em;
.box {
width: 2em;
height: 2em;
margin-right: 2em;
background-color: red;
}
&--thinner {
justify-content: space-between;
width: $width/2 + em;
.box {
margin-bottom: 2em;
&:nth-of-type(5n) {
margin-right: 0;
}
}
}
}
Here's a Codepen

Related

Add an overlay div inside nested flex containers (3x3 grid) in a specific cell

I have a 3x3 grid with flex-box concept, inside of each cell it has another 3x3 grid.
I was trying to put an Overlay over the Inner grid in one cell, but I didn't find how to do it.
I found some examples like this one
Overlay / hover a div in flexbox container div
but it don't work in nested flex-box, or I don't know how to set them up.
here is the html, the grid has just two cell to take up less space, it actually is done with JQuery but for the example lets use only 2.
.Region{
position: absolute;
top: 10px;
left: 10px;
width: 500px;
height: 500px;
border: 5px double black;
display: flex;
}
.FlexContainer{
display: flex;
flex-direction: column;
flex-grow: 1;
}
.FlexContainer > div{
flex-grow: 1;
flex-basis: 0;
border: 3px solid blue;
display: flex;
flex-direction: row;
margin: 5px;
}
.FlexContainer > div > div{
flex-grow: 1;
flex-basis: 0;
border: 1px solid red;
margin: 3px;
display:flex;
flex-direction: row;
}
.Overlay{
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(013, 130, 230, 0.5);
cursor: not-allowed;
}
<div class="Region">
<div class="FlexContainer">
<div>
<div>
<div class="FlexContainer">
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div>
<div class="FlexContainer">
<div class="Overlay"></div>
<div>
<div>
</div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
<div></div>
<div></div>
</div>
</div>
</div>
I have tried with the Overlay inside and outside the Inner FlexContainer, but didn't work.
Finally got it to work, indeed the parent container must have relative position for it to work, so there is two change, one in the FlexContainer and other in the Overlay
.FlexContainer{
position:relative; <-- ADD THIS
display: flex;
flex-direction: column;
flex-grow: 1;
}
.FlexContainer .Overlay {
position: absolute;
top: 0px;
left: 0px;
margin: 0px;
border: 0px;
width: 100%;
height: 100%;
background-color: rgba(013, 130, 230, 0.5);
cursor: not-allowed;
}
Code Pen solution https://codepen.io/anon/pen/dKaXqg
Credits to user Pogany from the css-tricks web site
CSS-TRICKS thread: https://css-tricks.com/forums/topic/add-and-overlay-div-in-nested-flex-box-container/#post-273437

how to lineup css boxes?

I have been busting my butt, just to lineup my pics in css boxes
here is the code(and the screen shop of result) its in the blade(laravel5) :
Here is my code:
#foreach($users as $user)
<div style="width: 200px;height: 200px;background-color: gray;text-align: center; float: right; margin-bottom: 22px;
margin-right: 17px;
">
<img src="{{$user->getavatar()}}" alt="{!!$user->username!!}" >
<strong>{!!$user->username!!}</strong>
</div>
<br>
#endforeach
Let's try another method using display instead of using float, and remove the <br>. How does this look?
<div style="width: 200px; height: 200px; text-align: center; display: inline-block; vertical-align: top; margin: 0 10px 22px;">
<img src="{{$user->getavatar()}}" alt="{!!$user->username!!}" >
<strong>{!!$user->username!!}</strong>
</div>
Remove the <br> tag at the end of the foreach loop.
You can put all your foreach loop divs inside a div container and use display:flex. It is better not to use css inline with yout html code(It looks heavy), also <br> is not needed there.
Please review this one:
#container {
display: flex;
flex-wrap: wrap;
padding: 50px;
}
#container div {
height: 200px;
width: 200px; /*or using calc(100% / 6);*/
background-color: gray;
text-align: center;
flex-grow: 0;
margin-bottom: 22px;
margin-right: 17px;
}
<div id="container">
<!--sample result of your foreach loop-->
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<!--end foreach-->
</div>

Centering floated elements with custom width [duplicate]

This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 6 years ago.
Today I am facing a big problem with centering floated elements that have set custom width. For better explanation I made a snippet for you:
body { text-align: center; }
.square {
width: 20%; height: 100px;
background: cornflowerblue;
float: left;
}
.container {
display: inline-block;
}
<div>
<div class="container">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
</div>
</div>
<br>
<div>
<div class="container">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
</div>
</div>
The problem is that first three squares get shrinked after centering.
The reason why I am floating the elements is that the second container has to be same as first container and it must contain 5 elements (to cover full width of document). Here is how it looks like without floating (see the gabs between elements):
body { text-align: center; }
.square {
width: 20%; height: 100px;
background: cornflowerblue;
display: inline-block;
}
.container {
display: block;
}
<div>
<div class="container">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
</div>
</div>
<br>
<div>
<div class="container">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
</div>
</div>
Now the elements have right width, but the second line doesn't cover width of document because of the gabs between elements.
Is there any way to have floated elements with custom width centered? Which styles I should use for container element?
OK, I think I got what you need
.square {
width: 20%; height: 100px;
background: cornflowerblue;
display: inline-block;
font-size: 1rem;
}
.container {
display: block;
font-size:0;
}
jsfiddle
body { text-align: center; }
.square {
width: 20%; height: 100px;
background: cornflowerblue;
float: left;
}
.container {
width:100%;
margin-right:20%;
margin-left:20%;
}
Are you looking for something like this?
Add min-width:7px; this will solve your issue
body { text-align: center; }
.square {
width: 20%;
height: 100px;
background: cornflowerblue;
float: left;
min-width:7px;
}
.container {
display: inline-block;
}
<div>
<div class="container">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
</div>
</div>
<br>
<div>
<div class="container">
<div class="square">a</div>
<div class="square">b</div>
<div class="square">c</div>
<div class="square">d</div>
<div class="square">e</div>
</div>
</div>
Here your 5 div row era is also working.

adjust width of inner / child elements

I have a parent DIV which may have 1,2 or 3 child elements. If the parent has only one element the child should have 100% width, if 2 then each element should have 50% of available width and in case of 3 elements each child should have 33.3333% of width.
If you want to avoid tables and are fine with flexbox (which is supported by all modern browsers), your solution would be simply
.container {
display: flex;
align-items: stretch;
}
.container > * {
display: block;
width: 100%;
}
with
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
(works fine for more elements as well).
/* solution */
.container {
display: flex;
align-items: stretch;
}
.container > * {
display: block;
width: 100%;
height: 100%;
}
/* for demo */
.container {
height: 30px;
}
.container > * {
height: 100%;
}
.container > :first-of-type {
background-color: red;
}
.container > :nth-of-type(2) {
background-color: green;
}
.container > :nth-of-type(3) {
background-color: blue;
}
<h3>one item</h3>
<div class="container">
<div></div>
</div>
<hr>
<h3>two items</h3>
<div class="container">
<div></div>
<div></div>
</div>
<hr>
<h3>three items</h3>
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
Use table layout
.wrap{
border: 1px solid green;
min-height: 100px;
display: table;
width: 100%;
}
.wrap > div{
border: 1px solid red;
display: table-cell;
}
<div class="wrap">
<div class="box">div 1</div>
<div class="box">div 2</div>
<div class="box">div 3</div>
</div>

Align <div> elements side by side

I know this is a rather simple question, but I can't figure it out for the life of me. I have two links which I've applied a background image to. Here's what it currently looks like (apologies for the shadow, just a rough sketch of a button):
However, I want those two buttons to be side by side. I can't really figure out what needs to be done with the alignment.
Here's the HTML
<div id="dB"}>
Download
</div>
<div id="gB">
Gallery
</div>
Here's the CSS
#buyButton {
background: url("assets/buy.png") 0 0 no-repeat;
display:block;
height:80px;
width:232px;
text-indent:-9999px;
}
#buyButton:hover{
width: 232px;
height: 80px;
background-position: -232px 0;
}
#buyButton:active {
width: 232px;
height: 80px;
background-position: -464px 0;
}
#galleryButton {
background: url("images/galleryButton.png") 0 0 no-repeat;
display:block;
height:80px;
width:230px;
text-indent:-9999px;
}
#galleryButton:hover{
width: 230px;
height: 80px;
background-position: -230px 0;
}
#galleryButton:active {
width: 230px;
height: 80px;
background-position: -460px 0;
}
Beware float: left… 🤔
…there are many ways to align elements side-by-side.
Below are the most common ways to achieve two elements side-by-side…
Demo: View/edit all the below examples on Codepen
Basic styles for all examples below…
Some basic css styles for parent and child elements in these examples:
.parent {
background: mediumpurple;
padding: 1rem;
}
.child {
border: 1px solid indigo;
padding: 1rem;
}
Using the float solution my have unintended affect on other elements. (Hint: You may need to use a clearfix.)
html
<div class='parent'>
<div class='child float-left-child'>A</div>
<div class='child float-left-child'>B</div>
</div>
css
.float-left-child {
float: left;
}
html
<div class='parent'>
<div class='child inline-block-child'>A</div>
<div class='child inline-block-child'>B</div>
</div>
css
.inline-block-child {
display: inline-block;
}
Note: the space between these two child elements can be removed, by removing the space between the div tags:
html
<div class='parent'>
<div class='child inline-block-child'>A</div><div class='child inline-block-child'>B</div>
</div>
css
.inline-block-child {
display: inline-block;
}
html
<div class='parent flex-parent'>
<div class='child flex-child'>A</div>
<div class='child flex-child'>B</div>
</div>
css
.flex-parent {
display: flex;
}
.flex-child {
flex: 1;
}
html
<div class='parent inline-flex-parent'>
<div class='child'>A</div>
<div class='child'>B</div>
</div>
css
.inline-flex-parent {
display: inline-flex;
}
html
<div class='parent grid-parent'>
<div class='child'>A</div>
<div class='child'>B</div>
</div>
css
.grid-parent {
display: grid;
grid-template-columns: 1fr 1fr
}
Apply float:left; to both of your divs should make them stand side by side.
keep it simple
<div align="center">
<div style="display: inline-block"> <img src="img1.png"> </div>
<div style="display: inline-block"> <img src="img2.png"> </div>
</div>
.section {
display: flex;
}
.element-left {
width: 94%;
}
.element-right {
flex-grow: 1;
}
<div class="section">
<div id="dB" class="element-left" }>
Download
</div>
<div id="gB" class="element-right">
Gallery
</div>
</div>
or
.section {
display: flex;
flex-wrap: wrap;
}
.element-left {
flex: 2;
}
.element-right {
width: 100px;
}
<div class="section">
<div id="dB" class="element-left" }>
Download
</div>
<div id="gB" class="element-right">
Gallery
</div>
</div>

Resources