How to put a div above columns of flex displayed elements? - css

I have a div that is displayed as flex. Inside the div are 3 other elements. I would like that the first element has 100% width and the 2nd and 3rd element should stay beside each other.
Sample code:
Codepen
#flex-container {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
#flex-container > .flex-item {
-webkit-flex: auto;
flex: auto;
}
#flex-container > .raw-item {
width: 5rem;
}
#flex-container {
width: 100%;
font-family: Consolas, Arial, sans-serif;
}
#flex-container > div {
border: 1px solid #f00;
padding: 1rem;
}
#flex-container > .raw-item {
border: 1px solid #000;
}
.fullwidth {
background-color: yellow;
}
<div id="flex-container">
<div class="fullwidth">full swidth</div>
<div class="flex-item" id="flex">Flex box (click to toggle raw box)</div>
<div class="raw-item" id="raw">Raw box</div>
</div>
Here I want to achieve that the yellow div (class = fullwidth) is 100% and above the 2 other elements, without changing the HTML and skipping flex.
Is there a way to achieve this properly?

You can use flex-wrap: wrap on Flex-container and flex: 0 0 100% on div you want to take full-width. Also to make other div's equal width you can use flex: 1
* {
box-sizing: border-box;
}
#flex-container {
font-family: Consolas, Arial, sans-serif;
display: flex;
flex-wrap: wrap;
}
#flex-container > div {
border: 1px solid #f00;
padding: 1rem;
flex: 1;
}
#flex-container > .raw-item {
border: 1px solid #000;
}
#flex-container > div.fullwidth {
background-color: yellow;
flex: 0 0 100%;
}
<div id="flex-container">
<div class="fullwidth">full swidth</div>
<div class="flex-item" id="flex">Flex box (click to toggle raw box)</div>
<div class="raw-item" id="raw">Raw box</div>
</div>

Related

How do I make parent container and other child in Flex to grow as one of the longest child

I need to the container and the green div to grow as the same size as blue whenever things inside the blue div grow.
.container {
background: grey;
height: 200px;
flex-direction: column;
padding: 10px;
display: flex;
}
.normal {
background: green;
}
.wide {
width: 2500px;
background: blue;
flex: 1 0 auto;
}
<div class="container">
<div class="normal">Normal</div>
<div class="wide">Wide</div>
</div>
CodePen
consider inline-flex instead
.container {
background: grey;
height: 200px;
flex-direction: column;
padding: 10px;
display: inline-flex;
min-width:100%; /*to make sure it behave like flex if the content is small*/
box-sizing:border-box;
}
.normal {
background: green;
}
.wide {
width: 2500px;
background: blue;
flex: 1 0 auto;
}
<div class="container">
<div class="normal">Normal</div>
<div class="wide">Wide</div>
</div>
Related: Why does the outer <div> here not completely surround the inner <div>?

3 expandable column landscape page in pure CSS

If this can be achieved in CSS:
When not hovered: 3 columns split in average width
When hovered on one of the column: that column expands and squeezes other 2 columns
Here's what I've been trying:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* vertical 1:2:1 */
html,
body {
height: 100%;
}
.vertical-divider {
display: flex;
flex-flow: column nowrap;
height: 100%;
}
/* container in page center */
.container {
display: flex;
flex-flow: row nowrap;
background-color: #eee;
flex: 2;
}
.container>.item {
display: flex;
flex-flow: column;
justify-content: left;
align-content: left;
align-items: left;
transition: .3s;
max-width: 50%;
padding-top: 24px;
padding-left: 12px;
background-color: #ccc;
min-width: 10%;
flex: 1;
text-align: left;
}
.container>.item:hover {
transition: .3s;
max-width: 80% !important;
background: #333;
flex: 4;
cursor: pointer;
color: #fff;
}
<!doctype html>
<html>
<head>
</head>
<body>
<div class="vertical-divider">
<div class="container">
<div class="item">
Column 1
</div>
<div class="item">
Column 2
</div>
<div class="item">
Column 3
</div>
</div>
</div>
</body>
</html>
But responsive design (e.g. If I want to just put them vertically if the screen is narrow) seems hard to achieve. So I'm asking if there is a better solution.
Flexbox offers a clean, modern solution. We can transition on the flex property. If you want to make the hovered div take up more room, simply adjust the value to a higher number.
.container {
display: flex;
}
.container > div {
flex: 1;
border-right: 2px solid black;
height: 300px;
padding: 10px;
transition: 0.5s flex;
}
.container > div:hover {
flex: 3;
}
.container > div:last-child {
border-right: 0;
}
<div class="container">
<div>col 1</div>
<div>col 2</div>
<div>col 3</div>
</div>
Edit A new requirement has emerged: make it responsive. Flexbox makes this an easy addition by changing the flex-direction property inside a simple media query.
#media screen and (max-width: 700px) {
.container {
flex-direction: column;
height: 100vh;
}
.container > div {
border-right: none;
border-bottom: 2px solid;
}
}
With the media query in place, our example is now complete.
Have a look.

Align element to the second column

