Issues adding a gap between two aligned items [duplicate] - html

This question already has answers here:
Better way to set distance between flexbox items
(40 answers)
Closed 1 year ago.
As shown in the code snippet below i have created two buttons that are always the same width, but im unable to make a gap between them.
Same goes for the mediaquery version (mobile)
How can i do it?
.flex-container {
display: flex;
justify-content: center;
margin: 1em;
}
.flex-container .flex-container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.flex-item {
height: 1.7rem;
padding: 0 1.2rem;
width: 100%;
}
.item1{
margin-right:1vw; /*wont work*/
}
#media only screen and (max-width: 480px) {
.flex-container .flex-container{
display:flex;
flex-direction: column;
}
}
<div class="flex-container">
<div class="flex-container">
<button class="flex-item item1">Button1</button>
<button class="flex-item">Button2 really long with same width</button>
</div>
</div>

column-gap: 1vw; works as expected:
.flex-container {
display: flex;
justify-content: center;
margin: 1em;
column-gap: 1vw;
}
.flex-container .flex-container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.flex-item {
height: 1.7rem;
padding: 0 1.2rem;
width: 100%;
}
#media only screen and (max-width: 480px) {
.flex-container .flex-container {
display: flex;
flex-direction: column;
}
}
<div class="flex-container">
<div class="flex-container">
<button class="flex-item item1">Button1</button>
<button class="flex-item">Button2 really long with same width</button>
</div>
</div>

Related

Placing container with flex order for different views [duplicate]

This question already has answers here:
Left column and stacked right column using flexbox CSS [duplicate]
(2 answers)
Closed 10 months ago.
I want to build with flex the following structure as a desktop first build:
In desktop view i need to place Container 1 and Container 2 side by side with the same height (use the height of the heighest content) and container 2 contains two content boxes.
But in mobile the overall order should be different as seen in the image. The problem i have here is the Container 2 im using here making it difficult to rearange the content as needed for mobile views.
Here is some of my code:
<div class="content-wrapper">
<div class="container-1" >
Content 1
</div>
<div class="container-2">
<div class="content-2">
Content 2
</div>
<div class="content-3">
Content 3
</div>
</div>
</div>
.content-wrapper {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
#media only screen and (max-width: 900px) {
flex-direction: row;
}
.container-1 {
width: 50%;
display: flex;
flex-direction: column;
order: 2;
justify-content: center;
#media only screen and (max-width: 900px) {
order: 1;
}
}
.container-2{
// height: 100vh;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
order: 1;
width: 50%;
#media only screen and (max-width: 900px) {
order: 2
}
.content-2 {
height: 70%;
}
.content-3 {
height: 30%;
}
}
}
Maybe someone can help me out here how to build this different views with flex (if you can provide a good grid solution im also happy with this)
IMHO the easiest way would be the use of CSS-Grid which controls both horizontal and vertical axis at the same time. For that you dont need wrappers and can simply use grid-template-areas:
.grid {
display: grid;
grid-template-areas:
"one two"
"one two"
"one three";
}
#media only screen
and (max-width: 900px) {
.grid {
grid-template-areas:
"two"
"one"
"three";
}
}
.grid :nth-child(1) {
grid-area: one;
}
.grid :nth-child(2) {
grid-area: two;
}
.grid :nth-child(3) {
grid-area: three;
}
/* for demonstration purpose only */
body {
margin: 0;
}
.grid {
grid-gap: 2px;
height: 100vh;
padding: 2px;
box-sizing: border-box;
}
.grid > div {
box-shadow: 0 0 0 2px black;
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
I try this with flex grid with your desktop view and display flex with your mobile view:
.content-wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 70% 30%;
height: 100%;
width: 100%;
}
.content-wrapper * {
border: solid 1px;
}
.content-wrapper .content-1 {
grid-row: 1/3;
grid-column: 1/2;
display: flex;
flex-direction: column;
justify-content: center;
}
.content-wrapper .content-2 {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.content-wrapper .content-2 {
grid-column: 2/3;
grid-row: 1/2;
}
.content-wrapper .content-3 {
grid-column: 2/3;
grid-row: 2/3;
}
#media only screen and (max-width: 900px)
{
.content-wrapper {
display: flex;
flex-direction: column;
}
.content-2 {
order: -1;
}
}
</style>
<div class="content-wrapper">
<div class="content-1" >
Content 1
</div>
<div class="content-2">
Content 2
</div>
<div class="content-3">
Content 3
</div>
</div>
</style>
I also change your html.
You can try like this:
.container-1 {
width: 50%;
display: flex;
flex-direction: column;
order: 2;
justify-content: center;
}
#media only screen and (max-width: 900px) {
.container-1 {
order: 2;
}
}
.container-2 {
height: 100vh;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
order: 1;
width: 50%;
}
#media only screen and (max-width: 900px) {
.container-2 {
order: 1
}
}

