Flex-direction column not working as expected [duplicate] - html

This question already has answers here:
Force flex item to span full row width
(2 answers)
Closed 3 years ago.
I have the following markup:
<div class="container">
<div class="logo"></div>
<div class="search"></div>
<div class="button"></div>
</div>
CSS (desktop):
.container {
display: flex;
}
On a desktop view they're displayed in a row, like that:
But on mobile view, i want them to re-reorder:
I've tried the following styles:
// here's media query for mobile devices
.container {
flex-direction: column;
flex-wrap: wrap;
align-items: stretch // so my items would be filling width
}
.logo {
order: 1;
flex: 1 0 50%;
}
.search {
order: 2;
flex: 0 1 100%;
}
.button {
order: 1;
flex: 1 0 50%;
}
But my results are:
Is this even possible with a flexbox?

You should look into "flex-grow" which allows flex items to grow if necessary in order to take up as much space as is available in its container. If all flex-items (in your case: .logo, .search, .button) have a flex-grow value of 1, the remaining space in .container will be distributed to its children equally.
Also, you should use
flex-direction: row;
in your case if you want them to stretch horizontally
Check out this fiddle for reference! https://jsfiddle.net/hgs5w19y/2/

You need to use flex-grow (great resource for understanding flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
HTML
<div class="container">
<div class="logo">Logo</div>
<div class="search">Search</div>
<div class="button">Button</div>
</div>
CSS
.container {
background-color: #ccc;
display: flex;
width: 300px;
flex-wrap: wrap;
text-align: center;
}
.container > div {
background-color: grey;
margin: 10px 20px;
padding: 10px 20px;
}
.logo {
order: 1;
flex-grow: 1;
}
.search {
order: 2;
flex-grow: 2;
}
.button {
order: 1;
flex-grow: 1;
}

No need of direction nor so many rules, just set a breakpoint and reset .search behavior
.container {
display: flex;
flex-wrap: wrap;
}
.container>div {
flex: 1;
}
div.search {
order: 1;
flex-basis: 100%;
}
#media screen and (min-width:731px) {
div.search {
order: 0;
flex: 1
}
}
/* demo purpose */
.container {
background: gray;
}
.container>div {
padding: 1em;
margin: 1em;
background: lightgray;
}
.container>div:before {
content: attr(class);
color: black;
}
<div class="container">
<div class="logo"></div>
<div class="search"></div>
<div class="button"></div>
</div>
breakpoint value is to be updated to yours (here set at 731 for the demo) , to see behavior, run the snippet in full page, or play with the demo https://codepen.io/gc-nomade/pen/mYXZdY

Related

Flex box Responsive Layout with Left and Right Container

I have trouble with flexbox layout in mobile device. Desktop it looks okay
in Mobile view I want to display like below
first it should display "Overview" Box
second it should display "Payment" Box
3rd it should display "Activity" Box
.div1 {
box-sizing:border-box;
border:0.5px solid red;
}
.main-container {
height:100%;
display:flex;
}
.left-container {
flex:1 1 0;
}
.right-container {
flex:1 1 0;
display:flex;
//flex-direction:column;
}
.half-containers {
flex:1;
overflow:auto;
order: 1;
}
.half-containers-activity {
flex:1;
overflow:auto;
order: 0;
}
#include media-breakpoint-down(sm) {
.main-container {
flex-direction: row;
}
}
<div class="div1">
<div class="main-container">
<div class="left-container">
<div class="half-containers">
Overview
</div>
<div class="half-containers-activity">
Activity
</div>
</div>
<div class="right-container">
Payment
</div>
</div>
</div>
You can use the following method. The main thing here is to use display: contents; on .left-container to "neutralize" it, so that all three elements can be used "on one level" as flex children, applying according order parameters to them. All that in a media query, of course, to leave the desktop version unaltered.
.div1 {
box-sizing: border-box;
border: 0.5px solid red;
}
.main-container {
height: 100%;
display: flex;
}
.left-container {
flex: 1 1 0;
}
.right-container {
flex: 1 1 0;
display: flex;
//flex-direction:column;
}
.half-containers {
flex: 1;
overflow: auto;
order: 1;
}
.half-containers-activity {
flex: 1;
overflow: auto;
order: 0;
}
#media screen and (max-width: 700px) {
.main-container {
flex-direction: column;
}
.left-container {
display: contents;
}
.half-containers {
order: 0;
}
.right-container {
order: 1;
}
.half-containers-activity {
order: 2;
}
}
<div class="div1">
<div class="main-container">
<div class="left-container">
<div class="half-containers">
Overview
</div>
<div class="half-containers-activity">
Activity
</div>
</div>
<div class="right-container">
Payment
</div>
</div>
</div>
I should add that display: contents; is still regarded an "experimental value", but browser support is quite good already: https://caniuse.com/?search=display%3A%20contents

How to place items in flexbox take equal width?

