What I am trying to achieve without javascript is to have four buttons arranged in a 2x2 matrix as long as all of their content fits into a cell. When any of them is too long to fit, it should wrap into a 1x4 matrix, with all the cells being having full width. The best I could come up with for now is something like the snippet below. It is just fine until the point where after the wrap the cells should have full width.
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-content: flex-start;
align-items: center;
border: 1px solid red;
}
.flex-item {
flex: 0 1 auto;
align-self: auto;
min-width: 40%;
max-width: 100%;
text-align: center;
padding: 10px;
border: 1px solid blue;
margin: 5px;
}
<div class="flex-container">
<div class="flex-item">AAA</div>
<div class="flex-item">BBBBBB</div>
<div class="flex-item">CCCCCCCCC</div>
<div class="flex-item">DDDDDDDDDDD</div>
</div>
<div class="flex-container" style="width: 280px; margin-top: 2em;">
<div class="flex-item">AAA</div>
<div class="flex-item">BBBBBB</div>
<div class="flex-item">CCCCCCCCC</div>
<div class="flex-item">DDDDDDDDDDD</div>
</div>
<div class="flex-container" style="width: 150px; margin-top: 2em;">
<div class="flex-item">AAA</div>
<div class="flex-item">BBBBBB</div>
<div class="flex-item">CCCCCCCCC</div>
<div class="flex-item">DDDDDDDDDDD</div>
</div
Something like this? I made flex:1; for .flex-item
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-content: flex-start;
align-items: center;
border: 1px solid red;
}
.flex-item {
flex:1;
align-self: auto;
min-width: 40%;
max-width: 100%;
text-align: center;
padding: 10px;
border: 1px solid blue;
margin: 5px;
}
<div class="flex-container">
<div class="flex-item">AAA</div>
<div class="flex-item">BBBBBB</div>
<div class="flex-item">CCCCCCCCC</div>
<div class="flex-item">DDDDDDDDDDD</div>
</div>
<div class="flex-container" style="width: 280px; margin-top: 2em;">
<div class="flex-item">AAA</div>
<div class="flex-item">BBBBBB</div>
<div class="flex-item">CCCCCCCCC</div>
<div class="flex-item">DDDDDDDDDDD</div>
</div>
<div class="flex-container" style="width: 150px; margin-top: 2em;">
<div class="flex-item">AAA</div>
<div class="flex-item">BBBBBB</div>
<div class="flex-item">CCCCCCCCC</div>
<div class="flex-item">DDDDDDDDDDD</div>
</div
Related
I would like to create a gallery which has a block for ads at the right side. The gallery images should float around the ad block. If possible, I would also like that the ad block doesn't "get buried" on smaller screens (or when it's collapsed in the desktop browser), but is shown as high up as possible.
But whatever I try, I can't flex my head around this problem. Wrapper boxes, justifying them in any possible way, using order etc didn't work.
.wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
.wrapper article {
border: 1px #ccc solid;
padding: 10px;
}
article {
flex: 5;
}
.inner-wrapper {
display: flex;
flex-wrap: wrap;
border: 1px #ccc solid;
justify-content: center;
flex-direction: row;
}
.video-box {
display: flex;
border: 1px #ccc solid;
height: 130px;
width: 190px;
font-size: 60px;
font-weight: bold;
color: white;
background-color: cornflowerblue;
align-items: center;
justify-content: center;
}
.add-box {
display: flex;
height: 260px;
width: 380px;
font-size: 60px;
font-weight: bold;
color: white;
background-color: orangered;
align-items: center;
justify-content: center;
}
<div class="wrapper">
<article>
<h2>Videos</h2>
<div class="inner-wrapper">
<div class="add-box">Ads</div>
<div class="video-box">1</div>
<div class="video-box">2</div>
<div class="video-box">3</div>
<div class="video-box">4</div>
<div class="video-box">5</div>
<div class="video-box">6</div>
<div class="video-box">7</div>
<div class="video-box">8</div>
<div class="video-box">9</div>
<div class="video-box">10</div>
<div class="video-box">11</div>
<div class="video-box">12</div>
<div class="video-box">13</div>
<div class="video-box">14</div>
<div class="video-box">15</div>
<div class="video-box">16</div>
<div class="video-box">17</div>
<div class="video-box">18</div>
<div class="video-box">19</div>
<div class="video-box">20</div>
<div class="video-box">21</div>
</div>
</article>
</div>
Result:
Any solution except CSS grid (because it's less supported) is much appreciated.
Sounds like a good use case for desandro/masonry.
var elem = document.querySelector('.grid');
var msnry = new Masonry(elem, {
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
percentPosition: true
});
.wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
.wrapper article {
border: 1px #ccc solid;
padding: 10px;
}
article {
flex: 5;
}
.inner-wrapper {
display: flex;
flex-wrap: wrap;
border: 1px #ccc solid;
justify-content: center;
flex-direction: row;
}
.video-box {
display: flex;
border: 1px #ccc solid;
height: 130px;
width: 190px;
font-size: 60px;
font-weight: bold;
color: white;
background-color: cornflowerblue;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.add-box {
display: flex;
height: 260px;
width: 380px;
font-size: 60px;
font-weight: bold;
color: white;
background-color: orangered;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
<script src="https://unpkg.com/masonry-layout#4/dist/masonry.pkgd.min.js"></script>
<div class="wrapper">
<article>
<h2>Videos</h2>
<div class="inner-wrapper grid">
<div class="grid-item add-box">Ads</div>
<div class="grid-sizer grid-item video-box">1</div>
<div class="grid-item video-box">2</div>
<div class="grid-item video-box">3</div>
<div class="grid-item video-box">4</div>
<div class="grid-item video-box">5</div>
<div class="grid-item video-box">6</div>
<div class="grid-item video-box">7</div>
<div class="grid-item video-box">8</div>
<div class="grid-item video-box">9</div>
<div class="grid-item video-box">10</div>
<div class="grid-item video-box">11</div>
<div class="grid-item video-box">12</div>
<div class="grid-item video-box">13</div>
<div class="grid-item video-box">14</div>
<div class="grid-item video-box">15</div>
<div class="grid-item video-box">16</div>
<div class="grid-item video-box">17</div>
<div class="grid-item video-box">18</div>
<div class="grid-item video-box">19</div>
<div class="grid-item video-box">20</div>
<div class="grid-item video-box">21</div>
</div>
</article>
</div>
I have an html page utilizing flex-box and a table which has text rows, in which some contain emojis and some do not. I have been unsuccessful thus far getting the rows to align vertically, such that all rows are centered vertically.
I have tried various combinations of margin and padding to no avail.
In the code provided you will see that rows without emojis are at the top and the ones with emojis are centered. If I make the rows without emojis centered, the rows with emojis are at the bottom. My goal is to have all rows properly centered vertically within the row under all cases.
.wrapper1 {
max-height: 200px;
margin-top: 50px;
margin-bottom: 15px;
padding-right: 25px;
padding-left: 25px;
}
.wrapper2 {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.wrapper3 {
max-height:150px;
overflow: auto;
width: 100%;
}
.sm_table_header {
display:flex;
flex-direction: column;
border-top-left-radius:4px;
border-top-right-radius:4px;
color:#ffffff;
background-color: #307eab;
height: 20px;
}
.sm_table_row {
height: 25px;
display: flex; display: -webkit-flex;
flex-direction: row; -webkit-flex-direction: row;
flex-grow: 0; -webkit-flex-grow: 0;
flex-wrap: wrap; -webkit-flex-wrap: wrap;
width: 100%;
border-bottom: 1px solid silver;
border-collapse: collapse;
}
<div class="wrapper1">
<div class="wrapper2">
<div class="wrapper3">
<div class="sm_table_header ui-widget-header">
<div class="sm_table_row">
<div class="sm_table_subject_head">Subject</div>
</div>
</div>
</div>
<div class="wrapper3">
<div class="sm_table_body">
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji </div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">test 3</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject"><span class="span.emoji" style=">π</span>"Test Emoji 2 <span class="span.emoji">π</span> - good deal</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji 2 <span class="span.emoji">π</span> - good deal</div>
</div>
</div>
</div>
You can simply set the line-height for .sm_table_row, will center each element perfectly.
.sm_table_row {
line-height: 25px;
}
.wrapper1 {
max-height: 200px;
margin-top: 50px;
margin-bottom: 15px;
padding-right: 25px;
padding-left: 25px;
}
.wrapper2 {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.wrapper3 {
max-height:150px;
overflow: auto;
width: 100%;
}
.sm_table_header {
display:flex;
flex-direction: column;
border-top-left-radius:4px;
border-top-right-radius:4px;
color:#ffffff;
background-color: #307eab;
height: 20px;
}
.sm_table_row {
height: 25px;
display: flex; display: -webkit-flex;
flex-direction: row; -webkit-flex-direction: row;
flex-grow: 0; -webkit-flex-grow: 0;
flex-wrap: wrap; -webkit-flex-wrap: wrap;
width: 100%;
border-bottom: 1px solid silver;
border-collapse: collapse;
line-height: 25px;
}
<div class="wrapper1">
<div class="wrapper2">
<div class="wrapper3">
<div class="sm_table_header ui-widget-header">
<div class="sm_table_row">
<div class="sm_table_subject_head">Subject</div>
</div>
</div>
</div>
<div class="wrapper3">
<div class="sm_table_body">
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji </div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">test 3</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject"><span class="span.emoji" style=">π</span>"Test Emoji 2 <span class="span.emoji">π</span> - good deal</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji 2 <span class="span.emoji">π</span> - good deal</div>
</div>
</div>
</div>
on .sm_table_row use
align-items: center;
"Flex items can be aligned in the cross axis of the current line of the flex container, similar to justify-content but in the perpendicular direction. align-items sets the default alignment for all of the flex containerβs items, including anonymous flex items."
- flexbox cheatsheet: https://yoksel.github.io/flex-cheatsheet/#align-items
.wrapper1 {
max-height: 200px;
margin-top: 50px;
margin-bottom: 15px;
padding-right: 25px;
padding-left: 25px;
}
.wrapper2 {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.wrapper3 {
max-height:150px;
overflow: auto;
width: 100%;
}
.sm_table_header {
display:flex;
flex-direction: column;
border-top-left-radius:4px;
border-top-right-radius:4px;
color:#ffffff;
background-color: #307eab;
height: 20px;
}
.sm_table_row {
height: 25px;
display: flex; display: -webkit-flex;
flex-direction: row; -webkit-flex-direction: row;
flex-grow: 0; -webkit-flex-grow: 0;
flex-wrap: wrap; -webkit-flex-wrap: wrap;
width: 100%;
align-items: center;
border-bottom: 1px solid silver;
border-collapse: collapse;
}
<meta charset="utf-8">
<div class="wrapper1">
<div class="wrapper2">
<div class="wrapper3">
<div class="sm_table_header ui-widget-header">
<div class="sm_table_row">
<div class="sm_table_subject_head">Subject</div>
</div>
</div>
</div>
<div class="wrapper3">
<div class="sm_table_body">
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji </div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">test 3</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject"><span class="span.emoji" style=">π</span>"Test Emoji 2 <span class="span.emoji">π</span> - good deal</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji 2 <span class="span.emoji">π</span> - good deal</div>
</div>
</div>
</div>
hey I'm new in Flexbox and I'm trying to get it as best as I can. However i faces a problem with some heights and orders, maybe some here could help out.
Note: Don't suggest using Grid/tables please.
this is what I have right now:
this is what I want to get:
html:
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="title">Title</div>
<div class="more">More</div>
</div>
<div class="lower-container">
<div class="runtime">Runtime</div>
<div class="description">Description</div>
<div class="director">Director</div>
</div>
</div>
css:
.movie-container{
display:flex;
flex-flow: column wrap;
}
.upper-container {
display: flex;
width:80%;
margin:0 auto;
flex-flow: raw wrap;
}
.upper-container div {
border: 1px solid black;
padding: 10px;
}
.lower-container {
display: flex;
width:80%;
margin:0 auto;
flex-flow: column wrap;
}
.lower-container div {
border: 1px solid black;
padding: 10px;
}
.image {
flex: 1;
}
.title {
flex: 3;
}
.more {
flex: 0.1;
}
.runtime{
}
.description{
}
.director{
}
Maybe other stuff need to be added beside flexbox I'm not sure, that's why I ask here. Any solution will be helpful!
If you change your HTML structure slightly you can accomplish this fairly easily:
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="side-container">
<div class="title">Title</div>
<div class="more">More</div>
<div class="runtime">Runtime</div>
<div class="description">Description</div>
</div>
</div>
<div class="lower-container">
<div class="director">Director</div>
</div>
</div>
JSFiddle
Flex isn't very good at stretching across multiple rows / columns like tables or Grid is, while you state you don't want that solution it is typically a better option in cases like this.
I find it easiest to work with flexbox on a row-by-row basis instead of using wrapping (although you can certainly do that too).
As a starting point, I think this snippet is what you're going for?
div {
flex: 1 1 auto;
}
.box {
border: 1px solid black;
}
.flex {
display: flex;
}
.image {
width: 120px;
flex: 0 0 auto;
}
.more {
flex: 0 0 auto;
}
<div class="flex upper">
<div class="box flex image">Image</div>
<div class="upper-detail">
<div class="flex title-container">
<div class="box title">Title</div>
<div class="box more">More</div>
</div>
<div class="box runetime">Runtime</div>
<div class="box director">Director</div>
</div>
</div>
<div class="box description">Description</div>
<div class="box other">Other stuff...</div>
Hope this helps.
.upper-container{
display: flex;
height: 200px;
}
.upper-left{
background: #ddd;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.upper-right{
flex: 3;
display: flex;
flex-direction: column;
height: 100%;
}
.title-more, .runtime, .director{
flex: 1;
border: 1px solid #222;
display: flex;
align-items: center;
}
.lower-container{
border: 1px solid #222;
padding: 10px;
}
.title-more{
justify-content: space-between;
}
.more-button{
height: 30px;
width: 100px;
border: 1px solid #333;
margin-right: 5px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="movie-container">
<div class="upper-container">
<div class="upper-left">
Image
</div>
<div class="upper-right">
<div class="title-more">
<div class="title-container">
Title
</div>
<div class="more-button">
More
</div>
</div>
<div class="runtime">Runtime</div>
<div class="director">Director</div>
</div>
</div>
<div class="lower-container">
Description
</div>
</div>
The key is to add some divs and remove some others:
.movie-container *{padding:.5em;}
.upper-container {
display: flex;
padding:0;
}
.image {
border: 1px solid;
flex: 1 1 25%;
}
.tmrd{flex: 1 1 75%;padding:0}
.title-more {
display: flex;
padding:0;
}
.title{flex: 1 1 75%;border: 1px solid;}
.more{flex: 1 1 25%;border: 1px solid;}
.runtime,.description,.director{border: 1px solid;}
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="tmrd">
<div class="title-more">
<div class="title">Title</div>
<div class="more">More</div>
</div>
<div class="runtime">Runtime</div>
<div class="description">Description</div>
</div>
</div>
<div class="director">Director</div>
</div>
Traditionally, I would stick with html table, but in my app I have to add some interaction in this "table" (I will be implementing collapsible window between rows with event listener, etc).
So I decided to use flexbox and emulate like a html table.
However I am having trouble for each row to align correctly column wise.
.container {
display: flex;
flex-wrap: wrap;
border: black 1px solid;
width: 100%;
}
.row {
display: flex;
height: 40px;
width: 100%;
align-items: center;
}
.cell {
padding-right: 25px;
padding-left: 20px;
align-items: center;
font-size: 20px;
border-right: 1px solid salmon
}
<div class="container">
<div class="row">
<div class="cell">Descrption</div>
<div class="cell">Amount per Month</div>
<div class="cell">Amount per year</div>
</div>
<div class="row">
<div class="cell">Income</div>
<div class="cell">$20,000</div>
<div class="cell">$45,000</div>
</div>
</div>
As you can see, the right-border of each cells does not align correctly.
Is it possible using flex-box to achieve this? Or is my implementation is wrong?
Note: I cannot use any JavaScript nor jQuery for this one.
Since you are using display flex. you can use flex-basis property
See snippet below
.container {
display: flex;
flex-wrap: wrap;
border: black 1px solid;
width: 100%;
}
.row {
display: flex;
height: 40px;
width: 100%;
align-items: center;
}
.row .cell{
flex:0 0 30%;
}
.cell {
padding-right: 25px;
padding-left: 20px;
align-items: center;
font-size: 20px;
border-right: 1px solid salmon
}
<div class="color-div">
</div><div class="container">
<div class="row">
<div class="cell">Descrption</div>
<div class="cell">Amount per Month</div>
<div class="cell">Amount per year</div>
</div>
<div class="row">
<div class="cell">Income</div>
<div class="cell">$20,000</div>
<div class="cell">$45,000</div>
</div>
</div>
It is quite simple. Just give equal width to cell. e.g.:
.container {
display: flex;
flex-wrap: wrap;
border: black 1px solid;
width: 100%;
}
.row {
display: flex;
height: 40px;
width: 100%;
align-items: center;
}
.cell {
padding-right: 25px;
padding-left: 20px;
align-items: center;
font-size: 20px;
border-right: 1px solid salmon;
width: 33%;
}
<div class="container">
<div class="row">
<div class="cell">Descrption</div>
<div class="cell">Amount per Month</div>
<div class="cell">Amount per year</div>
</div>
<div class="row">
<div class="cell">Income</div>
<div class="cell">$20,000</div>
<div class="cell">$45,000</div>
</div>
</div>
I am trying to adjust date and time to be on the same level as city name. Please, see the picture below. Blue path line doesn't start from the beginning of city name because .flight-date element moved to next line. How can I make date-time element to grow to top instead of bottom or propose any other solutions how can I achieve the similar result?
CodePen example
HTML:
<div class="container-fluid">
<div class="roundtrip">
<div class="trip col-xs-5">Outbound
<div class="flight">
<div class="date-time col-xs-offset-4 col-xs-1">
<div class="flight-time pull-right">12:40</div>
<div class="flight-date pull-right">Friday 11 Sep</div>
</div>
<div class="col-xs-offset-0 col-xs-2">
Los Angeles
</div>
</div>
<div class="flight-path"></div>
<div class="flight">Chicago</div>
<div class="connection">5hr wait</div>
<div class="flight">Chicago</div>
<div class="flight-path"></div>
<div class="flight">New York</div>
<div class="connection">2hr wait</div>
<div class="flight">New York</div>
<div class="flight-path"></div>
<div class="flight">Amsterdam</div>
</div>
<!-- just padding: --><div class="col-xs-2"></div>
<div class="trip col-xs-5">Inbound
<div class="flight">Amsterdam</div>
<div class="flight-path"></div>
<div class="flight">Los Angeles</div>
</div>
</div>
</div>
LESS:
body {padding: 2em 0 0 2em}
.roundtrip {
width: 100%;
display: inline-flex;
flex-direction: row;
align-items: stretch;
}
.trip {
//width: 100px;
text-align: center;
border: 1px solid black;
//margin: 0px 3px;
display: flex;
flex-direction: column;
}
.flight {
white-space: nowrap;
}
.date-time{
vertical-align:top
}
.flight-path {
width: 6px;
min-height: 85px;
flex-grow: 1;
align-self: center;
background-color: #6090FF;
}
.connection {
height: 40px;
align-self: center;
width: 70px;
color: red;
border: 1px solid red;
display: flex;
flex-direction: column;
justify-content: center;
}
You can use flexbox like this:
body {
padding: 2em 0 0 2em
}
.align-bottom { /*added*/
display: flex;
align-items: flex-end;
}
.roundtrip {
width: 100%;
display: inline-flex;
flex-direction: row;
align-items: stretch;
}
.trip {
//width: 100px;
text-align: center;
border: 1px solid black;
//margin: 0px 3px;
display: flex;
flex-direction: column;
}
.flight {
white-space: nowrap;
}
.date-time {
text-align: center;
}
.flight-path {
width: 6px;
min-height: 85px;
flex-grow: 1;
align-self: center;
background-color: #6090FF;
}
.connection {
height: 40px;
align-self: center;
width: 70px;
color: red;
border: 1px solid red;
display: flex;
flex-direction: column;
justify-content: center;
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid">
<div class="roundtrip">
<div class="trip col-xs-12">Outbound
<div class="flight align-bottom"> <!--added the class 'align-bottom'-->
<div class="date-time col-xs-offset-2 col-xs-3">
<div class="flight-time">12:40</div>
<div class="flight-date">Friday 11 Sep</div>
</div>
<div class="col-xs-offset-0 col-xs-2">Los Angeles</div>
</div>
<div class="flight-path"></div>
<div class="flight">Chicago</div>
<div class="connection">5hr wait</div>
<div class="flight">Chicago</div>
<div class="flight-path"></div>
<div class="flight">New York</div>
<div class="connection">2hr wait</div>
<div class="flight">New York</div>
<div class="flight-path"></div>
<div class="flight">Amsterdam</div>
</div>
</div>
</div>
Check this out for more info about flexbox