flexbox: stretching the height of elements with flex-direction: row - html

I want to stretch two div elements (.sideline and .main-contents) to reach the bottom of the page and stay at a certain height from the footer.
The two divs are nested inside a div (.row-elements) with the flex-direction: row since I wanted them to be on the same row.
/* body {
display:flex;
flex-direction:column;
} */
.one-above-all {
display: flex;
flex-direction: column;
/* flex: 1 0 auto; */
/* min-height: 1100px; */
border: solid black 1px;
}
.top-block {
margin: 0 auto;
border: solid black 1px;
width: 300px;
height: 30px;
margin-top: -15px;
}
.headline {
border: solid black 1px;
width: 90%;
align-self: flex-end;
margin-top: 40px;
margin-right: 10px;
height: 160px;
display: flex;
box-sizing: border-box;
}
.row-elements {
display: flex;
flex-direction: row;
margin-top: 40px;
align-items: stretch;
/* min-height: 900px;
flex: 1 0 auto;
*/
}
.sideline {
width: 160px;
border: solid 1px;
margin-left: calc(10% - 10px);
box-sizing: border-box;
flex-shrink: 1
}
.main-contents {
border: solid 1px;
margin-left: 40px;
/* align-self: stretch; */
flex: 1 1 auto;
margin-right: 10px;
box-sizing: border-box;
}
.bottom-block {
align-self: flex-end;
margin-top: auto;
border: black solid 1px;
margin: auto;
width: 300px;
height: 30px;
margin-bottom: -10px;
/* margin-top: 880px; */
}
/* .stretch-test {
border:solid, 1px;
display: flex;
flex-direction: column;
flex: 1 0 auto;
} */
<div class="one-above-all">
<div class="top-block"></div>
<div class="headline"></div>
<!-- <div class="stretch-test"> -->
<div class="row-elements">
<div class="sideline"></div>
<div class="main-contents">jhjkdhfjksdhafjksdahfl</div>
<!--</div> -->
</div>
</div>
<div class="bottom-block">footer</div>
Codepen
The commented out code in the css is the things I have tried.
I tried to set the body as flex and give the row-elements class flex property of 1 0 auto which didn't work.
I tried nesting the row-elements class (which has the flex-direction of row) in another div with a flex-direction of column and setting .row-elements to flex:1 0 auto which also didn't work.
I tried totally removing the the row-elements class but the two divs won't come on the same row.
Any solution will be appreciated.

To stick the footer to the bottom, here are two methods:
Method #1: justify-content: space-between
Align the container vertically with flex-direction: column. Then pin the last element to the bottom with justify-content: space-between.
revised codepen
Method #2: auto margins
Also with the container in column-direction, apply margin-top: auto to the footer, which spaces it away from the other flex items. (Seems you're already familiar with this method.)
Here's a detailed explanation for both: Methods for Aligning Flex Items
Make sure to define a height for your container, unless you simply want content height. In my example I've used height: 100vh on body.

Related

Align horizontal border line with header div

I have a header div that looks like this in css:
.page-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-content: stretch;
align-items: center;
padding: 5px 5px 5px 20px
margin-left: auto;
margin-right: auto;
width: 100%
height: 40px;
}
and a border div under it:
.horizontal-line {
border-bottom: 1px solid red;
margin: auto;
}
My problem is that I can't use padding on the border to make it align with the header or change the margin to fixed numbers, because then it doesn't center.
How would i go about fixing this so that the border adjust to the same width as the header?
Can it be done in CSS only? The reason I ask is that the JS is a template (not ideal I know) and there are other versions on the site using the same template (none of them are using the border div).
I've tried using max-width and that works really good on the large version of the site. Problem with that is that when the page is shrunk it doesn't dynamically adjust the max-width :(
Appreciate any help that I could get :)
Maybe if you can add a container you can do something like this:
You can also add horizontal-line div inside the container and make it full 100% width and get the same result.
.container {
width: 60%;
height: 300px;
background-color: white;
border-bottom: 2px solid black;
}
.page-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-content: stretch;
align-items: center;
padding: 5px 5px 5px 20px
margin-left: auto;
margin-right: auto;
width: 100%;
height: 200px;
background-color: yellow;
}
<div class="container">
<div class="page-header"></div>
</div>
or put % on max-width and then when you resize screen it will resize this is not pretty i would rather choose to use container around it.
.page-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-content: stretch;
align-items: center;
padding: 5px 5px 5px 20px
margin-left: auto;
margin-right: auto;
/* width: 100%; */
max-width: 50%;
height: 200px;
background-color: yellow;
}
.horizontal-line {
max-width: 50%;
margin-top: 50px;
border-bottom: 2px black solid;
}
<div class="page-header"></div>
<div class="horizontal-line"></div>

Flex element inside another flex element collapses on Safari

