Flexbox, wrap items by column [duplicate] - css

This question already has answers here:
Layout possible? Flexbox vs Float layout with multiple columns and rows
(3 answers)
Left column and stacked right column using flexbox CSS [duplicate]
(2 answers)
Closed 4 years ago.
I am trying to control the position of some blocks contained in a wrapper with flexbox functionalities. Here is what I want at the end:
Here is the markup I would like to use. I wish not to change it and visually organize my box with CSS:
<div class="wrapper">
<div class="list-1">
Liste 1
</div>
<div class="list-2">
Liste 2
</div>
<div class="list-3">
Liste 3
</div>
</div>
I tried multiple things but it does not work. Here is the closest thing I came with, but list-3 only starts when list-2 also starts:
.wrapper {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
div[class^="list-"] {
text-align: center;
}
.list-1 {
background: red;
flex-basis: 80%;
line-height: 50px;
}
.list-2 {
background: pink;
flex-basis: 80%;
line-height: 50px;
}
.list-3 {
background: green;
flex-basis: 20%;
line-height: 100px;
}
<div class="wrapper">
<div class="list-1">
Liste 1
</div>
<div class="list-2">
Liste 2
</div>
<div class="list-3">
Liste 3
</div>
</div>
Is it even possible? Thank you for your help.

try this code
add div to first and second list and use flex-basis:80% for new div
i add class
.list {
flex-basis: 80%;
}
.wrapper {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
div[class^="list-"] {
text-align: center;
}
.list-1 {
background: red;
flex-basis: 80%;
line-height: 50px;
}
.list-2 {
background: pink;
flex-basis: 80%;
line-height: 50px;
}
.list-3 {
background: green;
flex-basis: 20%;
line-height: 100px;
}
.list {
flex-basis: 80%;
}
<div class="wrapper">
<div class="list">
<div class="list-1">
Liste 1
</div>
<div class="list-2">
Liste 2
</div>
</div>
<div class="list-3">
Liste 3
</div>
</div>

.wrapper {
display: flex;
flex-wrap: wrap;
align-items: stretch; /* this is for the children of flex to be of equal height. */
}
div[class^="list-"] {
text-align: center;
}
.list-1 {
background: red;
line-height: 200px;
height:200px;
}
.list-2 {
background: pink;
line-height: 100px;
height:100px;
}
.list-3 {
background: green;
flex-basis: 20%;
/* following 3 codes is for centered the liste3. deletable */
display:flex;
align-items:center;
justify-content:center;
}
.column {
display:flex;
flex-direction:column;
flex:4;
}
<div class="wrapper">
<div class="column">
<div class="list-1">
Liste 1
</div>
<div class="list-2">
Liste 2
</div>
</div>
<div class="list-3">
Liste 3
</div>
</div>

Related

CSS flexbox and justify-content [duplicate]

This question already has answers here:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
(6 answers)
Closed 4 months ago.
For a layout, I need to have three flex items (rows) in a flex container, and I want them justified as space-between... The first row will contain some cloud tags, the second a price, and the third a Read more link.
But there will be cases where for specific items, only the last row (the Read more) will need to exist.
So, in those cases, for uniformity, I want the Read more link to be placed at the bottom of the container; but space-between doesn't help much towards that approach...
What can I do to have a fallback justify-content property set to end for when there is only one child item?
.container {
background-color: #aaa;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-end;
height: 200px;
margin-bottom: 20px;
}
.tags {
display: flex;
}
.tags span {
background-color: #f0f;
padding: 10px;
margin: 0 0 0 10px;
}
.price {
display: flex;
background-color: #ff0;
padding: 10px;
font-size: 150%
}
.read-more {
display: flex;
background-color: #0ff;
padding: 10px;
}
<div class="container">
<div class="tags">
<span>tag 1</span><span>tag2</span><span>tag 3</span>
</div>
<div class="price">
$100
</div>
<div class="read-more">
Read more >>
</div>
</div>
<div class="container">
<div class="read-more">
Read more >>
</div>
</div>
If you are able/willing to change the order of the flex-items in your HTML code, you can reverse them there and use flex-direction: column-reverse; on the container. That way the "read more" element is the first flex-item and due to the reversed direction at the bottom of the container:
.container {
background-color: #aaa;
display: flex;
flex-direction: column-reverse;
justify-content: space-between;
align-items: flex-end;
height: 200px;
margin-bottom: 20px;
}
.tags {
display: flex;
}
.tags span {
background-color: #f0f;
padding: 10px;
margin: 0 0 0 10px;
}
.price {
display: flex;
background-color: #ff0;
padding: 10px;
font-size: 150%
}
.read-more {
display: flex;
background-color: #0ff;
padding: 10px;
}
<div class="container">
<div class="read-more">
Read more >>
</div>
<div class="price">
$100
</div>
<div class="tags">
<span>tag 1</span><span>tag2</span><span>tag 3</span>
</div>
</div>
<div class="container">
<div class="read-more">
Read more >>
</div>
</div>
You can give the container a position: relative; tag, the .read-more class, and the :only-child pseudo class. Then when it is the only child in the container, it will add the attributes position:absolute; bottom:0; right:0; to it.
This moves it to the bottom right of the container. The justify-content: end !important; doesn't move the container to where you want it to be.
Example:
.container {
background-color: #aaa;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-end;
height: 200px;
margin-bottom: 20px;
position:relative;
}
.tags {
display: flex;
}
.tags span {
background-color: #f0f;
padding: 10px;
margin: 0 0 0 10px;
}
.price {
display: flex;
background-color: #ff0;
padding: 10px;
font-size: 150%
}
.read-more {
display: flex;
background-color: #0ff;
padding: 10px;
}
.read-more:only-child{
position:absolute;
bottom:0;
right:0;
}
<div class="container">
<div class="tags">
<span>tag 1</span><span>tag2</span><span>tag 3</span>
</div>
<div class="price">
$100
</div>
<div class="read-more">
Read more >>
</div>
</div>
<div class="container">
<div class="read-more">
Read more >>
</div>
</div>

CSS Flex item spanning two rows without fixed height

I am trying to create a flex container layout whereby one of the flex items should span two rows. See image below for a better explanation:
Here is my markup:
<div class="container">
<div class="item item-1">ITEM 1</div>
<div class="item item-2">ITEM 2</div>
<div class="item item-3">ITEM 3</div>
</div>
I cannot seem to achieve this, I have tried using flex-wrap and different combinations of the flex property.
I was able to achieve this by putting ITEM 1 & ITEM 2 in a separate <div>, but this presents a problem on a smaller screen, whereby ITEM 3 needs to appear BETWEEN ITEM 1 & ITEM 2. So I would rather keep the markup as is and use the order property to move things around as necessary.
You can use display: contents on your extra div to achieve what you want:
* {
box-sizing: border-box;
}
.container {
display: flex;
width: 100%;
}
.holder {
width: 67%;
}
.item {
border: 1px solid black;
}
.item-1 {
margin-bottom: 40px;
}
.item-3 {
width: 33%;
}
#media screen and (max-width: 700px) {
.container {
flex-direction: column;
}
.item {
margin-bottom: 20px;
}
.item-1 {
order: 1;
}
.item-2 {
order: 3;
}
.item-3 {
order: 2;
width: 100%;
}
.holder {
width: 100%;
display: contents;
}
}
<div class="container">
<div class="holder">
<div class="item item-1">ITEM 1</div>
<div class="item item-2">ITEM 2</div>
</div>
<div class="item item-3">ITEM 3</div>
</div>
You can't achieve it using flexbox. Instead, you should have two parents which are better.
Use Css-grid. Actually, css-grid is the best option in this case.
Flex-Box
* {
color: #fff;
}
.flex {
display: flex;
justify-content: center;
align-items: center;
}
.child {
border-radius: 10px;
}
.container {
display: flex;
width: 500px;
height: 200px;
border: 1px solid #ff0000;
}
.container .first-item {
flex-direction: column;
justify-content: space-between;
align-items: start;
width: 50%;
height: 100%;
margin-right: 10px;
}
.first-item .child {
width: 100%;
height: 50%;
background-color: blue;
}
.first-item .child:first-child {
margin-bottom: 10px;
}
.container .second-item {
width: 50%;
height: 100%;
}
.second-item .child {
width: 100%;
height: 100%;
background-color: blue;
}
<div class="container">
<div class="first-item flex">
<div class="child flex">Item 1</div>
<div class="child flex">Item 2</div>
</div>
<div class="second-item flex">
<div class="child flex">Item 3</div>
</div>
</div>
Grid
.flex {
display: flex;
justify-content: center;
align-items: center;
}
.child {
background-color: blue;
border-radius: 10px;
}
.container {
display: grid;
grid-template-columns: 1fr 10px 1fr;
grid-template-rows: 1fr 10px 1fr;
grid-template-areas: "c1 . c3"
". . c3"
"c2 . c3";
width: 500px;
height: 300px;
border: 1px solid red;
}
.container .child {
border: 1px solid blue;
}
.child1 {
grid-area: c1;
}
.child2 {
grid-area: c2;
}
.child3 {
grid-area: c3;
}
<div class="container">
<div class="child child1 flex">Item 1</div>
<div class="child child3 flex">Item 3</div>
<div class="child child2 flex">Item 2</div>
</div>
i dont know if its a good solution but
put two item3 codes one in the individual div (item1&2) and one outside then put the one in the div to display none in non-small screens and switch between them with mediaquery
#media (max-width: 40rem) {
.item3 {
display: none;
}
.mobile-item3{
display: block;
}
}