Use of Flexbox and avoid justification

I have a problem with this flexbox. I would like to place 3 div per row. For this reason I've used flexbox.
The first 3 divs are fine and have 33% width, while the divs 4 and 5 get 50%.
Is there any trick to do the job?
Thanks
* {
box-sizing: border-box;
}
.flex-container {
display: flex;
flex-wrap: wrap;
font-size: 30px;
text-align: center;
}
.flex-item-left {
background-color: #f1f1f1;
padding: 10px;
flex: 33%;
}
.flex-item-center {
background-color: dodgerblue;
padding: 10px;
flex: 33%;
}
.flex-item-right {
background-color: red;
padding: 10px;
flex: 33%;
}
/* Responsive layout - makes a one column-layout instead of a two-column layout */
#media (max-width: 800px) {
.flex-item-right, .flex-item-left {
flex: 100%;
}
}
<h1>Responsive Flexbox</h1>
<p>In this example, we change the percentage of flex to create different layouts for different screen sizes.</p>
<p><b>Resize the browser window to see that the direction changes when the
screen size is 800px or smaller.</b></p>
<div class="flex-container">
<div class="flex-item-left">1</div>
<div class="flex-item-center">2</div>
<div class="flex-item-right">3</div>
</div>
<div class="flex-container">
<div class="flex-item-left">4</div>
<div class="flex-item-center">5</div>
</div>
flex: 33% is short for flex: 1 1 33% meaning that the container will grow or shrink if needed with a basis of 33%. Since there is space left, the containers will grow to 50%.
To fix this, replace the flex property with 0 1 33% meaning that it cannot grow and will not be larger than 33%.
You can simplify with display: grid; and it will give you a little more control over your layout.
* {
box-sizing: border-box;
}
.row-1 {
grid-column: 1 / -1;
grid-gap: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
flex-direction: column;
text-align: center;
}
.row-2 {
grid-column: 1 / -1;
grid-gap: 0;
display: grid;
grid-template-columns: repeat(2, 50%);
flex-direction: column;
text-align: center;
}
.flex-container {
display: flex;
flex-wrap: wrap;
font-size: 30px;
text-align: center;
}
.flex-item-left {
background-color: #f1f1f1;
padding: 10px;
}
.flex-item-center {
background-color: dodgerblue;
padding: 10px;
}
.flex-item-right {
background-color: red;
padding: 10px;
}
/* Responsive layout - makes a one column-layout instead of a two-column layout */
#media (max-width: 800px) {
.row-1, .row-2 {
display: flex;
flex-direction: column;
}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no" />
</head>
<body>
<h1>Responsive Flexbox</h1>
<p>In this example, we change the percentage of flex to create different layouts for different screen sizes.</p>
<p><b>Resize the browser window to see that the direction changes when the
screen size is 800px or smaller.</b></p>
<div class="row-1">
<div class="flex-item-left">1</div>
<div class="flex-item-center">2</div>
<div class="flex-item-right">3</div>
</div>
<div class="row-2">
<div class="flex-item-left">4</div>
<div class="flex-item-center">5</div>
</div>
</body>
</html>

Hide grid column with the rest of columns redistributing