I got this code working on Chrome where the content of first flex-item needs to be aligned to the bottom and stretches if necessary:
body {
height:100vh;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
}
.flex-container {
padding: 0;
margin: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.flex-item {
background: tomato;
padding: 10px;
border: 5px solid red;
flex: 0 1 auto;
}
.flex-stretch {
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-end;
flex: 1 1 auto;
}
<div class="flex-container">
<div class="flex-item flex-stretch">1</div>
<div class="flex-item">2<br>2<br>2<br>2<br>2<br>2<br>2<br>2</div>
<div class="flex-item">3</div>
</div>
but on Safari it doesn't respect the content of the first flex-item and collapses if the viewport is smaller than the flex-container and scrolling is necessary.
Is there any work around this issue?
Thanks, this is my first question here :)
Here is the codePen: https://codepen.io/felphos/pen/GRZVKwY
Since you use flexbox you shouldn't define the height explicitly. I think that removing height: "100%" and also setting .flex-stretch{flex: 1 0 auto;} (0 flex-shrink) will get you what you want.

How to place two divs next to each other?

I am trying to make a very simple .html for the purpose of learning.
I'm trying to put two divs each next to each other, but I can not accomplish that.
So far I managed to do it, but if I add the property of the "width" it goes down, if I put a float: left; It works but the other div does not fill the rest of the page. .
Style
#video{
width: 50%;
height: 100%;
border-style: solid;
float: left;
}
#chat{
width: 50%;
height: 100%;
border-style: solid;
float: left;
}
#caja{
overflow: hidden;
}
</head>
<body>
<div id="caja">
<div id="video">
TEST
</div>
<div id="chat">
TEST
</div>
</div>
</body>
Your border overflows here.
Try setting box-sizing: border-box to both divs:
#video{
width: 50%;
height: 100%;
border-style: solid;
float: left;
box-sizing: border-box;
}
#chat{
width: 50%;
height: 100%;
border-style: solid;
float: left;
box-sizing: border-box;
}
The border is part of the equation although you haven't specified a size.
Border-box would set the border inside the box. Not sure if this is different in each browser or not.
MDN box-sizing
Use display: inline with width of 50% for inner divs.
The following css would resolve the issue.
CSS
#video{
width: 50%;
height: 100%;
border-style: solid;
display: inline;
box-sizing: border-box;
}
#chat{
width: 50%;
height: 100%;
border-style: solid;
display: inline;
box-sizing: border-box;
}
#caja{
width: 100%;
}
HTML
<div id="caja">
<div id="video">
TEST
</div>
<div id="chat">
TEST
</div>
</div>
https://jsfiddle.net/uo5qfj2t/
You could use another approach with flexbox:
#video {
width:50%;
border-style: solid;
}
#chat {
width:50%;
border-style: solid;
}
#caja {
display: flex;
flex-wrap: nowrap;
}
I would drop floats and use flexbox.
Here is a codepen I made with a bunch of goodies.
See the Pen Simple flexbox layout by Craig Curtis (#craigocurtis) on CodePen.
HTML
<div id="caja" class="flex-container fullheight fullwidth">
<div id="video" class="flex-item-6 flex-container-vh-center">
<div class="flex-item">Video</div>
</div>
<div id="chat" class="flex-item-6 flex-container-vh-center">
<div class="flex-item">Chat</div>
</div>
</div>
CSS
/* body reset - to get rid of default margins */
body {
margin: 0;
}
/* basic horizontal alignment */
.flex-container {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
}
/* based off of 12-column layout (like Bootstrap) */
.flex-item-6 {
-webkit-flex: 0 1 50%;
-ms-flex: 0 1 50%;
flex: 0 1 50%;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
/* perfect vertical and horizontal centering */
.flex-container-vh-center {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-content: stretch;
-ms-flex-line-pack: stretch;
align-content: stretch;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
/* simple flex item child maintaining original dimensions */
.flex-item {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
/* full height */
.fullheight {
/* a nice way to get the viewport height in percentage */
min-height: 100vh;
}
.fullwidth {
/* another good way to get the viewport width in percentage */
width: 100vw;
}
#caja {
/* I can relax! */
}
#video, #chat {
/* rems are better than px since px keep getting smaller. rems are units based off of hte root font size, and don't change */
border: 0.25rem solid black;
color: white;
font-size: 4rem;
font-family: sans-serif; /* a more readable font family */
}
#video {
/* just a fun gradient with ridiculous html colors */
background: linear-gradient(lime,tomato);
}
#chat {
/* a better way of controlling colors via rgba alpha scale, good for transparent-esque overlays */
background: linear-gradient(rgba(0,0,0,0.25),rgba(0,0,0,0.75));
}
Drop floats, because they pull content out of the normal flow and get real buggy and require clearfixes, use flexbox instead.
Use reusable classes instead of id's.
This code may look daunting, but there is a super easy way to create quick layouts. Play with Flexy Box - it will solve nearly all of your layout headaches!
http://the-echoplex.net/flexyboxes/
*{
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
Add this property also due to border on div total width of div will be 50% + width of border and this property include border in width.

First flex item in a row disappearing outside left viewport edge without access via scroll [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 6 years ago.
I have a flex container with three flex items in a row.
I'm trying to understand why when the screen isn't wide enough to accommodate all content, the 1st flex box gets truncated.
My expectation is that the horizontal scroll bar on .boxes_container allows all the content in #boxa to be visible provided we scroll.
Some quick notes:
Fixed widths are intentional.
In .boxes_container, justify-content:center is intentional. In the actual implementation the boxes are dynamic and I want the boxes to be centered if for example only one is visible.
.boxes_container {
display: flex;
flex-direction: row;
justify-content: center;
height: 77vh;
/* We need to set an explicit height here that translates into a real value
or scroll bars will not work because heights need a concrete value
*/
overflow-x: auto;
}
#boxa {
background-color: #994400;
display: flex;
flex-direction: column;
flex: 0 0 620px;
height: 100%;
/*
.boxa_content{
flex: 1 1 auto;
overflow-y: auto;
}
*/
}
#boxb {
background-color: #449900;
display: flex;
flex-direction: column;
flex: 0 0 620px;
height: 100%;
padding: 5px;
border: 2px solid #DDD;
border-radius: 8px;
}
#boxb .preview_content {
flex: 1 1 auto;
overflow-y: auto;
}
#boxc {
display: flex;
flex: 0 0 500px;
height: 100%;
flex-direction: column;
overflow-y: auto;
padding: 5px;
}
<div class="boxes_container">
<div id="boxa">
<h1>Stuff kajsdlkaj laksdjlka jslkdja sldjals jdlaksjd lkajs dlkajs dlkjas lkdjal ksdjalks jdlaj </h1>
</div>
<div id="boxb">
<h1>Stuff2 a;sldka;lskd a;lksd ;laks;dl kas;ldk a;lskd; laksd;la ksd;lak s;dlka s;ldlk a;lslkd ;alskd ;lask d;</h1>
</div>
<div id="boxc">
<h2>slkjdflksjd lfsjdklfs jdlkfjs ldkfjs ldkfj sl</h2>
</div>
</div>
codepen demo
The left box gets truncated because you are centering the content. When there isn't enough space, the content overflows the same amount on the left and right sides.
You can solve it by using margin: auto on the first and last elements as a way to center the content only when there is space left
.boxes_container {
display: flex;
flex-direction: row;
height: 77vh;
overflow-x: auto;
}
.boxes_container div:first-child {
margin-left: auto;
}
.boxes_container div:last-child {
margin-right: auto;
}
#boxa {
background-color: #994400;
display: flex;
flex-direction: column;
//width: 620px;
flex: 0 0 620px;
height: 100%;
}
#boxb {
background-color: #449900;
display: flex;
flex-direction: column;
//width: 620px;
flex: 0 0 620px;
height: 100%; // this is so important for the scrollbar behavior we want
//align-self:flex-start;
padding: 5px;
border: 2px solid #DDD;
border-radius: 8px;
.preview_content {
flex: 1 1 auto;
overflow-y: auto;
}
}
#boxc {
display: flex;
//width: 500px;
flex: 0 0 500px;
height: 100%;
flex-direction: column;
overflow-y: auto;
padding: 5px;
}
<div class="boxes_container">
<div id="boxa">
<h1>Stuff kajsdlkaj laksdjlka jslkdja sldjals jdlaksjd lkajs dlkajs dlkjas lkdjal ksdjalks jdlaj </h1>
</div>
<div id="boxb">
<h1>Stuff2 a;sldka;lskd a;lksd ;laks;dl kas;ldk a;lskd; laksd;la ksd;lak s;dlka s;ldlk a;lslkd ;alskd ;lask d;</h1>
</div>
<div id="boxc">
<h2>slkjdflksjd lfsjdklfs jdlkfjs ldkfjs ldkfj sl</h2>
</div>
</div>