I want to place the items in the flexbox take the same width.
Within the flexbox I have a searchsvg, input field and div with some text. I want each of them to take equal width themselves based on the width of the flexbox. I don't want to provide the width of each item manually. I tried using justify-content: space-evenly. In doing so, the input field takes more width than rest of them.
How can I avoid it? Below is the code:
.wrapper {
display: flex;
flex-grow: 1;
}
.items_container {
position: relative;
width: 40px;
height: 40px;
top: 16px;
margin-left: 16px;
padding-left: 5px;
display: flex;
align-items: center;
justify-content: space-evenly;
}
#media (min-width: 300px) {
.items_container.expanded {
width: 50%;
}
}
.items_container.expanded .search_input_field {
display: flex;
align-items: center;
}
<div class="wrapper">
<div class="items_container expanded">
<div class="search_input_field">
<div>
<Svgsearch/>
</div>
<input type="text" placeholder="input" />
</div>
<div>dropdown to be added</div>
</div>
.child elements should grow equally and not shrink
.parent {
display: flex;
}
.child {
flex: 1 0 0;
}
/* ignore */
.child {
padding: 5px;
height: 50px;
background: lightcoral;
margin: 2px;
text-align: center;
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
</div>
I moved flex-grow: 1 from where you placed it, because it wasn't doing anything. This is a rule that affects flex children. Therefore, I moved it to affect all direct children of the flex parent, .wrapper.
.wrapper {
display: flex;
/* flex-grow: 1; <-- moved below */
& > * {
flex-grow: 1;
}
}
jsFiddle

Two columns of equal height to reverse at breakpoint

I'm looking to make two columns of equal height that reverse their stacking at an 845px breakpoint. How should I code my css for regular view vs the 845px #media?
What are the benefits and or shortcomings of either method?
You can do it with the Flexbox:
.parent {
display: flex;
height: 300px;
}
.parent > .child-1 {
flex: 1;
background: red;
}
.parent > .child-2 {
flex: 1;
background: blue;
}
#media screen and (max-width: 845px) {
.parent {
flex-direction: column;
}
.parent > .child-1 {
order: 2;
}
}
<div class="parent">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
This can be accomplished with flex and the order property. The basic idea is to stack the items, using their default DOM order (col 1 before col 2), then in a media query use the order property to swap the order so col 2 is to the left of col 1. Like this:
.container {
display: flex;
flex-direction: column;
}
.col {
flex: 1;
display: flex;
flex-basis: 200px;
flex-direction: column;
border-width: 1px;
border-style: solid;
justify-content: center;
text-align: center;
margin: 10px;
font-family: Arial;
}
.col--1 {
border-color: red;
color: red;
}
.col--2 {
border-color: blue;
color: blue;
}
#media screen and (min-width: 845px) {
.container {
flex-direction: row;
}
.col--1 {
order: 2;
}
.col--2 {
order: 1;
}
}
<div class="container">
<div class="col col--1">
COL 1<br/> DIV
</div>
<div class="col col--2">
COL 2<br/> DIV
</div>
</div>

Flex-wrapping without nested divs

I'm trying to make a horizontal card using flexbox without having nested divs.
For example, what I have right now is this:
.card {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.card-img {
width: 37%;
}
.card-content {
width: 63%;
}
<div class='card'>
<div class='card-img'>
<img src='example' />
</div>
<div class='card-content'>
<div class='card-number'>
</div>
<div class='card-type'>
</div>
</div>
</div>
This layout works for now, but when the viewport resizes, I want the horizontal card to change into a vertical one (which it already does). However, I want to re-order the card-img, card-number, and card-type using flex order.
How could I get this same horizontal layout while using this type of div layout?
Edit:
Sorry for the confusing wording, what I was aiming to do was to create a horizontal layout that works like the image except with 3 separate divs, not 2 divs with 1 being a nested div. Sorry!
.card {
display: flex;
}
.card-img {
flex: 0 0 37%;
border: 1px dashed red;
}
.card-number {
flex: 0 0 30%;
border: 1px dashed red;
}
.card-type {
flex: 1 0 30%;
border: 1px dashed red;
}
img {
width: 100%;
}
.card > div {
display: flex;
align-items: center;
justify-content: center;
}
#media (max-width: 500px) {
.card { flex-direction: column; }
.card-img { order: 3; }
.card-number { order: 2; }
.card-type { order: 1; }
}
<div class='card'>
<div class='card-img'>
<img src="http://i.imgur.com/60PVLis.png">
</div>
<div class='card-number'>555</div>
<div class='card-type'>Orange</div>
</div>
https://jsfiddle.net/7y8sarwn/

How do I eliminate this huge unwanted margin between two rows of flex items? [duplicate]

This question already has an answer here:
Remove space (gaps) between multiple lines of flex items when they wrap
(1 answer)
Closed 6 years ago.
html, body {
height: 100%;
}
.flex{
min-height: 100%;
display: flex;
justify-content:center;
flex-flow: row wrap;
align-items: center;
background: red;
}
.coloring {
background:#CCC;
border-radius:7px;
padding: 20px;
margin: 0px;
}
.Projects{
order: 1;
flex: 0 1 100%;
}
.Tribute{
order: 2;
flex: 1 1;
}
.Portfolio{
order: 3;
flex: 1 1;
}
<section class="flex">
<div class="coloring Projects">Projects</div>
<div class="coloring Tribute">Tribute</div>
<div class="coloring Portfolio">Portfolio</div>
</section>
When you narrow the screen there is going to be 3 rows and now there are 2 such huge unwanted margins. I don’t know what to do. If I eliminate align-items: center the boxes will fill the entire page, but that is not what I want.
Aligning between multiple flex lines is handled by the align-content property - try align-content: center to eliminate the margins - see demo below:
html,
body {
height: 100%;
}
.flex {
min-height: 100%;
display: flex;
justify-content: center;
flex-flow: row wrap;
align-items: center;
align-content: center;
background: red;
}
.coloring {
background: #CCC;
border-radius: 7px;
padding: 20px;
margin: 0px;
}
.Projects {
order: 1;
flex: 0 1 100%;
}
.Tribute {
order: 2;
flex: 1 1;
}
.Portfolio {
order: 3;
flex: 1 1;
}
<section class="flex">
<div class="coloring Projects">Projects</div>
<div class="coloring Tribute">Tribute</div>
<div class="coloring Portfolio">Portfolio</div>
</section>
only you have to remove
min-height from .flex class