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>
Related
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
I am trying to create inner borders with gaps. I tried to create borders by using :after pseudo elements, but :after elements are not visible.
.view {
display: flex;
flex-direction: column;
border: none;
overflow: hidden;
}
.container {
display: flex;
flex-wrap: wrap;
margin: 0 -5px -5px 0;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
background: yellow;
padding: 20px;
border-right: 1px solid black;
border-bottom: 1px solid black;
}
.content:after{
content: '';
background: black;
position: absolute;
bottom: 5px;
width: 2px;
height: 20px;
right: -10px;
}
.head {
text-align: center;
}
<div class="view">
<div class="container">
<div class="content">
<div class="val">0</div>
<div class="head">Total balance</div>
</div>
<div class="content">
<div class="val">0</div>
<div class="head">Available balance</div>
</div>
<div class="content">
<div class="val">0</div>
<div class="head">Orders</div>
</div>
<div class="content">
<div class="val">500</div>
<div class="head">Wallet balance</div>
</div>
<div class="content">
<button class="val" type="button">Send</button>
</div>
</div>
</div>
I am trying to achieve this result:
There are possibly better ways of doing this. But this is done without changing your HTML layout.
.view {
display: flex;
flex-direction: column;
border: none;
overflow: hidden;
}
.container {
display: flex;
flex-wrap: wrap;
margin: 0 -5px 0 0;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
background: yellow;
padding: 20px;
border-right: 1px solid black;
border-bottom: 1px solid black;
position: relative;
}
.content:before {
content: "";
position: absolute;
bottom: 0;
left: -5px;
right: -5px;
background: yellow;
z-index: 1111;
border: 4px solid yellow;
}
.content:after {
content: "";
position: absolute;
top: 0;
left: -5px;
right: -5px;
background: yellow;
z-index: 1111;
border: 4px solid yellow;
}
.head {
text-align: center;
}
<div class="view">
<div class="container">
<div class="content">
<div class="val">0</div>
<div class="head">Total balance</div>
</div>
<div class="content">
<div class="val">0</div>
<div class="head">Available balance</div>
</div>
<div class="content">
<div class="val">0</div>
<div class="head">Orders</div>
</div>
<div class="content">
<div class="val">500</div>
<div class="head">Wallet balance</div>
</div>
<div class="content">
<button class="val" type="button">Send</button>
</div>
</div>
</div>
I hope this helps
<!DOCTYPE html>
<html>
<head>
<style>
.center {
display: flex;
justify-content: center;
align-items: center;
}
.view {
background-color: yellow;
}
.topContainer {
display: grid;
grid-template-columns: repeat(3, 3fr);
border-bottom: 1px solid #000;
}
.bottomContainer {
display: grid;
grid-template-columns: repeat(2, 3fr);
}
.content {
padding: 25px;
text-align: center;
border-left: 1px solid #000;
}
.topContainer .content:first-child {
border: none;
}
.bottomContainer .content:first-child {
border: none;
}
</style>
</head>
<body>
<div class="view">
<div class="topContainer">
<div class="content center">
<div>
<div class="val">0</div>
<div class="head">Total balance</div>
</div>
</div>
<div class="content center">
<div>
<div class="val">0</div>
<div class="head">Available balance</div>
</div>
</div>
<div class="content center">
<div>
<div class="val">0</div>
<div class="head">Orders</div>
</div>
</div>
</div>
<div class="bottomContainer">
<div class="content center">
<div>
<div class="val">500</div>
<div class="head">Wallet balance</div>
</div>
</div>
<div class="content center">
<button class="val" type="button">Send</button>
</div>
</div>
</div>
</body>
</html>
Result
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