I am trying to create a masonry layout using flexboxes but I can't find a way to fill the gaps.
I attached a code pen example below
http://codepen.io/anon/pen/KpgMKX?editors=110
.wrapper {
margin: auto;
width: 1024px;
height: 100%;
display: flex;
flex-flow: row wrap;
align-items: stretch;
align-content: stretch;
}
Update:
Please note that flex-direction: column will not work for me as it breaks the order of the content.
Here's how I would do it:
http://codepen.io/anon/pen/gpwwpX
I made two more wrappers, one that is for the two boxes on the left and one that surrounds the two wrappers. Like this:
<div class="big-wrapper">
<div class="wrapper2">
<div class="box oneTwo"></div>
<div class="box oneOne"></div>
</div>
<div class="wrapper">
<div class="box oneOne"></div>
<div class="box oneOne"></div>
<div class="box twoOne"></div>
<div class="box oneTwo"></div>
<div class="box threes"></div>
</div>
</div>
Then in the CSS I just added the two new wrappers adjusted their widths a bit, but you can play with that of course.
Related
I'm using Bulma have a column of cards which need to have the same height regardless of the content.
To achieve so I have created the following class
.equal-height
display: flex
flex-direction: column
height: 100%
My HTML looks like
<div class='columns is-multiline'>
<div class='column is-one-fifth'>
<div class='card equal-height'>
<div class='card-content'>
# CONTENT GOES HERE
</div>
<div class='card-footer'>
# FOOTER GOES HERE
</div>
</div>
</div>
<div class='column is-one-fifth'>
<div class='card equal-height'>
<div class='card-content'>
# CONTENT GOES HERE
</div>
<div class='card-footer'>
# FOOTER GOES HERE
</div>
</div>
</div>
</div>
Which produces something like
Now I'm trying to make the card-footer to stick at the bottom of the card like below.
I have tried a few things with flex but they don't really make sense.
Any ideas on how I may do it?
Add "flex: auto;" to '.card-contents' to make the card-footer to stick at the bottom of the card. Here is the working jsfiddle link.
.equal-height {
display: flex;
flex-direction: column;
height: 100%;
}
.equal-height .card-content {
flex: auto;
}
Add this CSS
.card-footer {
margin-top: auto;
}
working demo : https://jsfiddle.net/baLg7940/
UPDATE:
I made a fiddle for testing.
An illustration of what I'd like to achieve: (Rows and columns are Bootstrap 4 rows and columns.)
The page should only have scrollbars if the second row is already
"fully compressed" (0 height) and still the header + first row +
footer can't fit in the viewport.
The second row doesn't have to fill
in all remaining pale green place. It's height can be flexible.
Flexbox? Max-width? Overflow... How should I start? What could be a good solution?
HTML:
<div class="page">
<div class="header">
...<br>...
</div>
<div class="main">
<div class="container-fluid">
<div class="row">
<div class="col-6">
<div class="card">
<div class="card-header"> .... </div>
<div class="card-body"> .... </div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-header"> .... </div>
<div class="card-body"> .... </div>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
<div class="card">
<div class="card-header"> .... </div>
<div class="card-body scrollable"> THIS <br> SHOULD <br> BE <br> THE <br> SCROLLABLE <br> CONTENT </div>
</div>
</div>
</div>
</div>
</div>
<div class="footer">
...
</div>
</div>
CSS:
div.page {
background-color: palegreen;
display: flex;
flex-direction: column;
min-height: 100vh;
max-height: 100vh;
}
div.header,
div.footer {
background-color: grey;
padding: 0.5em;
}
div.main {
display: flex;
flex-grow: 1;
}
div.row {
margin-top: 1em;
}
div.scrollable {
/* ??? */
}
The key is how you calculate the height for the <main> and usage of flex, esp. flex-grow, flex-shrink.
<header>, <main> and <footer>
The second row doesn't have to fill in all remaining pale green place. It's height can be flexible.
So I assume you want the <header> and <footer> always stay on top and bottom. Instead of regular absolute positioning approach, I want to explicitly set the heights for them, as well as for <main>.
HTML
<header>header</header>
<main class="container-fluid"></main>
<footer>footer</footer>
SCSS
$custom-header-height: 3rem;
$custom-footer-height: 2rem;
header, footer {
background-color: var(--gray);
// In order to position the text to the center, like your picture
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
header {
height: $custom-header-height;
}
footer {
height: $custom-footer-height;
}
main {
// Calculate the height for main, which is 100% viewport height -
// height of header - height of footer
height: calc(100vh - #{$custom-header-height} - #{$custom-footer-height});
background-color: var(--teal);
}
Result
This gives you the playground you can build stuff on.
First Row
The first row is free to expand as high as its contents, but you don't want it to take up any free space. That's why you set flex-grow: 0;. Also when you resize the window and the space for first row is shrinking, you don't want the cards go over the row. That's why you set flex-shrink: 0;. We might as well use the shortcut flex: 0 0 auto; for those 2.
But in order to set that, the first row (as well as the second row) needs to be flexbox children. So we set display:flex; on its parent - <main>.
HTML
<header>header</header>
<main class="container-fluid">
<div class="row first-row">
<div class="col-6">
<div class="card">...</div>
</div>
<div class="col-6">
<div class="card">...</div>
</div>
</div>
</main>
<footer>footer</footer>
SCSS (In addition)
main {
display: flex;
flex-flow: column nowrap;
}
.first-row {
// I purposely make first row's background yellow so that you can see it
background-color: var(--yellow);
flex: 0 0 auto;
}
Result
Second Row
The key here is to make the <card> not to grow when there is space, but shrink on limited space, which is the default of flexbox children: flex: 0 1 auto;
But again, in order to use that, its parent needs to display: flex;. Here the parent is col-6 since we want to use bootstrap grid system.
HTML
<header>header</header>
<main class="container-fluid">
<div class="row first-row">
<div class="col-6">
<div class="card">...</div>
</div>
<div class="col-6">
<div class="card">...</div>
</div>
</div>
<div class="row second-row">
<div class="col-6">
<div class="card">
...
...
...
</div>
</div>
</div>
</main>
<footer>footer</footer>
SCSS (In addition)
.second-row {
// I purposely make second row's background to be blue so that you can see it
background-color: var(--blue);
// Any column, class name starts as "col-"
[class*="col-"] {
display: flex;
flex-flow: column nowrap;
// So that when the second row is compressed to 0, it doesn't show
// the row completely.
min-height: 0;
.card {
// flex-grow: 0;
// flex-shrink: 1;
// Might as well just set it
// flex: 0 1 auto;
// But this is the default of flexbox children so we don't need to set
// it here.
.card-body {
overflow-y: auto;
}
}
}
}
Result
The second row doesn't have to fill in all remaining pale green place. It's height can be flexible.
An illustration of what I'd like to achieve
The page should only have scrollbars if the second row is already "fully compressed" (0 height) and still the header + first row + footer can't fit in the viewport
Notes
There is still a funkiness when the second row is fully compressed. The scrollbar is still hanging there and I don't know how to get rid of it.
The code can be simplified a little bit without usage of bootstrap grid system.
Demo
https://codepen.io/anon/pen/XBqyxZ
Sorry for this lengthy post. If you want to know more about flexbox, here is a great guide: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
I would but a set the height (or max-height if you prefer) on the card and then set overflow to scroll.
<html>
<div class="box">
<div class="content">
Dispassionate extraterrestrial observer citizens of distant epochs
permanence of the stars billions upon billions vastness is bearable only
through love brain is the seed of intelligence.
</div>
</div>
</html>
<style>
.box {
width: 500px;
overflow: scroll;
}
</style>
I am trying to split my webpage into two vertical columns which can be clicked on to take you to the right pages. I've gotten this far.
HTML
<!-- Choices -->
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-xs-12 vertical-center webd">
<h1 class="text-muted text-center">Web Design</h1>
</div>
<div class="col-md-6 col-xs-12 vertical-center circ">
<h1 class="text-muted text-center">Circus</h1>
</div>
</div>
</div>
CSS
.vertical-center {
min-height: 100%;
min-height: 100vh;
display: flex;
align-items: center;
}
.webd {
background-image: url('webd.jpg');
}
.circ {
background-image: url(circ.JPG);
}
My issue is, no matter where I put the text-center class. My <h1>s stay left aligned on the page. Can anybody help?
It is because you have added display flex to the parent container. This means the children are not full width anymore.
If you add the following style, it will fix your error:
.vertical-center > .text-center
{
flex-grow: 1;
}
Example bootply
If you don't want to grow the children, you can just add the following to your vertical center: justify-content: center;
Example bootply 2
This question already has answers here:
Zebra striping a flexbox table with wrapping items
(3 answers)
Closed 8 months ago.
When using tables, it is easy to alternate colors in table rows using the nth child selectors (https://stackoverflow.com/a/3084318/1385857). Is there a comparable way to do so when using the flexbox layout. I have the following (from https://philipwalton.github.io/solved-by-flexbox/demos/grids/):
<div class="Grid">
<div class="Grid-cell"></div>
[more divs]
<div class="Grid-cell"></div>
</div>
.Grid
{
display: flex;
flex-wrap: wrap;
}
.Grid-cell
{
flex: 1;
}
Is it possible to alternate row colors in this scenario. To clarify, there are no real rows, only the virtual rows created by flex box due to wrapping.
A bit late but it might help others. Here is a working solution I've just come up with.
It uses the linear-gradient CSS function.
The only downside is that it requires your cells to have a fixed height.
/* $cell_height: 80px */
.grid {
display: flex;
flex-flow: row wrap;
/* this is where the magic is */
background-image: linear-gradient(180deg, red 50%, green 50%);
background-repeat: repeat;
background-size: 100px 160px; /* width is not relevant, but height must be 2*$cell_height */
}
.grid-cell {
height: 80px; /* $cell_height */
/* this is just to have a responsive display for the demo */
width: 25%;
min-width: 250px;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
<div class="grid">
<div class="grid-cell">1</div>
<div class="grid-cell">2</div>
<div class="grid-cell">3</div>
<div class="grid-cell">4</div>
<div class="grid-cell">5</div>
<div class="grid-cell">6</div>
<div class="grid-cell">7</div>
<div class="grid-cell">8</div>
<div class="grid-cell">9</div>
<div class="grid-cell">10</div>
<div class="grid-cell">11</div>
<div class="grid-cell">12</div>
<div class="grid-cell">13</div>
<div class="grid-cell">14</div>
</div>
This is a super old post, but I guess still relevant as this issue just came up for me where I had to do a static layout that's responsive going from two columns to four, so trying to organize the columns into rows like an actual table didn't make sense. The above answer with the repeating gradient is creative and works great if you can have a fixed height on your items, but the down-voted nth-child selector answer is better with flex-box if your items need to wrap and have flexible heights. I think that answer just needed to be tweaked a bit for the situation.
<div class="list-cols">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
<div>Eight</div>
<div>Nine</div>
<div>Ten</div>
<div>Eleven</div>
<div>Twelve</div>
<div>Thirteen</div>
<div> </div>
<div> </div>
<div> </div>
</div>
Then adjust your selector for how many columns you have. In this case I've got 4 columns, so the nth-of-type formula selects 1-4, 9-12, etc. In your markup, the number of children needs to be divisible by 4 to make a complete last row, so fill it out with empty divs if necessary.
.list-cols {
display: flex;
flex-wrap: wrap;
}
.list-cols > div {
padding: 8px 12px;
box-sizing: border-box;
flex-basis: 25%;
width: 25%;
}
.list-cols > div:nth-of-type(8n+1),
.list-cols > div:nth-of-type(8n+2),
.list-cols > div:nth-of-type(8n+3),
.list-cols > div:nth-of-type(8n+4) {
background: #f2f2f2;
}
You can use the same technic with nth-child (2n+1, even, odd), or whatever you want.
The display of the element doesn't interfere with that here.
.Grid {
display: flex;
flex-wrap: wrap;
}
.Grid-row {
flex: 1;
}
.Grid-cell:nth-child(2n+1) {
background: pink;
}
<div class="Grid">
<div class="Grid-row">
<div class="Grid-cell">Grid-cell 1</div>
<div class="Grid-cell">Grid-cell 2</div>
<div class="Grid-cell">Grid-cell 3</div>
<div class="Grid-cell">Grid-cell 4</div>
<div class="Grid-cell">Grid-cell 5</div>
<div class="Grid-cell">Grid-cell 6</div>
<div class="Grid-cell">Grid-cell 7</div>
</div>
<div class="Grid-row">
<div class="Grid-cell">Grid-cell 1</div>
<div class="Grid-cell">Grid-cell 2</div>
<div class="Grid-cell">Grid-cell 3</div>
<div class="Grid-cell">Grid-cell 4</div>
<div class="Grid-cell">Grid-cell 5</div>
<div class="Grid-cell">Grid-cell 6</div>
<div class="Grid-cell">Grid-cell 7</div>
</div>
</div>
I noticed a weird bug in all the major browsers when you use a percentage width on an element in a nested flexbox with its justify-content property set to "flex-end". It renders the parent element as if the child were set to 100% width regardless of the percentage actually used by the child.
I have created a Fiddle to demonstrate the issue: https://jsfiddle.net/u21pe916/
HTML
<div class="wrapper">
<div class="flex-col-1">Column 1</div>
<div class="flex-col-2">
<div class="nested-col-1" id="percent-width">Nested Column 1</div>
<div class="nested-col-2">Nested Column 2</div>
</div>
</div>
<div class="wrapper">
<div class="flex-col-1">Column 1</div>
<div class="flex-col-2">
<div class="nested-col-1" id="unit-width">Nested Column 1</div>
<div class="nested-col-2">Nested Column 2</div>
</div>
</div>
CSS
.wrapper {
display: flex;
justify-content: flex-end;
}
.flex-col-2 {
display: flex;
justify-content: flex-end;
}
.nested-col-1 {
/* Overflow is for display purposes. It does not affect the bug. */
overflow: hidden;
}
#percent-width {
width: 0%;
}
#unit-width {
width: 0px;
}
Screenshot
Is there a fix/work-around so that percentage values can be used without creating the extra space?