Flex container with two columns; second column has four rows

I am having difficulty displaying the following layout in flex. I have 5 boxes and I want to divide my container in two, displaying one box vertically and the other 4 vertically.
Here's my CSS:
.trades, .trade-panel {
flex: 1;
}
.layout-4-5 {
flex-direction: column;
}
.layout-4-5 > div {
width: 50%;
}
Then I set the basis of the fourth or last child to 100%.
.layout-4-5 > div:nth-child(1) {
flex-basis: 100%;
}
And here's my HTML
<div class="trades layout-4-5">
<!--trade-panel are my individual boxes --->
<div class="trade-panel">
</div>
</div>
Above print my layout horizontally. Considering My flex-direction is column and my first child or box has a 100% basis, shouldn't that print what I want? Please any help would be appreciated.
Note: Since the boxes are of equal size, the column containing the four other boxes should be longer, provided they are in the arrangement above, its ok. tq
I'm not entirely clear on your question or code. But here's a general solution:
flex-container-1 {
display: flex; /* establish flex container */
flex-direction: row; /* flex items will align horizontally */
justify-content: center; /* center flex items horizontally */
align-items: center; /* center flex items vertically */
/* for demo purposes only */
height: 250px;
width: 400px;
border: 1px solid #777;
background-color: lightgreen;
}
flex-container-1 > flex-item {
height: 90%;
flex: 0 0 45%; /* <flex-grow> <flex-shrink> <flex-basis> */
margin-right: 8px; /* a bit of space between the centered items */
border: 1px dashed #333;
background-color: yellow;
}
flex-container-2 {
height: 90%;
flex: 0 0 45%;
display: flex; /* flex item is now also flex container */
flex-direction: column; /* items will stack vertically */
justify-content: space-between; /* align items vertically */
}
flex-container-2 > flex-item {
flex: 0 0 22%;
border: 1px dashed #333;
background-color: yellow;
}
<flex-container-1><!-- main container -->
<flex-item></flex-item><!-- flex item #1 (first column) -->
<flex-container-2><!-- flex item #2 / nested flex container (second column) -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container-2><!-- close nested container -->
</flex-container-1><!-- close main container -->
jsFiddle
I struggled and struggled on this one and then serendipitously discovered a new solution to this problem right as I had decided to give up and use floats. I was finally able to get this to work without using separate DIVs for columns.
UPDATE: I have simplified my previous version of this by having the height specified on .items.
Provide non-percentage width and height to .items.
Use flex-direction: column on .items.
CSS:
.items {
display: flex;
flex-direction: column;
flex-wrap: wrap;
width: 40em;
height: 20em;
}
.item:first-child {
width: 20em;
height: 20em;
background-color: black;
}
.item:nth-child(2) {
width: 20em;
height: 5em;
background-color: pink;
}
.item:nth-child(3) {
width: 20em;
height: 5em;
background-color: blue;
}
.item:nth-child(4) {
width: 20em;
height: 5em;
background-color: yellow;
}
.item:last-child {
width: 20em;
height: 5em;
background-color: red;
}
HTML:
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div><!-- .items -->
Codepen:
https://codepen.io/anon/pen/ZXoqJJ
I have give margin and background color property so you can better understand.
<div id="wrapper">
<div id="left">
<div class="flex-harshad">
<div class = "flex-harshad2">
Harshad
</div></div>
</div>
<div id="right">
<div class="flex-harshad">
<div class="flex-item">world</div>
<div class="flex-item">by</div>
<div class="flex-item">Alan</div>
<div class="flex-item">Dong</div>
</div>
</div>
</div>
Here is css.
body,
div {
margin: 0;
border: 0 none;
padding: 0;
}
html,
body,
#wrapper,
#left,
#right {
height: 100%;
min-height: 100%;
}
#wrapper {
margin: 0 auto;
overflow: hidden;
}
#left {
float: left;
}
div.flex-harshad2{
margin : 5px;
margin-top : 25px;
min-height: 91%;
background : white ;
width : 90px;
}
div.flex-harshad{
background: red;
height : 100%;
width : 100px;
text-align: center;
display : inline-block;
background :orange ;
margin :10px;
}
div.flex-item {
background: white;
margin: 5px;
margin-top : 25%;
min-height : 20%;;
/* remove text-lign will not center text itself */
text-align: center;
}
Here is output :
flex-container-1 {
display: flex; /* establish flex container */
flex-direction: row; /* flex items will align horizontally */
justify-content: center; /* center flex items horizontally */
align-items: center; /* center flex items vertically */
/* for demo purposes only */
height: 250px;
width: 400px;
border: 1px solid #777;
background-color: lightgreen;
}
flex-container-1 > flex-item {
height: 90%;
flex: 0 0 45%; /* <flex-grow> <flex-shrink> <flex-basis> */
margin-right: 8px; /* a bit of space between the centered items */
border: 1px dashed #333;
background-color: yellow;
}
flex-container-2 {
height: 90%;
flex: 0 0 45%;
display: flex; /* flex item is now also flex container */
flex-direction: column; /* items will stack vertically */
justify-content: space-between; /* align items vertically */
}
flex-container-2 > flex-item {
flex: 0 0 22%;
border: 1px dashed #333;
background-color: yellow;
}
<flex-container-1><!-- main container -->
<flex-item></flex-item><!-- flex item #1 (first column) -->
<flex-container-2><!-- flex item #2 / nested flex container (second column) -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container-2><!-- close nested container -->
</flex-container-1><!-- close main container -->