Flexbox layout - element width - html

How can I achieve with flexbox this?
.img should have 25% of width .info should have 75% of width .row
should have always 100% .half should have 50%
Here is my code http://codepen.io/anon/pen/zrBRgP
.wrap {display: flex;}
.row { width: 100%;}
.half {width: 50%;}
Why the row have not 100% of the div?

Use flex-basis instead of width.
You also need to apply flex layout to the rows.
This article is a great guide to flex.
.wrap {
display: flex;
flex-direction: column;
}
div {
border: 1px black dotted;
}
img {
width: 100%;
}
.img {
flex-basis: 25%;
}
.info {
flex-basis: 75%;
}
.half {
flex-basis: 50%;
}
.row {
display: flex;
flex-basis: 100%;
}
<div class="wrap">
<div class="row">
<div class="img">
<img src="http://41.media.tumblr.com/tumblr_lvrfnaXz651qibz0jo1_r1_500.png" />
</div>
<div class="info">
<h3>Hello How Are You</h3>
</div>
</div>
<div class="row">
<div class="half">1</div>
<div class="half">2</div>
</div>
<div class="row">
<div class="half">1</div>
<div class="half">2</div>
</div>
</div>
Update from Comment by #ZcelaAnonymní
* {
box-sizing: border-box;
}
.wrap {
display: flex;
flex-direction: column;
}
div {
border: 1px black dotted;
}
img {
width: 100%;
}
.img {
flex: 0 0 25%;
}
.info {
flex: 0 0 75%;
}
.half {
flex: 0 0 50%;
}
.row {
display: flex;
flex: 0 0 100%;
flex-wrap: wrap;
}
<div class="wrap">
<div class="row">
<div class="img">
<img src="http://41.media.tumblr.com/tumblr_lvrfnaXz651qibz0jo1_r1_500.png" />
</div>
<div class="info">
<h3>Hello How Are You</h3>
</div>
</div>
<div class="row">
<div class="half">1</div>
<div class="half">2</div>
<div class="half">1</div>
<div class="half">2</div>
</div>
</div>

Related

How can I put two <div> that has the same width and height next to each other without having to scroll?