I have the following layout:
#container {
display: flex;
flex-wrap: wrap;
}
#a {
flex-basis: 100%;
height: 100px;
}
#b {
flex-grow: 1;
height: 150px;
}
#c {
flex-grow: 2;
height: 100px;
}
/* Less relevant styles */
#a, #b, #c {
font-family: sans-serif;
font-size: 3em;
color: white;
text-shadow: 1px 1px 3px grey;
display: flex;
justify-content: center;
align-items: center;
}
#a {
background-color: #FFC300;
}
#b {
background-color: #FF5733;
}
#c {
background-color: #C70039;
}
<div id="container">
<div id="a">A</div>
<div id="b">B</div>
<div id="c">C</div>
</div>
How can I change the A element so that instead of taking up all the horizontal space, it's aligned to the C element? Basically I want to achieve something like that:
Note that I don't want to set something like margin-left: 33% on the A element, because I don't know if the B element will always take up one third of the horizontal space. I want the A element to remain aligned to C even if the width of B or C changes.
If possible, I want to achieve this using flexbox, but I'm open to workarounds.
Wrapping nested flexboxes and justify-content:flex-end is one option.
#container {
display: flex;
}
[class^="wrap"] {
display: flex;
flex-direction: column;
justify-content: flex-end;
}
/* Less relevant styles */
#a,
#b,
#c {
height: 100px;
font-family: sans-serif;
font-size: 3em;
color: white;
text-shadow: 1px 1px 3px grey;
display: flex;
justify-content: center;
align-items: center;
}
#a {
background-color: #FFC300;
}
#b {
background-color: #FF5733;
}
#c {
background-color: #C70039;
}
.wrap-left {
flex: 1;
}
.wrap-right {
flex: 2;
}
<div id="container">
<div class="wrap-left">
<div id="b">B</div>
</div>
<div class="wrap-right">
<div id="a">A</div>
<div id="c">C</div>
</div>
</div>
This sort of layout is standard for a table element (especially because of the variable width of each column). Something to consider, if possible.
Basically, you need to force "A" and "C" into the same column so they can track each other's width.
One method would be to force "B" to consume all space in the first column. This can be done by nesting "B" in a container with 100% height, then aligning "B" to the bottom half.
#container {
display: flex;
flex-flow: column wrap;
height: 200px;
}
nested-container {
flex-basis: 100%;
display: flex;
align-items: flex-end;
}
#b {
flex: 1;
background-color: #FF5733;
}
#a {
background-color: #FFC300;
}
#c {
background-color: #C70039;
}
#a, #b, #c
{
height: 100px;
font-family: sans-serif;
font-size: 3em;
color: white;
text-shadow: 1px 1px 3px grey;
display: flex;
justify-content: center;
align-items: center;
}
<div id="container">
<nested-container>
<div id="b">B</div>
</nested-container>
<div id="a">A</div>
<div id="c">C</div>
</div>
You can group your boxes this way:
<div id="container">
<div class="first-col">
<div id="empty"></div>
<div id="b">B</div>
</div>
<div class="second-col">
<div id="a">A</div>
<div id="c">C</div>
</div>
</div>
and style their width togehter by column, but their color and content by id

How can I place two divs in one row of a vertically sorted flex div?

Here is my code snippet:
.container {
display: flex;
flex-direction: column;
}
.container > div {
padding: 20px;
color: #fff;
margin: 5px;
text-align: center;
font-size: 30px;
}
.fruits {
order: 2;
background: #ff5423;
}
.container :not(.fruits) {
order: 1;
}
.flowers {
background: #f970bd;
}
.trees {
background: #049500;
}
<div class="container">
<div class="fruits">The fruits</div>
<div class="flowers">The flowers</div>
<div class="fruits">The fruits</div>
<div class="trees">The trees</div>
<div class="fruits">The fruits</div>
</div>
I am putting all .fruits div in the bottom using flex-direction: column;. There are two other divs .flowers and .trees which can be placed randomly anywhere inside .conatiner and I can't handle that. I want them to take half of its parent width so they take only one row.
What I want to achieve:
Giving 50% width will not work here. I know the rule says the direction is column-wise, however, I still hope if there is any available method/trick to do so! Any other workaround using different technique rather than using flex will also help.
You can do this with flex-direction: row you just need to set flex-wrap: wrap on parent and flex: 0 0 50% on elements you want to take half width.
You also need to use * {box-sizing: border-box} for paddings and calc() for margins.
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-wrap: wrap;
}
.container > div {
padding: 20px;
color: #fff;
margin: 5px;
flex: 0 0 calc(100% - 10px);
text-align: center;
font-size: 30px;
}
.fruits {
order: 2;
background: #ff5423;
}
.container div:not(.fruits) {
order: 1;
flex: 0 0 calc(50% - 10px);
}
.flowers {
background: #f970bd;
}
.trees {
background: #049500;
}
<div class="container">
<div class="fruits">The fruits</div>
<div class="flowers">The flowers</div>
<div class="fruits">The fruits</div>
<div class="trees">The trees</div>
<div class="fruits">The fruits</div>
</div>

Line height or vertical align in flexbox child

Minimal working example: http://jsfiddle.net/3qxfknd7/
You can see that the A and B are both centered horizontally within their respective divs, but not vertically. The height is dynamic, and thus I cannot set the line-height to the font-size, because a button with larger font-size will have to determine the line-height. Next to that, the class large may or may not be present: I cannot assume it is present!
How am I going to do this?
<div class="button-group">
<div class="button"><span>A</span></div>
<div class="button"><span class="large">B</span></div>
</div>
.button-group {
display: flex;
flex-flow: row nowrap;
align-content: flex-start;
justify-content: flex-start;
}
.button {
flex: 1 0 auto;
text-align: center;
outline: 1px solid red;
}
.button span {
font-size: 20px;
}
.button span.large {
font-size: 40px;
}
Not sure if this is what you are after:
.button-group {
display: flex;
flex-flow: row nowrap;
}
.button {
display:flex;
align-items: center;
flex: 1 0 auto;
align-content: center;
justify-content: center;
outline: 1px solid red;
}
.button span {
font-size: 20px;
}
.button span.large {
font-size: 40px;
}
<div class="button-group">
<div class="button"><span>A</span></div>
<div class="button"><span class="large">B</span></div>
</div>

Resources