Nested Flexbox Flex-Basis Not Working in Chrome or Opera - html

I have a row which is a flexbox filled with 3 columns which are also flexboxes. One of the columns is taller than the others so the shorter ones stretch to match it's height. However when I set flex-direction: column on the columns and fill one with elements with percentage based flex-basis it doesn't work in Chrome or Opera.
It works in Firefox and IE. It also works if I set a specific height on the column but I can't do that. I also don't want to use the flex-grow property to try and do this because the size would change if you add or take away elements. Does anyone know a workaround to make this work in Chrome and Opera?
<div class="row">
<div class="column col-1">
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
</div>
<div class="column col-2">
<div class="cell cell-1">1</div>
<div class="cell cell-2">2</div>
<div class="cell cell-3">3</div>
</div>
<div class="column col-3">
3
</div>
</div>
.row {
display: flex;
}
.column {
background: blue;
display: flex;
flex-direction: column;
margin: 5px;
}
.col-1 {
flex: 0 1 16.666%;
}
.col-2 {
flex: 0 1 33.333%;
}
.col-3 {
flex: 0 1 50%;
}
.cell {
background: gold;
margin: 5px;
}
.cell-1 {
flex: 0 1 16.666%;
}
.cell-2 {
flex: 0 1 33.333%;
}
.cell-3 {
flex: 0 1 50%;
}
Here is an example:
http://codepen.io/anon/pen/ZGZNjY

Related

html/css flex: How to prevent item in container exceed parent container height?

I have very simple layout:
+---------------+
| Header |
+---------------+
| | |
| | |
| Item1 | Item2 |
| | |
| | |
+---------------+
Which should be 100% of page height and Item2 should be vertically scrollable (Item 1 have fixed size and do not influence height).
I am trying to use flexbox. The root container is flex column which holds header and child flex container. The child container holds Item1 and Item2 and has flex: 1 to force items grows till bottom of the page.
The problem is, that when adding content to Item2 it's parent container starts to grow in height and exceed root container height! So scrollbar appears for the page, but I need only Item2 should be scrollable.
Is there any method to prevent this, only using flex features, not involving height, max-height? If it's not possible what is correct settings for heights in this situation?
<div style="display: flex; flex-direction:column; height: 100vh;">
<div>Hello Flex!</div>
<div style="flex: 1; display: flex">
<div style="flex: 1">
1
</div>
<div style="flex: 1; overflow: auto">
2<br>2<br>2<br>very long content, should be scrollable and NOT stretch parent.
</div>
</div>
</div>
To solve this with flexbox you need to wrap the box you want to scroll and add overflow-x: hidden; to the wrapping container. To fix some extra space use the calc() method. This happens, when is used height: 100vh; on a scrollable element.
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--header-height: 60px;
}
.container {
height: 100vh;
display: flex;
flex-direction: column;
background-color: #f1f1f1;
}
header {
min-height: var(--header-height);
display: flex;
justify-content: center;
align-items: center;
}
main {
display: flex;
}
.box1,
.box2 {
display: flex;
flex: 1 0 50%;
border: 1px solid red;
}
.box2 {
height: calc(100vh - var(--header-height));
background-color: antiquewhite;
overflow-x: hidden;
}
.scrollable {
width: 100%;
display: flex;
overflow-y: auto;
}
<div class="container">
<header>Hello Flex!</header>
<main>
<div class="box1">1</div>
<div class="box2">
<div class="scrollable">
2<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> 2
<br />2<br />2<br /> very long content, should be scrollable and NOT stretch parent.
</div>
</div>
</main>
</div>
Here is one possibility using CSS Grid Layout and flexbox. The height of the header was set at 200px but it could be anything or a relative unit.
<!DOCTYPE html>
<html>
<head>
<title>layout</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
#grid {
display: grid;
background: rgba(255, 255, 255, 0.5);
grid-template-rows: 200px calc(100vh - 200px);
}
#header {
background: blue;
}
#cols {
display: grid;
grid-template-columns: 1fr 1fr;
background: green;
}
#colA {
background: yellow;
}
#colB {
display: flex;
flex-direction: column;
overflow-y: auto;
background: orange;
}
#content {
padding: 1200px 20px;
}
</style>
</head>
<body>
<div id="grid">
<div id="header"></div>
<div id="cols">
<div id="colA"></div>
<div id="colB">
<div id="content">
colB content
</div>
</div>
</div>
</div>
</body>
</html>
See it on codepen.

How to set a multiple DIVs with pictures side by side to each other?

