I'm trying to create a Slider Layout with flex boxes, like this photo :
Here I've big photo at right side and thumbnail items on the left. I want to align left side and thumbnails wrapper with big photo height. But unfortunately It's not possible only with flex boxes and I should check big photo height with JavaScript and align left side with that.
For example check this code:
main{
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
display: flex;
align-items: center;
justify-content: center;
}
.wrapper{
width: 500px;
overflow: hidden;
background: gray;
display: flex;
align-items: flex-start;
justify-content: center;
}
.right{
width: calc(100% - 150px);
height: 450px;
background: red;
}
.left{
width: 150px;
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: column;
}
.item{
width: 100%;
height: 50px;
color: white;
background: green;
display: flex;
align-items: center;
justify-content: center;
}
<main>
<div class="wrapper">
<div class="left">
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
</div>
<div class="right"></div>
</div>
</main>
In sample code I've not image and I handled this issue with 450px height in CSS.
So how can I align the left side with out JS and only with CSS? I want to use space-between mode to show all items in this height. Consider it, height:100% didn't work for this issue.
As per my comment, in order for your left column to extend to the height of your right column, all you need to do is remove the align items from your wrapper:
main{
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
display: flex;
align-items: center;
justify-content: center;
}
.wrapper{
width: 500px;
overflow: hidden;
background: gray;
display: flex;
/* align-items: flex-start; -- remove this */
justify-content: center;
}
.right{
/* width: calc(100% - 150px); I would swap this for flex grow, then you don't need hard values */
flex-grow: 1;
height: 450px;
background: red;
}
.left{
width: 150px;
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: column;
}
.item{
width: 100%;
height: 50px;
color: white;
background: green;
display: flex;
align-items: center;
justify-content: center;
}
<main>
<div class="wrapper">
<div class="left">
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
</div>
<div class="right"></div>
</div>
</main>
This solution uses CSS Grid layouts - use display: grid on your wrapper that lays out your left and right sections using grid-template-columns: 150px 1fr (remove the width definitions in right and left elements.).
Now add height: 100% to left and then for the items flex: 1 for the flexbox items to occupy the dynamic height coming from the right section - see demo below:
main {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
display: flex;
align-items: center;
justify-content: center;
}
.wrapper {
width: 500px;
overflow: hidden;
background: gray;
display: grid; /* make this a grid container */
grid-template-columns: 150px 1fr; /* 150px for left and rest for right*/
align-items: flex-start;
justify-content: center;
}
.right {
/* width: calc(100% - 150px);*/
height: 450px;
background: red;
}
.left {
/*width: 150px;*/
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: column;
height: 100%; /* ADDED */
}
.item {
width: 100%;
height: 50px;
color: white;
background: green;
display: flex;
align-items: center;
justify-content: center;
flex: 1; /* ADDED */
}
<main>
<div class="wrapper">
<div class="left">
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
<div class="item">
<strong>Item</strong>
</div>
</div>
<div class="right"></div>
</div>
</main>
Something like this can be done with flexbox, if you set the height of the container to be the height you want all your sliders to be:
.container {
display: flex;
flex-flow: column wrap;
height: 250px;
width: 250px;
}
.container > * {
display: flex;
flex-flow: row wrap;
flex: 1 100%;
}
.thumbs {
flex-direction: row;
margin-right: 5px;
}
.thumb {
background: red;
flex: 1 100%;
margin: 5px 0;
}
.large {
background: blue;
margin: 5px;
}
<div class="container">
<div class="thumbs">
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
</div>
<div class="large"></div>
</div>
Related
I have this image and this box I'm trying to put on the same line. The box is just going to be holding a header and some text, but I can't seem to get them on the same line. I'm using flexbox and I did some research into this, but can't quite work it out. Here's the code:
#container {
min-height: 95vh;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.box {
height: 400px;
width: 600px;
background-color: #f5f2ed;
text-align: justify;
padding: 20px;
}
img {
width: auto;
height: 400px;
border-radius: 16px;
}
<div id="container">
<div class="main">
<img src="/">
<div class="box">
<h2>hello</h2>
<p>paragraph here...</p>
</div>
</div>
</div>
I made two divs inside the container because the image is going to be outside the box with the text.
Maybe display: flex; in .main{} can fix the problem.
You should add display:flex property to main element and flex :1 property to both child elements of main element
#container {
min-height: 95vh;
}
.main {
display : flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.box {
height: 400px;
width: 50%;
flex : 1;
background-color: #f5f2ed;
text-align: justify;
padding: 20px;
}
img {
width: auto;
height: 400px;
flex : 1;
border-radius: 16px;
}
<div id="container">
<div class="main">
<div class="pic-div">
<img src="/">
</div>
<div class="box">
<h2>hello</h2>
<p>paragraph here...</p>
</div>
</div>
</div>
I have a flex parent container set to flex-wrap: wrap and justify-content: flex-end. I have one flex-child, button-group which i want to align to flex-start, but align-self is not working.
.container{
width: 500px;
height: 500px;
background: pink;
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
}
.button-group {
background: lightblue;
align-self: flex-start; /* Not working!*/
padding: 5px 10px;
}
.main-box {
width: 450px;
height: 300px;
background: lime;
}
.myfooter {
width: 50%;
height: 10%;
background-color: black;
}
<div class="container">
<div class="button-group">
<button></button>
<button></button>
<button></button>
</div>
<div class="main-box"></div>
<div class="myfooter"> </div>
</div>
How can I get the button group to align itself to the left while preserving the flex wrap?
Flexbox aligns items in 1D direction. Thats why the flex-start didnt work,
In oreder to make it work wrap it with a div and add appropriate styles as shown in the snippet
.container {
width: 500px;
height: 500px;
background: pink;
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
}
.button-group {
background: lightblue;
padding: 5px 10px;
display: inline-block;
}
.main-box {
width: 450px;
height: 300px;
background: lime;
}
.myfooter {
width: 50%;
height: 10%;
background-color: black;
}
.holder{width: 100%;}
<div class="container">
<div class="holder">
<div class="button-group">
<button>1</button>
<button>2</button>
<button>3</button>
</div>
</div>
<div class="main-box"></div>
<div class="myfooter"> </div>
</div>
If you don't need margin to the right side of button-group, you can simply use .margin-right:auto; on .button-group to make it align itself to the left.
.container{
width: 500px;
height: 500px;
background: pink;
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
}
.button-wrap {
display: flex;
flex-basis: 100%;
}
.button-group {
background: lightblue;
align-self: flex-start;
padding: 5px 10px;
margin-right: auto;
}
.main-box {
width: 450px;
height: 300px;
background: lime;
}
.myfooter {
width: 50%;
height: 10%;
background-color: black;
}
<div class="container">
<div class="button-wrap">
<div class="button-group">
<button></button>
<button></button>
<button></button>
</div>
</div>
<div class="main-box"></div>
<div class="myfooter"> </div>
</div>
Try this. You need to use a additional wrapper for button group and apply display: flex; flex-basis: 100%; for that wrapper.
https://jsfiddle.net/Sampath_Madhuranga/7ad2u804/
.container{
width: 500px;
height: 500px;
background: pink;
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
}
.button-wrap {
display: flex;
flex-basis: 100%;
}
.button-group {
background: lightblue;
align-self: flex-start; /* Not working!*/
padding: 5px 10px;
}
.main-box {
width: 450px;
height: 300px;
background: lime;
}
.myfooter {
width: 50%;
height: 10%;
background-color: black;
}
<div class="container">
<div class="button-wrap">
<div class="button-group">
<button></button>
<button></button>
<button></button>
</div>
</div>
<div class="main-box"></div>
<div class="myfooter"> </div>
</div>
Here what happened, the flex-direction default is row, so your child elements is placed horizontally, but because the container width is static and it cant expand to wrap all of your child elements, it push them down, that cause your layout may look vertically but it is still placed horizontally. And in that case (flex-direction: row) the align-self property only set the flex items in the vertical direction.
How to fix it, first, you need to apply flex-direction: column. Then you can set the align-self for your flex-items and now and it will align self horizontally
.container{
width: 500px;
height: 500px;
background: pink;
flex-direction: column;
display: flex;
flex-wrap: wrap;
}
.button-group {
background: lightblue;
align-self: flex-start; /*working now!*/
padding: 5px 10px;
}
.main-box {
width: 450px;
height: 300px;
background: lime;
align-self: flex-end;
}
.myfooter {
width: 50%;
height: 10%;
background-color: black;
align-self: flex-end;
}
<div class="container">
<div class="button-group">
<button></button>
<button></button>
<button></button>
</div>
<div class="main-box"></div>
<div class="myfooter"> </div>
</div>
This question already has answers here:
When flexbox items wrap in column mode, container does not grow its width
(9 answers)
Closed 4 years ago.
When I use flex-flow: column wrap, the parent element's width is not stretched.
*{
margin: 0;
padding: 0;
}
.box{
background: #f03;
position: relative;
display: inline-block;
/* top:10px; */
/* left: 10px; */
padding: 20px;
}
.in{
display: flex;
align-items: center;
flex-flow: column wrap;
max-height: 300px;
align-content: flex-start;
justify-content: space-between;
}
.item{
background: #fe3;
width: 100px;
margin-bottom: 20px;
height: 100px;
}
.item:last-child{
margin-left: 15px;
}
<body>
<div class="box">
<div class="in">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</div>
</body>
https://jsfiddle.net/p4oLk7dz/5/
So what should I do?
You are trying to have a flex container inside the oder one, the first one needs the display flex to get the content of the element below
I would also make some small changes but it really depends on what you are trying to achive.
If this isnt what you were looking for, please comment so i can try to improve it.
Hope this works :)
.box{
background: #f03;
position: relative;
display: flex;
max-width: 220px;
padding: 20px;
}
.in{
display: flex;
flex-wrap: wrap;
max-width: 220px;
}
*{
margin: 0;
padding: 0;
}
.box{
background: #f03;
position: relative;
display: flex;
max-width: 220px;
padding: 20px;
}
.in{
display: flex;
flex-wrap: wrap;
max-width: 220px;
}
.item{
background: #fe3;
width: 100px;
margin-bottom: 20px;
height: 100px;
}
.item-2{
order: 3;
}
.item-3{
margin-left: 20px;
}
<body>
<div class="box">
<div class="in">
<div class="item">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
</div>
</div>
</body>
<!-- 第三个并没有把父元素宽度撑开 -->
Remove the display properties from this class
.box{
background: #f03;
display: inline-block;
display:relative;
/* top:10px; */
/* left: 10px; */
padding: 20px;
}
and everything works !!!
*{
margin: 0;
padding: 0;
}
.box{
background: #f03;
padding: 20px;
}
.in{
display: flex;
align-items: center;
flex-flow: column wrap;
max-height: 300px;
align-content: flex-start;
justify-content: space-between;
}
.item{
background: #fe3;
width: 100px;
margin-bottom: 20px;
height: 100px;
}
.item:last-child{
margin-left: 15px;
}
<body>
<div class="box">
<div class="in">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</div>
</body>
you can check the result here https://jsfiddle.net/p4oLk7dz/30/
I'm trying to create a visual layout using Flexbox.
In this layout, controls are arranged in rows. Some of the rows will have a predefined height, and some of the rows will be anchored to both the top and bottom of the screen, which means they'll stretch their height to occupy all available space.
I've got a working layout that will achieve this, but there seems to be an issue when the rows with predefined height need stretch because their contents no longer fit. They seem to not actually be stretching, which causes them to overlap with one another.
Anyone know how to get the rows to resize in height, properly?
You can have a look at the current status here:
https://jsfiddle.net/cgledezma1101/o9zwa7na/
I'm using the following CSS for my containers:
.main-container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
height: 100vh;
}
.row {
flex: 1 1 auto;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
width: 100%;
}
.row2 {
height: 200px;
min-height: 200px;
}
.row1 {
height: 100px;
min-height: 100px;
}
.not-anchored {
height: 100px;
}
.anchored {
height: 100%;
}
A fixed height on the container means it cannot expand to accommodate a taller layout. Hence, flex items are forced to overlap on smaller screens.
Instead of height: 100vh, use min-height: 100vh.
Also, remove fixed heights on flex items. They override align-items: stretch.
revised fiddle
.main-container {
display: flex;
flex-flow: column nowrap;
min-height: 100vh;
}
.row {
display: flex;
flex-flow: row wrap;
}
.row.anchored { flex: 1; }
body { margin: 0; }
.item12 {
flex: 1 1 100px;
height: 200px;
min-width: 100px;
background: tomato;
}
.item21 {
flex: 1 1 200px;
height: 100px;
min-width: 100px;
background: deepskyblue;
}
.item {
text-align: center;
color: white;
font-weight: bold;
font-size: 3em;
border: 1px dashed black;
line-height: 100px;
margin-left: auto;
margin-right: auto;
}
.item.anchored {
flex: 1;
/* height: 100%; */
min-height: 150px;
background: hotpink;
}
<body>
<div class="main-container">
<div class="row row2 not-anchored">
<div class="item item12">
1.1
</div>
<div class="item item12">
1.2
</div>
<div class="item item12">
1.3
</div>
</div>
<div class="row anchored">
<div class="item anchored">
A.1
</div>
</div>
<div class="row row1 not-anchored">
<div class="item item21">
2.1
</div>
<div class="item item21">
2.2
</div>
</div>
<div class="row anchored">
<div class="item anchored">
A.2
</div>
</div>
</div>
</body>
It seems the issue arises from giving the .main-container element a height: 100vh;. Changing that to height: 100%; seems to fix it.
.main-container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
height: 100%;
}
.main-container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
height: 100%;
}
.row {
flex: 1 1 auto;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
width: 100%;
}
.row2 {
height: 200px;
min-height: 200px;
}
.row1 {
height: 100px;
min-height: 100px;
}
.not-anchored {
height: 100px;
}
.anchored {
height: 100%;
}
.item12 {
flex: 1 1 100px;
height: 200px;
min-width: 100px;
background: tomato;
}
.item21 {
flex: 1 1 200px;
height: 100px;
min-width: 100px;
background: deepskyblue;
}
.item {
text-align: center;
color: white;
font-weight: bold;
font-size: 3em;
border: 1px dashed black;
line-height: 100px;
margin-left: auto;
margin-right: auto;
}
.item.anchored {
flex: 1 1 100%;
height: 100%;
min-height: 150px;
background: hotpink;
}
<body>
<div class="main-container">
<div class="row row2 not-anchored">
<div class="item item12">
1.1
</div>
<div class="item item12">
1.2
</div>
<div class="item item12">
1.3
</div>
</div>
<div class="row anchored">
<div class="item anchored">
A.1
</div>
</div>
<div class="row row1 not-anchored">
<div class="item item21">
2.1
</div>
<div class="item item21">
2.2
</div>
</div>
<div class="row anchored">
<div class="item anchored">
A.2
</div>
</div>
</div>
</body>
The following produces:
I am using flexbox to center content with justify-content: center which works as intended but flexbox also moves divs to be side by side which I don't want.
Here is an example
.flex {
display: flex;
justify-content: center;
}
.content {
width: 100px;
height: 100px;
background-color: #000;
margin: 10px;
}
<div class="flex">
<div class="content">
</div>
<div class="content">
</div>
</div>
How can I use flexbox while retaining the default one div on top of the other positioning.
You can set flex-direction: column and then you have to use align-items: center. Default flex-direction is row.
.flex {
display: flex;
align-items: center;
flex-direction: column;
}
.content {
width: 100px;
height 100px;
color: #000;
border: 1px solid black;
padding: 5px;
margin: 5px;
}
<div class="flex">
<div class="content"></div>
<div class="content"></div>
</div>
Try following code,
.flex {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.content {
width: 100px;
height: 100px;
background-color: #000;
margin: 10px;
}
<div class="flex">
<div class="content">
</div>
<div class="content">
</div>
</div>