How to set two elements be next each other using flexbox

I'm trying to make my css with flexbox, so I followed some articles and tried to set my elements like this example:
the elements 1 & 2 are in another container
I'm trying to set the two elements (1 and 3) to be next each other as the second example (The first is what I have now and the other is what I'm trying to achieve.)
but I can't find a good way with the Flexbox since I set the container to flex-direction: column;
<div class="container">
<div class="sub-ctn">
<h5 class="1"><span>♦ </span>{{ text }}</h5>
<span class="2">{{ value }}</span>
<div class="3">
<h5>{{ text }}
</div>
</div>
</div>
CSS:
.container {
margin-right: 2.5%;
direction: rtl;
}
.sub-ctn {
display: flex;
flex-flow: row;
margin-top: 1%;
flex-direction: column;
}
.1 {
width: 100%;
direction: rtl;
text-align: right;
}
.2 {
float: right;
/* text-align: right; */
}
.3 {
margin-left: 1%;
display: flex;
flex-direction: column;
}
let me know if another information is needed
Don't use float and flex together. Flex alone will be much easier and better.
.cont{
display: flex;
width: 80%;
border: 1px solid black;
padding: 10px;
}
.left-cont{
height: 100%;
flex-grow: 1;
}
.right-cont{
flex-grow: 1;
display: flex;
flex-direction: column;
}
.item{
text-align: center;
border: 1px solid black;
margin: 3px;
}
<div class="cont">
<div class="left-cont">
<div class="item">3</div>
</div>
<div class="right-cont">
<div class="item">1</div>
<div class="item">2</div>
</div>
</div>

