I would like to align the divs in a way that on the left there is a big expandable box like the ones you can see and the 2 aligning ones one on top of the other on the right right by it
Imagine, instead of boxes 1&3 that you see in the code I've written, to have them as 1 big box and the other 2&4 stay as they are aligned to the big box.
I've been playing around with the flex command but cant get it to work
every time I use the flex commands it doesn't align properly and becomes a pyramid
If someone can help me out and explain it to me I'd appreciate it as I don't understand how to get it to work
.Scrollbox h1 {
color: #ffffff !important;
}
.scroll-con {
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.Scrollbox {
background: rgba(130, 164, 179,0.6);
border: 1px solid #ffffff;
overflow-y: scroll;
width: 300px;
height: 250px;
transition: height 1s ease;
overflow: hidden;
text-align: center;
color: #ffffff;
font-family: 'Poiret One', cursive;
}
.Scrollbox:hover {
height: 500px;
overflow-y: hidden;
}
<div class="scroll-con">
<div class="Scrollbox">1</div>
<div class="Scrollbox">2</div>
<div class="Scrollbox">3</div>
<div class="Scrollbox">4</div>
</div>
From what I understand, you want 1&3 to be one long box and 2&4 to be 2 individual boxes beside it?
You can split them up into two different divs where 2&4 will be children of the right div.
.container {
display: flex;
}
.container>div {
flex: 1;
}
.left {
background: pink;
min-height: 500px
}
.right {
display: flex;
flex-direction: column;
background: blue;
}
.right>div {
flex: 1;
}
.right>div:first-child {
background: yellow;
}
.right>div:last-child {
background: gold;
}
<div class="container">
<div class="left">1 & 3</div>
<div class="right">
<div>2</div>
<div>4</div>
</div>
</div>
Alternatively, you can use grid to do the same.
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.left {
min-height: 500px;
grid-row-start: 1;
grid-row-end: 3;
background-color: pink;
}
.left+div {
background-color: yellow;
}
.left+div+div {
background-color: gold;
}
<div class="container">
<div class="left">1 & 3</div>
<div>2</div>
<div>4</div>
</div>
Related
This question already has answers here:
Fill remaining vertical space with CSS using display:flex
(6 answers)
Closed last year.
I have the following markup:
.layout {
display: flex;
flex-direction: column;
background-color: gray;
height: 100vh;
}
.app-bar {
background-color: lightblue;
}
.app-drawer {
background-color: black;
color: white;
flex-grow: 1;
}
.app-sidebar-container {
}
<div class="layout">
<div id="app-bar-container">
<div class="app-bar">APP BAR</div>
</div>
<div id="app-sidebar-container" class="app-sidebar-container">
<div class="app-drawer">DRAWER AND CONTENT</div>
</div>
</div
How should I modify this in order to get the drawer and content black div to stretch the entire remaining layout element (gray)?
Thanks.
flex-grow only works for direct child.
.layout {
display: flex;
flex-direction: column;
background-color: gray;
height: 100vh;
}
.app-bar {
background-color: lightblue;
}
.app-drawer {
background-color: black;
color: white;
/* new line */
height: 100%;
}
.app-sidebar-container {
/* new line */
flex-grow: 1;
}
<div class="layout">
<div id="app-bar-container">
<div class="app-bar">APP BAR</div>
</div>
<div id="app-sidebar-container" class="app-sidebar-container">
<div class="app-drawer">DRAWER AND CONTENT</div>
</div>
</div
Give the background-color to the .app-sidebar-container class and give that height: 100%.
That will fill make the element stretch to the entire grey area.
Alternatively you could give both the .app-sidebar-container and the .app-drawer a height of 100%.
Both should work.
change your css like this:
.layout {
display: flex;
flex-direction: column;
background-color: gray;
height: 100vh;
}
#app-bar-container {
flex-grow: 0.1
}
.app-bar {
background-color: lightblue;
height: 100%;
}
.app-sidebar-container {
flex-grow: 1;
}
.app-drawer {
height: 100%;
background-color: black;
color: white;
flex-grow: 1;
}
I am using CSS media queries to create a responsive layout.
In my current HTML layout I use flexbox to align rows of divs:
<div id="page">
<div id="div-1">DIV 1</div>
<div id="div-2">DIV 2</div>
<div id="div-3">DIV 3</div>
<div id="div-4">DIV 4</div>
</div>
and CSS:
#page {
display: flex;
flex-direction: column;
align-items: center;
}
[id^="div-"] {
border: 1px solid #ccc;
margin-bottom: 10px;
width: 50vw;
}
#div-1 {
height: 50px;
}
#div-2 {
height: 70px;
}
#div-3 {
height: 150px;
}
#div-4 {
height: 100px;
}
Here is Jsfiddle for you to tinker with.
It is what I am after for a smaller viewports, but would like to switch things around on the next media query break point to have 2 middle divs to shift to a separate column on the right like this:
How do I achieve that? It is pretty obvious for me how to shift last few div rows to another column, but not sure how to tackle the middle rows...
Is there a way to do it by using flexbox or grid?
Another possible solution is to use the order-property in combination with Flexbox (drawback: you'll need a tiny bit of extra html and set the height of the #page container; advantages: flexible div heights and gap sizes):
#page {
display: flex;
flex-direction: column;
align-items: center;
}
[id^="div-"] {
border: 1px solid #ccc;
margin-bottom: 10px;
width: 50vw;
}
#div-1 {
height: 50px;
background: lightgreen;
}
#div-2 {
height: 70px;
background: lightyellow;
}
#div-3 {
height: 150px;
background: lightcoral;
}
#div-4 {
height: 100px;
background: lightblue;
}
#media (max-width: 1000px) {
#page {
flex-wrap: wrap;
height: 300px;
}
#small-screen-spacer {
order: 3;
align-self: stretch;
flex: 1 0 100%;
margin-right: 10px;
}
#div-1 {
order: 1;
}
#div-2 {
order: 4;
}
#div-3 {
order: 5;
}
#div-4 {
order: 2;
}
}
<div id="page">
<div id="div-1">DIV 1</div>
<div id="div-2">DIV 2</div>
<div id="div-3">DIV 3</div>
<div id="div-4">DIV 4</div>
<div id="small-screen-spacer"> </div>
</div>
The #small-screen-spacer will fill the entire available vertical space, so that all elements that come after the spacer (defined by the order property) are moved to the second column. Additionally you can set the desired gap between the two columns by setting margin-right on the spacer to your desired value.
Fiddle
I want to have a layout like the following image using flexbox:
I have tried the following but no luck so far:
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 200px;
}
.flex-item:not(:first-child) {
width: calc(100% - 50px);
background-color: gray;
border: 1px solid blue;
}
.flex-item:first-child {
width: 50px;
height: 100%;
border: 1px solid blue;
background-color: red;
}
<div class="flex-container">
<div class="flex-item">item 1(long)</div>
<div class="flex-item">item 2</div>
<div class="flex-item">item 3</div>
<div class="flex-item">item 4</div>
</div>
I need the DOM structure to be like this, otherwise, I already know how to achieve this with nested elements.
It's possible using your DOM structure but I doubt it will be particularly useful, and as others have said, you're better off using Grid or even just inline elements. The trouble is you are trying to mix two layout contexts and flexbox isn't really built for that.
Give the container a explicit height and the wider elements a flex:1 property, which will make them grow to fill the remaining space. I used nth-child as it is more readable to me and your original code didn't actually behave as you intended when put into codepen.
.flex-container {
border: 1px solid green;
display: flex;
flex-direction: column;
flex-wrap: wrap;
width: 200px;
height: 200px;
}
.flex-item {
height: 100%;
width: 50px;
background-color: gray;
border: 1px solid blue;
}
.flex-item:nth-child(n+2) {
width: calc(100% - 50px);
flex: 1;
border: 1px solid blue;
background-color: red;
}
<div class="flex-container">
<div class="flex-item">item 1(long)</div>
<div class="flex-item">item 2</div>
<div class="flex-item">item 3</div>
<div class="flex-item">item 4</div>
</div>
CSS Grid Layout would be more appropriate.
body {
background: white;
color: #323232;
font-weight: 300;
height: 100vh;
margin: 0;
font-family: Helvetica neue, roboto;
}
.flex-container {
display: grid;
width: 90%;
height: 50%;
margin: 2rem auto;
text-align: center;
grid-template-columns: 25% 75%;
grid-template-rows: 25% 25% 50%;
}
.flex-item1 {
grid-column: 1 / 2;
grid-row: 1 / 4;
background: pink;
}
.flex-item2 {
grid-column: 2 / 3;
grid-row: 1 / 2;
background: lightcoral;
}
.flex-item3 {
grid-column: 2 / 3;
grid-row: 2 / 3;
background: lemonchiffon;
}
.flex-item4 {
grid-column: 2 / 3;
grid-row: 3 / 4;
background: lightblue;
}
<div class="flex-container">
<div class="flex-item1">item 1</div>
<div class="flex-item2">item 2</div>
<div class="flex-item3">item 3</div>
<div class="flex-item4">item 4</div>
</div>
Although you can do it with Flexbox.
It makes more sense to me to make a small change to the DOM structure.
Your items 2, 3, 4 would be wrapped in an other Flex container.
body {
background: white;
color: #323232;
font-weight: 300;
height: 100vh;
margin: 0;
display: flex;
font-family: Helvetica neue, roboto;
}
.flex-container {
display: flex;
flex-wrap: wrap;
width: 90%;
height: 50%;
margin: 1rem;
text-align: center;
}
.flex-itemA {
width: 25%;
background: pink;
}
/* Flex-itemB and Flex container itself for the next 3 elements */
.flex-itemB {
width: 75%;
display: flex;
flex-wrap: wrap;
flex-direction: column;
background: lightblue;
}
.flex-itemB1,
.flex-itemB2 {
height: 25%;
}
.flex-itemB1 {
background: lightcoral;
}
.flex-itemB2 {
background: lemonchiffon;
}
<div class="flex-container">
<div class="flex-itemA">item A</div>
<div class="flex-itemB">
<div class="flex-itemB1">item B1</div>
<div class="flex-itemB2">item B2</div>
<div class="flex-itemB3">item B3</div>
</div>
</div>
EDIT based on #lawrence-witt answer
Or if you really want to keep the DOM structure that way and use Flexbox and not Grid. Then you could do it like #lawrence-witt suggested.
I kept the :nth-child selectors although it would be easy to add a class for each element and avoid increasing the specificity.
body {
background: white;
color: #323232;
font-weight: 300;
height: 100vh;
margin: 0;
font-family: Helvetica neue, roboto;
}
.flex-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
width: 90%;
height: 50%;
margin: 2rem 5%;
text-align: center;
}
.flex-item {
height: 100%;
width: 25%;
background: pink;
}
.flex-item:nth-child(n + 2) {
width: 75%;
/* This will make the height = 25% since the last element will have flex-grow: 1 */
flex: 0.5;
}
.flex-item:nth-child(2) {
background: lightcoral;
}
.flex-item:nth-child(3) {
background: lemonchiffon;
}
.flex-item:nth-child(4) {
flex: 1;
background: lightblue;
}
<div class="flex-container">
<div class="flex-item">item 1</div>
<div class="flex-item">item 2</div>
<div class="flex-item">item 3</div>
<div class="flex-item">item 4</div>
</div>
Here is the CSS, from the media query, all display:flex
video {
height: 800px;
width: auto;
}
.info {
order: 2;
border: 0.5 px solid #f7f7f7;
background: white;
width: 566.03px;
height: max-content;
position: relative;
}
.video-div {
border: 0.5 px solid #f7f7f7;
background: white;
width: 566.03px;
order: 1;
}
.interaction {
order: 3;
border: 0.5 px solid #f7f7f7;
background: white;
width: 566.03px;
height: max-content;
}
.middle {
height: 569px;
}
<main>
<div> First div</div>
<div> Second div</div>
<div> Third div</div>
</main>
This is where I am. I need to move the highlighted div, under the second div,(The small one "therock" div).
You can achieve this with flex pretty easily.
In my example below, there is a main div with flex-direction set to row. The right column is set to display: flex with flex-direction column. This stacks the children of main horizontally and children of right vertically.
html, body {
height: 100%
}
.main {
display: flex;
flex: 1 1 0;
flex-direction: row;
width: 100%;
height: 100%;
}
.left {
background: lightblue;
}
.right {
flex-grow: 1;
display: flex;
flex-direction: column;
background: pink;
}
.fill {
flex-grow: 1;
background: yellow;
}
<div class="main">
<div class="left"><img src="https://via.placeholder.com/150" /></div>
<div class="right">
<div>Blah blah blah</div>
<div class="fill">More blah blah</div>
</div>
</div>
This question already has answers here:
Stretch columns in two columns layout with shared header using flexbox
(2 answers)
Closed 4 years ago.
I have this layout, where a row wrap flex container has a first child with 100% width and 2 more children on the second row. The container has a fixed height and the first child (Filters block below) is collapsible (i.e. has 2 possibles values for height).
I would like the blocks on the last line to take all available height in all cases (filters block collapsed or expanded), but I can't find a solution.
I've tried various combinations of height, align-items/align-self: stretch, to no avail. Setting the pdt/list blocks height to 100% makes them effectively 100% of parent container, so they overflow due to the filters.
I know I could achieve it by making the first container flex column and throw in a second one with flex row,but I'd like to keep the current markup if possible. Any idea?
JSfiddle: https://jsfiddle.net/Lp4j6cfw/34/
HTML
<div id="lp-tag">
<div id="header">HEADER</div>
<div id="lp-ctnr">
<div id="filters" onclick="toggle()">FILTERS</div>
<div id="pdt">PDT</div>
<div id="list">LIST</div>
</div>
CSS
#lp-tag{
display: flex;
flex-flow: column nowrap;
width: 350px;
margin: auto;
border: 1px solid red;
height: 250px;
}
#header{
background: lightblue;
height: 80px;
}
#lp-ctnr{
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-content: flex-start;
align-items: stretch;
border: 1px solid green;
flex: 1;
}
#filters{
width: 100%;
background: lightgreen;
height: 45px;
}
.close{
height: 20px !important;
}
#pdt, #list {
flex: 1;
border: 1px solid blue;
text-align: center;
align-self: stretch;
}
#pdt{
background: yellow;
}
#list{
background: pink;
}
If you are open to alternative layout methods, I'd recommend CSS-Grid
.lp-tag {
width: 250px;
margin: 1em auto;
border: 1px solid red;
height: 250px;
display: inline-grid;
grid-template-rows: auto 1fr;
}
.header {
background: lightblue;
height: 80px;
}
.header.small {
height: 40px;
}
.lp-ctnr {
display: grid;
grid-template-rows: auto 1fr;
grid-template-columns: repeat(2, 1fr);
border: 1px solid green;
flex: 1;
}
.filters {
grid-column: 1 / span 2;
background: lightgreen;
height: 45px;
}
.filters.large {
height: 80px;
}
.pdt,
.list {
border: 1px solid blue;
text-align: center;
}
.pdt {
background: yellow;
}
.list {
background: pink;
}
<div class="lp-tag">
<div class="header">HEADER</div>
<div class="lp-ctnr">
<div class="filters" onclick="toggle()">FILTERS</div>
<div class="pdt">PDT</div>
<div class="list">LIST</div>
</div>
</div>
<div class="lp-tag">
<div class="header small">HEADER</div>
<div class="lp-ctnr">
<div class="filters large" onclick="toggle()">FILTERS</div>
<div class="pdt">PDT</div>
<div class="list">LIST</div>
</div>
</div>
This is the only solution I can see without an intermediary container. https://jsfiddle.net/5j38ouvs/
However, I would probably do like Nandita and add a surrounding container like here: https://jsfiddle.net/8md4oyLx/
CSS
#lp-ctnr{
display: flex;
flex-direction: column;
border: 1px solid green;
height: 550px;
width: 350px;
margin: auto;
}
#filters{
width: 100%;
background: lightgreen;
}
.close{
height: 20px !important;
}
#pdt{
flex-grow: 1;
background: yellow;
}
#list{
flex-grow: 1;
background: pink;
}
.list-container {
flex-grow: 1;
border: 1px solid blue;
text-align: center;
display: flex;
flex-direction: row;
}
HTML
<div id="lp-ctnr">
<div id="filters" onclick="toggle()">FILTERS</div>
<div class="list-container">
<div id="pdt">PDT</div>
<div id="list">LIST</div>
</div>
</div>