everyone.
I'm trying to implement the grid column that hides when the wrapping container width goes below certain value, while the rest of columns should redistribute over the entire width:
Neither visibility: hidden, nor display: none for disappearing column did work (since the blank space is left in place of removed column, while the left column doesn't take the whole width).
My question is: how do I achieve desired behavior with pure CSS and without modifying grid-template-columns of the parent grid container?
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(100px, 1fr));
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnA {
grid-column-start: 1;
grid-column-end: 2;
}
.columnB {
grid-column-start: 2;
grid-column-end: 4;
}
#media (max-width: 800px) {
.columnA {
visibility: hidden;
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>
Simplify your code like below:
.grid {
display: grid;
grid-gap:5px;
grid-auto-columns: minmax(100px, 1fr); /* size of one column */
grid-auto-flow:column; /* column flow */
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnB {
grid-column:span 2; /* B takes 2 columns */
}
#media (max-width: 800px) {
.columnA {
display:none;
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>
If you want to keep the template (which is not needed) you can do like below:
.grid {
display: grid;
grid-gap:5px;
grid-template-columns: repeat(3, minmax(100px, 1fr));
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnB {
grid-column:span 2;
}
#media (max-width: 800px) {
.columnA {
display:none;
}
.columnB {
grid-column:span 3; /* B will take 3 columns when A is hidden */
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>

How to make an element of a Grid take all remaining space?

I am building a grid layout based on 3 rows and I would like the middle row to take as much space as possible.
The first row should be at the start of the screen (blue bar in the code example) and the third row should be at the end of the screen(red bar in the code example)
How can I achieve this? :S
https://jsfiddle.net/xmghkLvs/31/
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto auto auto;
row-gap: 1%;
}
.top-bar{
background-color: blue;
border-radius: 5px;
}
.main-menu{
justify-self: center;
display: flex;
flex-direction: column;
background-color: green;
}
.bottom-bar{
background-color: red;
border-radius: 5px;
}
<div class="grid">
<div class="top-bar">
<h1>
Title
</h1>
</div>
<div class="main-menu">
<button>
One Button
</button>
<button>
Other Button
</button>
</div>
<div class="bottom-bar">
<p>
I'm a text
</p>
</div>
</div>
1st: Give the grid a min-height like 100vh (.grid { min-height: 100vh; }). This will make consume at least the viewports height.
2nd: Give the the first and last row a height of min-content. That will make it only consume as much height as needed. auto will then consume all remaining space by default.
.grid {
min-height: 100vh;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content auto min-content;
row-gap: 1%;
}
.top-bar{
background-color: blue;
border-radius: 5px;
}
.main-menu{
justify-self: center;
display: flex;
flex-direction: column;
background-color: green;
}
.bottom-bar{
background-color: red;
border-radius: 5px;
}
<div class="grid">
<div class="top-bar">
<h1>
Title
</h1>
</div>
<div class="main-menu">
<button>
One Button
</button>
<button>
Other Button
</button>
</div>
<div class="bottom-bar">
<p>
I'm a text
</p>
</div>
</div>
Try using 100vh
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto auto auto;
row-gap: 1%;
height: 100vh;
}
and add specific height for the .top-bar abd .bottom-bar
You could approach this using Flexbox and 100vh as show below.
.grid {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.top-bar{
display: flex;
height: 20%;
}
.main-menu{
display: flex;
align-items: center;
justify-content: center;
height: 60%;
}
.main-menu button {
height: 60px;
width: 120px;
}
.bottom-bar{
display: flex;
align-items: center;
justify-content: center;
height: 20%;
}

Flexbox or CSS Grid: How to let one column be larger than two others?

How would you solve this Layout if you have only 3 Containers:
<div class="main-container">
<div class="blue-container"></div>
<div class="red-container"></div>
<div class="green-container"></div>
</div>
.main-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: stretch;
align-content: stretch;
}
.blue-container, .red-container {
width: 50%;
}
.green-container {
flex-basis: 100%;
width: 100%;
}
I solved it for Desktop (code above) and Mobile (everything flex-basis: 100%). But how to solve the tablet layout without adding more Markup/<div>'s?
The grid solution. Look how compact and nice it is. For all tree conditions. Used grid-template-areas. Try it while resizing the viewport.
.main-container {
display: grid;
grid-template-areas:
"blue red"
"green green";
grid-template-columns: 1fr 1fr;
grid-auto-rows: auto;
grid-gap: 10px;
min-height: 150px; /*just for instance */
}
.blue-container {
grid-area: blue;
background: blue;
}
.red-container {
grid-area: red;
background: red;
}
.green-container {
grid-area: green;
background: green;
}
/* tablet */
#media (max-width: 991.98px) {
.main-container {
grid-template-areas:
"blue red"
"green red";
}
}
/* mobile */
#media (max-width: 575.98px) {
.main-container {
grid-template-areas:
"blue blue"
"red red"
"green green";
}
}
<div class="main-container">
<div class="blue-container"></div>
<div class="red-container"></div>
<div class="green-container"></div>
</div>
Change your flex-direction to column and use the order property. Flex-basis will determine the height:
.main-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: space-between;
align-items: stretch;
align-content: stretch;
height: 100vh;
}
.red-container {
flex-basis: 100%;
background: red;
order: 3;
}
.green-container {
background: green;
order: 2;
flex-basis: 25%;
}
.blue-container {
background: blue;
order: 1;
flex-basis: 75%;
}
<div class="main-container">
<div class="blue-container"></div>
<div class="red-container"></div>
<div class="green-container"></div>
</div>