Making an input and two buttons aligned using SCSS

I want my two buttons, that are actually <a> tags, stick with my input, and be the same size as input. Image perfectly describes what I want to achieve.
Note that I am just starting to learn SASS and CSS. I have tried with this but no luck
NumberInput.js
<div
className="NumberInput"
data-key={dataKey}>
<div className="numberInputField">
<input
data-key={dataKey}
type="text"
name="number"
value={getValue(datakey)}
onChange={onChange(datakey)}/>
</div>
<div className="buttonsField">
<div className="row">
<ValueChangeButton/>
</div>
<div className="row">
<ValueChangeButton/>
</div>
</div>
</div>
NumberInput.scss
$inputMaxWidth: 450px;
$maxHeight: 80px;
$btnFieldMaxWidth: 150px;
.NumberInput{
max-width: $inputMaxWidth;
max-height: $maxHeight;
.numberInputField{
display: inline-block;
text-align: center;
max-width: inherit;
max-height: inherit;
}
.buttonsField{
display: inline-block;
max-width: $btnFieldMaxWidth;
max-height: $maxHeight;
.button{
width: auto;
height: auto;
}
}
}
The result I get is, buttons are contained in their respective rows, but are not the same size as input, and they are flying all around the page. Also, if I change the className of my input, and set the className of its <div> to "numberInputField", it doesn't change its width and height.
Flexbox is perfect for this:
body {
margin: 1em;
}
.NumberInput {
display: flex;
max-width:450px;
margin:auto;
}
.numberInputField {
flex: 3; /* say 3/4 of width */
display: flex;
flex-direction: column;
}
input {
padding: 1em 4em;
flex: 1;
}
.buttonsField {
flex: 1; /* say 1/4 of width */
display: flex;
flex-direction: column;
}
.row {
flex: 1; /* share width equally */
}
a {
width: 100%;
display: block;
background: rebeccapurple;
text-align:center;
text-decoration: none;
font-size: 1.5em;
color: white;
border:1px solid grey;
}
<div class="NumberInput">
<div class="numberInputField">
<input type="submit" />
</div>
<div class="buttonsField">
<div class="row">
↑
</div>
<div class="row">
↓
</div>
</div>
</div>