Does anyone know how to set multiple divs side-by-side that are centered and have at least 10 pixels gap between each other? I managed to do it but the following divs went right under the first 2.
Here is an example of what outcome I am expecting: https://imgur.com/a/p1ilgCu
And here is the outcome I made: https://imgur.com/a/JI0beTk
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 50px;
height: 50%;
width: 33.33%;
text-align: center;
transform: translate(50px, 20px);
}
.column1 {
background-color: whitesmoke;
margin-top: 10px;
border-radius: 20px;
}
<div class="container">
<div class="column1">
<img src="profilepiclink256x" style="width:50%">
<h1>text name</h1>
</div>
<div class="column1">
<img src="profilepiclink256x" style="width:50%">
<h1>text name</h1>
</div>
<div class="column1">
</div>
<div class="column1">
</div>
</div>
You can use flex to place them side by side. If you want them to fill the width of your parent element, use min-width on the children calculate 100% by the amount of divs and subtract the column gap. min-width: calc(100% / var(--num-cols) - var(--col-gap)); i used css variables.
:root {
--num-cols: 4;
--col-gap: 10px;
}
.container {
display: flex;
/* centers content when flex axis is set as row */
justify-content: center;
}
.column1 {
background-color: whitesmoke;
margin-top: 10px;
border-radius: 20px;
/* will fill parents width with children including gap
/* can also use flex-grow: 1; to fill parents width with children */
/* min-width: calc(100% / var(--num-cols) - var(--col-gap)); */
flex-grow: 1; /* remove if you do not want to spread entire width of parent width */
}
.column1~.column1 {
/* adds a gap of 10px to all but first col element */
margin-left: var(--col-gap);
}
<div class="container">
<div class="column1">
<img src="profilepiclink256x" style="width:50%">
<h1>text name</h1>
</div>
<div class="column1">
<img src="profilepiclink256x" style="width:50%">
<h1>text name</h1>
</div>
<div class="column1">
<img src="profilepiclink256x" style="width:50%">
<h1>text name</h1>
</div>
<div class="column1">
<img src="profilepiclink256x" style="width:50%">
<h1>text name</h1>
</div>
</div>
Use flex element in your css:
.container {
display: flex;
}

Resize flex items to fit container (prevent items from overflowing)