I'm currently making a simple html page with two sections with content inside of each of them but the last content of the second div .right is going on the bottom of the page and make the page scrollable.
I tried making another div and put a flex-direction: column but it doesn't work:
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: column;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
}
.right {
background: #ffffff;
width: 50%;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
How can I put two <div> that has the same width and height next to each other without having to scroll?
You need to use flex-direction: row and not flex-direction: column.
To avoid repeating width: 50%; height: 100vh; for both .left and .right, I would also create another class, such as .box, which is applied to both and contains these properties.
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: row;
}
.box {
width: 50%;
height: 100vh;
}
.left {
background: #ecece9;
}
.right {
background: #ffffff;
}
<div class="main-container">
<div class="left box">
<h2>content</h2>
</div>
<div class="right box">
<h2>content should be on top</h2>
</div>
</div>
Change the flex direction from column to row
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: row;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
}
.right {
background: #ffffff;
width: 50%;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
Use CSS Grid to build Layouts it is very powerful. See I changed only two lines and the layout is ready.
.main-container {
display: grid;
grid-template-columns: 50% 50%
}
body {
margin: 0;
}
.main-container {
display: grid;
grid-template-columns: 50% 50%
}
.left {
background: #ecece9;
height: 100vh;
}
.right {
background: #ffffff;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
Try only display flex on large screen and and block on mobile
body {
margin: 0;
}
.main-container {
display: flex;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
padding:20px;
}
.right {
background: #ddd;
width: 50%;
height: 100vh;
padding:20px;
}
/* For mobile screen
#media only screen and (max-width: 768px) {
.main-container{
display: block;
}
.left, .right{
width: 100%;
}
}
*/
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>

Flexbox 100% height Issue

I have found the following links... but it still doesn't help me...
how to make nested flexboxes work
Height 100% on flexbox column child
How to make flexbox children 100% height of their parent?
I need a full page that is responsive, like the following image:
With header and footer and the middle 5 columns filling the height equally in the remaining space, and then when I do media queries, fill the screen of the mobile device like so:
Here's the code I have so far...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
html,
body {
height: 100%;
margin: 0
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
flex: 1 1 auto;
}
.box .row.footer {
flex: 0 1 40px;
}
.yellow-back {
background: #ffe001;
}
.red-back {
background: #e31e25;
}
.green-back {
background: #66af45;
}
.purple-back {
background: #954294;
}
.containerFull { position: relative; width: 100%; margin: 0 auto; padding: 0;}
.containerFull .column,
.containerFull .columns { float: left; display: inline; margin-left: 0px; margin-right: 0px; }
.containerFull .one-fifth.column { width: 20%; }
</style>
</head>
<body>
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<div class="containerFull">
<div class="one-fifth column green-back">Here</div>
<div class="one-fifth column red-back">Here</div>
<div class="one-fifth column">Here</div>
<div class="one-fifth column yellow-back">Here</div>
<div class="one-fifth column purple-back">Here</div>
</div><!-- ContainerFull -->
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>
</body>
</html>
html,
body {
height: 100%;
margin: 0
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
flex: 1 1 auto;
}
.box .row.footer {
flex: 0 1 40px;
}
.yellow-back {
background: #ffe001;
}
.red-back {
background: #e31e25;
}
.green-back {
background: #66af45;
}
.purple-back {
background: #954294;
}
.containerFull {
position: relative;
width: 100%;
margin: 0 auto;
padding: 0;
}
.containerFull .column,
.containerFull .columns {
float: left;
display: inline;
margin-left: 0px;
margin-right: 0px;
}
.containerFull .one-fifth.column {
width: 20%;
}
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<div class="containerFull">
<div class="one-fifth column green-back">Here</div>
<div class="one-fifth column red-back">Here</div>
<div class="one-fifth column">Here</div>
<div class="one-fifth column yellow-back">Here</div>
<div class="one-fifth column purple-back">Here</div>
</div>
<!-- ContainerFull -->
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>
In addition to Michael Coker's answer, if you go all the way with Flexbox, you can cut down both your markup and CSS quite much and get this amazing result.
I also included the background image and media query you commented/asked about just to show how simple this can be done.
Made some notes in the CSS. When it comes to the header and footer, you can give them a height if you want, but is not needed for this to work, so I left them out so one can see how Flexbox excel in distributing the content...wish I had this technique 20 years ago :)
html, body {
margin: 0;
}
.box {
display: flex;
flex-direction: column;
height: 100vh; /* instead of using 100% all over, use viewport units once */
background-size: cover;
background: black url(http://lorempixel.com/500/500/nature/4/) no-repeat center;
}
.box .row.content,
.content .one-fifth.column {
flex: 1; /* fill the space equal, no matter row or column direction */
display: flex;
}
.box .row.header,
.box .row.footer { color: white; }
.box .row.content { background: #fff; }
.yellow-back { background: #ffe001; }
.red-back { background: #e31e25; }
.green-back { background: #66af45; }
.purple-back { background: #954294; }
#media screen and (max-width: 600px) {
/* smaller screens */
.box .row.content {
flex-direction: column; /* by simply swap direction it work on smaller screen */
}
}
<div class="box">
<div class="row header">
<p><b>header</b><br /><br />(sized to content)</p>
</div>
<div class="row content">
<div class="one-fifth column green-back">Here</div>
<div class="one-fifth column red-back">Here</div>
<div class="one-fifth column">Here</div>
<div class="one-fifth column yellow-back">Here</div>
<div class="one-fifth column purple-back">Here</div>
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>
I would make the column section a flex layout, too. You can set .content and .containerFull to display: flex, then .containerFull will "stretch" to fill the height of .content, and then you can use flex-basis on the columns to control the width.
html,
body {
height: 100%;
margin: 0
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
display: flex;
}
.box .row.content {
flex: 1 1 auto;
}
.containerFull {
display: flex;
}
.box .row.footer {
flex: 0 1 40px;
}
.yellow-back {
background: #ffe001;
}
.red-back {
background: #e31e25;
}
.green-back {
background: #66af45;
}
.purple-back {
background: #954294;
}
.containerFull {
position: relative;
width: 100%;
margin: 0 auto;
padding: 0;
}
.containerFull .column,
.containerFull .columns {
margin-left: 0px;
margin-right: 0px;
}
.containerFull .one-fifth.column {
flex-basis: 20%;
}
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<div class="containerFull">
<div class="one-fifth column green-back">Here</div>
<div class="one-fifth column red-back">Here</div>
<div class="one-fifth column">Here</div>
<div class="one-fifth column yellow-back">Here</div>
<div class="one-fifth column purple-back">Here</div>
</div><!-- ContainerFull -->
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>

Flex - make parent width of children?

I have a flex box layout. I want the width of .outer-2 to be the width of its children, with .outer-1 and outer-3 taking up the rest of the space.
How can I achieve this?
JSFiddle
.container {
display: flex;
}
.outer-1 {
background: red;
height: 100px;
flex: 1;
}
.outer-2 {
display: flex;
flex: 1;
}
.outer-3 {
background: blue;
height: 100px;
flex: 1;
}
.inner {
flex-basis: 30px;
background: green;
height: 100px;
margin: 0 3px;
}
<div class="container">
<div class="outer-1">
</div>
<div class="outer-2">
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
</div>
<div class="outer-3">
</div>
</div>
You need to change the flex properties for the second child of container preventing it from growing to fit it's parent. That, and adding a width or min-width to each .inner element will prevent their parent from collapsing them down.
.container{
display: flex;
}
.outer-1{
background: red;
height: 100px;
flex: 1;
}
.outer-2{
display: flex;
flex: 1;
}
.outer-3{
background: blue;
height: 100px;
flex: 1;
}
.inner{
width: 30px;
flex: 1 0 30px;
background: green;
height: 100px;
margin: 0 3px;
}
<div class="container">
<div class="outer-1">
</div>
<div class="outer-2">
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
</div>
<div class="outer-3">
</div>
</div>

Nested flexbox height issue in IE

I have nested flexboxes with some images inside, it looks good in Chrome, but in IE you can see the borders on the flex-item-wrapper are not flush against the bottom of the image. By the way, in the layout I will sometimes have several flex-row with many pictures.
.flex-list {
display: flex;
flex-direction: column;
}
.flex-row {
display: flex;
}
.flex-item-wrapper {
width: 100%;
border: 1px solid green;
}
.flex-item {
height: 100%;
width: 100%;
border: 1px solid blue;
}
.picture {
width: 100%;
}
<div class="flex-list">
<div class="flex-row">
<div class="flex-item-wrapper">
<div class="flex-item">
<a href='#'>
<img class="picture" src="http://www.picgifs.com/clip-art/cartoons/super-mario/clip-art-super-mario-832109.jpg" alt="">
</a>
</div>
</div>
<div class="flex-item-wrapper"></div>
<div class="flex-item-wrapper"></div>
<div class="flex-item-wrapper"></div>
</div>
</div>
This seems to be working:
.flex-row {
display: flex;
flex: 0 0 auto; /*added*/
}
or
.flex-row {
display: flex;
height: 100%; /*added*/
}
See simplified demo:
.flex-list {
display: flex;
flex-direction: column;
}
.flex-row {
display: flex;
flex: 0 0 auto;
}
.flex-item {
flex: 1;
border: 1px solid blue;
}
.picture {
width: 100%;
height: auto;
}
<div class="flex-list">
<div class="flex-row">
<div class="flex-item">
<a href='#'>
<img class="picture" src="http://www.picgifs.com/clip-art/cartoons/super-mario/clip-art-super-mario-832109.jpg" alt="">
</a>
</div>
<div class="flex-item"></div>
<div class="flex-item"></div>
<div class="flex-item"></div>
</div>
</div>
The problem seems due to the nesting flexbox. This fixes it:
.flex-row {
width: 100%;
align-self: flex-start;
}
.flex-list {
display: flex;
flex-direction: column;
}
.flex-row {
display: flex;
width: 100%;
align-self: flex-start;
}
.flex-item-wrapper {
width: 100%;
border: 1px solid green;
}
.flex-item {
height: 100%;
width: 100%;
border: 1px solid blue;
}
.picture {
width: 100%;
}
<div>
<div class="flex-list">
<div class="flex-row">
<div class="flex-item-wrapper">
<div class="flex-item">
<a href='#'>
<img class="picture" src="http://www.picgifs.com/clip-art/cartoons/super-mario/clip-art-super-mario-832109.jpg" alt="">
</a>
</div>
</div>
<div class="flex-item-wrapper"></div>
<div class="flex-item-wrapper"></div>
<div class="flex-item-wrapper"></div>
</div>
</div>
<div></div>
</div>

some issue with margin in flex container

need some help. How to fix bug with .half-img2{ margin-top: 10px; }
http://prntscr.com/94uqok
These 2 imgs height must be equal to main-img
http://plnkr.co/edit/Dvj5HfG6hJqvYPxr0ljJ?p=preview
Html:
<style type="text/css">
.test{
display: flex;
}
.test>div{
flex: 1;
}
.test .main-img{
flex-grow: 2;
}
img{
width: 100%;
}
.half-img{
margin-left: 10px;
}
.half-img2{
margin-top: 10px;
}
</style>
<div class="test">
<div class="main-img">
<img src="http://fakeimg.pl/350x200/00CED1/FFF/?text=img+placeholder">
</div>
<div class="half-img">
<div class="half-img1">
<img src="http://fakeimg.pl/350x200/00CED1/FFF/?text=img+placeholder">
</div>
<div class="half-img2">
<img src="http://fakeimg.pl/350x200/00CED1/FFF/?text=img+placeholder">
</div>
</div>
</div>
I'll ignore the images sizes as these are not really relevant to the div layout issue.
A judicious use of margins and flex-column div layout seems to be required.
Layout would be something like this.
* {
box-sizing: border-box;
}
.test {
display: flex;
width: 80%;
margin: 1em auto;
border:1px solid green;
}
img {
display: block;
}
.test div {
}
.main-img {
flex:2;
margin-right: 10px;
background: lightblue;
}
.half-img {
display: flex;
flex-direction: column;
height: 250px;
}
.half-img {
flex:1;
display: flex;
flex-direction: column;
}
.half-img div {
flex:1;
background: lightblue;
}
.half-img1 {
margin-bottom: 5px;
}
.half-img2 {
margin-top: 5px;
}
<div class="test">
<div class="main-img">
</div>
<div class="half-img">
<div class="half-img1">
</div>
<div class="half-img2">
</div>
</div>
</div>