CSS - Horizontally and vertically distribute divs

So I've got this header with three elements in them.
What I want is basically this:
http://jsfiddle.net/zktbfmqo/2/
Only with vertically centered content in each of the divs as well.
Is there an easy and clever way to do this without using absolutes etc?
Vertical-align: middle doesn't seem to do much, but that property isn't always easy to work with either.
HTML:
<div id="container">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
<span class="stretch"></span>
</div>
CSS:
#container {
border: 2px dashed #444;
height: 125px;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
min-width: 612px;
}
.box1, .box2, .box3 {
width: 150px;
height: 125px;
vertical-align: middle;
display: inline-block;
*display: inline;
zoom: 1;
text-align: center;
}
.stretch {
width: 100%;
display: inline-block;
font-size: 0;
line-height: 0
}
First you can achieve the same result in a better way by using Flexbox.
For vertical align text to the middle you can simply approach that by adding the line-height property and set it to the same exact height of the container div so in your case it would be 125px or if you used flexbox it can be done with align-items: center , and here is the final code:
.wrapper {
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row nowrap; /* Safari 6.1+ */
flex-flow: row nowrap;
-webkit-justify-content: space-between; /* Safari 6.1+ */
justify-content: space-between;
font-weight: bold;
height: 125px;
min-width: 612px;
padding: 5px;
border: 2px dashed #444;
}
.wrapper > div{
display: -webkit-flex;
display: flex;
-webkit-flex-basis: 150px;
flex-basis: 150px;
justify-content: center;
align-items: center;
}
.aside-1, .aside-3{
background: #ccc
}
.aside-2{
background: #0ff;
}
<div class="wrapper">
<div class="aside aside-1">text1</div>
<div class="aside aside-2">text2</div>
<div class="aside aside-3">text3</div>
</div>
Flexbox to the rescue!
Good resources:
https://philipwalton.github.io/solved-by-flexbox/
https://github.com/philipwalton/flexbugs
#container {
display: flex; /* magic maker */
justify-content: space-between; /* set equal space between boxes */
border: 2px dashed #444;
height: 125px;
/* just for demo */
min-width: 612px;
}
.box1, .box2, .box3, .box4 {
display: flex; /* magic maker */
/*
shorthand for flex-grow, flex-shrink, and flex-basis properties
we don't want the boxes to grow or shrink, and the basis is the explicit
width we want them
*/
flex: 0 0 150px;
justify-content: center; /* horizontally center text within */
align-items: center; /* vertically center text within */
height: 125px;
}
.box1, .box3 {
background: #ccc
}
.box2, .box4 {
background: #0ff
}
<div id="container">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
</div>
you can use display:table/table-cell and using a workaround with border-collapse/spacing + margin you will get the desired output.
#wrap {
border: 2px dashed #444;
height: 125px;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
overflow:hidden;
/* just for demo */
width: 612px;
}
#container {
margin: 0 -81px; /*must be equal to border-spacing */
}
#table {
display: table;
table-layout: fixed;
border-collapse: separate;
border-spacing: 81px 0;
width: 100%;
}
.box1,
.box2,
.box3,
.box4 {
width: 150px;
height: 125px;
vertical-align: middle;
display: table-cell;
text-align: center;
}
.stretch {
width: 100%;
vertical-align: middle;
display: table-cell;
}
.box1,
.box3 {
background: #ccc
}
.box2,
.box4 {
background: #0ff
}
<div id="wrap">
<div id="container">
<div id="table">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
<span class="stretch"></span>
</div>
</div>
</div>
Are you familiar with Bootstrap?
It is a CSS Framework made by Twitter.
Put this inside of your head -
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
Use this in your body to see what it does, there's great docs on it.
<div class="container"> <!-- Creates margin -->
<div class="row"> <!-- Read docs on rows, they're awesome! -->
<div class="col-lg-4"> <!-- 1 -->
<!-- Just to take up space -->
</div>
<div class="col-lg-4"> <!-- 2 -->
<!-- YOUR CONTENT GOES HERE -->
</div>
<div class="col-lg-4"> <!-- 3 -->
<!-- Just to take up space -->
</div>
</div> <!-- ./row -->
</div> <!-- ./container -->
Now inside of the 2nd ./col-lg-4 div all of that content will be perfectly centered in the screen with the text aligned left.
If you want to align center the text, replace
<div class="col-lg-4"> <!-- 2 -->
with
<div class="col-lg-4 text-center"> <!-- 2 -->
Hope this helps!

Resources