I've been struggling with an issue that i think will have a pretty simple solution, but i just can't see it right now. I have a nested flexbox layout. The first level of flex items are divs that are display:flex themselves, and depending on class they can have a flex-directon: of row or column. Both the first and second level of these nested flex items should grow to fill up the remaining parent size, and shrink if new elements are added, never overflowing.
My Problem: When adding new flex items to the "first level", this seems to work fine. However, adding new flex items to the second level seems to always overflow the parent container height.
As i'm not really good at describing stuff like this, here's a picture of what i need:
The purple box is the parent container (not flex)
The orange box is the flex container with flex-direction: row, with the red lines being its flex items (each item is a flexbox as well).
The blue lines are the nested flex items.
Nested Flexbox layout
Adding new red items works and expands or shrinks as needed, but adding new blue items, overflows the container.
https://jsfiddle.net/t40x7or8/
Here's my code sample:
CSS
width: 1800px;
height: 500px;
border: 4px blue solid;
}
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.flex-item {
flex-grow: 1;
flex-basis: 0;
display: flex;
}
.flex-item > div {
flex-grow: 1;
border: 1px solid orange;
}
.height-1 {
flex-direction: column;
max-height: 100%;
}
.height-2 {
max-height: 100%;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
HTML
<div class="flex-container">
<div class="height-2 flex-item">
<div class="img-div">
<img src="https://picsum.photos/1080/600" />
</div>
</div>
<div class="height-1 flex-item">
<div class="img-div">
<img src="https://picsum.photos/1080/601" />
</div>
<div class="img-div">
<img src="https://picsum.photos/1080/602" />
</div>
</div>
</div>
</div>
Sorry for the chaotic description, i'm quite bad at these kind of things.
Thanks for the help
I think we should use flex: 1 1 0 for the fix the layout of the flex items.
And using width: 100% to control the size of the inner image.
https://jsfiddle.net/ramseyfeng/kxf46bju/
.page {
border: 3px solid green;
width: 600px;
height: 300px;
}
.flex {
display: flex;
}
.cols {
display: flex;
flex-direction: row;
}
.rows {
display: flex;
flex-direction: column;
}
.flex-1-1-0 {
flex: 1 1 0;
}
.img-div {
flex: 1 1 0;
display: flex;
}
.img-div img {
width: 100%;
}
<div class="page cols">
<div class="flex-1-1-0 rows">
<div class="img-div">
<img src="https://picsum.photos/1080/600" />
</div>
</div>
<div class="flex-1-1-0 rows">
<div class="img-div">
<img src="https://picsum.photos/1080/601" />
</div>
<div class="img-div">
<img src="https://picsum.photos/1080/602" />
</div>
</div>
<div class="flex-1-1-0 rows">
<div class="img-div">
<img src="https://picsum.photos/1080/607" />
</div>
<div class="img-div">
<img src="https://picsum.photos/1080/608" />
</div>
</div>
<div class="flex-1-1-0 rows">
<div class="img-div">
<img src="https://picsum.photos/1080/605" />
</div>
<div class="img-div">
<img src="https://picsum.photos/2000/1000" />
</div>
<div class="img-div">
<img src="https://picsum.photos/2000/1001" />
</div>
</div>
</div>

100% height dependent on height of brother element

I need the element cnt-right to be height 100% of its sibling.
It doesn't have a parent element, only siblings.
Is it possible to accomplish this with CSS? Or do I have to use javascript?
I have this estructure: jsFiddle
.column {
display: block;
min-height: 50px;
background-color: #ccc;
text-align: center;
float: left;
}
.decktop-12 {
width: 100%;
}
.decktop-8 {
width: 66%;
}
.decktop-4 {
width: 33%;
}
.cnt {
background-color: #995595;
}
.cnt-right {
background-color: #559959;
}
<div class="mobile-12 decktop-12 cnt-top column">
Content top
</div>
<div class="mobile-12 decktop-8 cnt column">
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
</div>
<div class="mobile-12 decktop-4 cnt-right column">
Content - right
</div>
<div class="mobile-12 decktop-12 cnt-bottom column">
Content bottom
</div>
You can use only CSS creating a grid layout, javascript is not necessary: https://css-tricks.com/snippets/css/complete-guide-grid/
This is an example of what you could do:
.grid{
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-areas:
"header header"
"content right"
"footer footer"
}
.header {
grid-area: header;
}
.content {
grid-area: content;
background-color: #995595;
}
.right {
grid-area: right;
background-color: #559959;
}
.footer {
grid-area: footer;
}
.header, .footer{
min-height: 50px;
background-color: #ccc;
}
.grid > * {
text-align: center;
}
<div class="grid">
<div class="header">
Content top
</div>
<div class="content">
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
</div>
<div class="right">
Content - right
</div>
<div class="footer">
Content bottom
</div>
</div>
You can use css grid or flex displays.
I recommand you to have a look at :
https://css-tricks.com/snippets/css/complete-guide-grid/
https://css-tricks.com/snippets/css/a-guide-to-flexbox
And also at how Bootstrap 4 implemented their grid using flex :
https://getbootstrap.com/docs/4.0/layout/grid/
You will have more control over how your grid behaves and possibilities than with float.
I made you an example with using flex. In this example flex evens the columns height by default and looks similar to code written with float :
<div class="row">
<div class="mobile-12 desktop-12 column c1">
Content top
</div>
<div class="mobile-12 desktop-8 column c2">
Content - main
<br><br><br>
</div>
<div class="mobile-12 desktop-4 column c3">
Content - right
</div>
<div class="mobile-12 desktop-12 column c1">
Content bottom
</div>
</div>
<style>
.row {
display: flex;
flex-wrap: wrap; /* Allow multi-line */
}
.column {
flex-grow: 0; /* Prevents column from auto growing */
flex-shrink: 0; /* Prevents column from auto shrinking */
}
.mobile-12 {
flex-basis: 100%;
}
.desktop-8 {
flex-basis: 66.66666%;
}
.desktop-4 {
flex-basis: 33.33333%;
}
.c1 { background-color: grey; }
.c2 { background-color: purple; }
.c3 { background-color: green; }
</style>

flex-wrap not working in Safari and float left isn't an option

I have a setup where I am trying to have a div centered in the screen, yet the images within the div flex-wrap based on the parent divs width.
This works in all browsers except Safari.
float: left; won't work due to the centering issue.
I have a fiddle with the scene broken down...
http://jsfiddle.net/6f59t7qh/2/
<div class="gallery">
<div class="galleryBlock">
<div class="galleryTile">
<img src="http://hdcomputerwallpaper.com/wp-content/uploads/2013/12/Puppy-images.jpg" />
</div>
<div class="galleryTile">
<img src="http://hdcomputerwallpaper.com/wp-content/uploads/2013/12/Puppy-images.jpg" />
</div>
<div class="galleryTile">
<img src="http://hdcomputerwallpaper.com/wp-content/uploads/2013/12/Puppy-images.jpg" />
</div>
<div class="galleryTile">
<img src="http://hdcomputerwallpaper.com/wp-content/uploads/2013/12/Puppy-images.jpg" />
</div>
<div class="galleryTile">
<img src="http://hdcomputerwallpaper.com/wp-content/uploads/2013/12/Puppy-images.jpg" />
</div>
<div class="galleryTile">
<img src="http://hdcomputerwallpaper.com/wp-content/uploads/2013/12/Puppy-images.jpg" />
</div>
<div class="galleryTile">
<img src="http://hdcomputerwallpaper.com/wp-content/uploads/2013/12/Puppy-images.jpg" />
</div>
</div>
</div>
.gallery {
text-align: center;
background-color: green;
}
.galleryBlock {
width: 585px;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
flex-wrap: wrap; /* flex-wrap not working in Safari*/
background-color: red;
}
.galleryTile {
position: relative;
height: 100px;
width: 190px;
overflow: hidden;
margin: 0 5px 5px 0;
}
any thoughts would be great!
Thanks.
Check this:
center a block and set its children flex
1.You should always set the size of your image in px of percentage. if it's flexible
width: 100%;
height: 100%;
so the image could change with its parent's size.
2.just use these two can set a block horizontal center. text-align is not appropriate in this situation.
margin-left: auto;
margin-right: auto;
3.set .galleryBlock
display: -webkit-flex; /* Safari */
display: flex;
and set .galleryTile
-webkit-flex: 1; /* Safari 6.1+ */
-ms-flex: 1; /* IE 10 */
flex: 1;
Here's flex tutorial in W3C