Now I learned how to vertical centering an item with flexbox, but how can I align the item to the 1/3 position vertically? thanks
Assuming you mean the space below the flex item to be 3 times the space above, you can add pseudo-elements with flex-grow 1 and 3:
#container {
display: flex;
flex-direction: column;
height: 200px;
background: #aaf;
}
#container > div {
height: 50px;
background: #afa;
}
#container::before {
content: '';
flex: 1;
}
#container::after {
content: '';
flex: 3;
}
<div id="container">
<div>Content</div>
</div>
You can use transform: translate
#container {
display: flex;
flex-direction: column;
height: 180px;
background: gray;
}
#container > div {
position: relative;
top: 33%;
transform: translateY(-33%);
background: lightgray;
}
<div id="container">
<div>Content</div>
</div>
Related
Here, I have a red container, yellow container, and a navbar component.
When the navbar component(blue) is present, I want to reduce the width of both the red and yellow container so that it doesn't overlap.
I tried using fr so that red and blue container takes only the available space but it doesn't seem to work.
.flexrow {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.pagetoplayout {
display: grid;
flex-grow: 1;
grid-template-columns: 70fr 30fr;
grid-template-rows: auto auto;
overflow: auto;
grid-template-areas:
'tophalf tophalf'
'bottomside bottomside';
}
.tophalf{
grid-area: tophalf;
background: red;
}
.bookingside {
grid-area: bottomside;
background: yellow;
}
.navbar--visible {
width: 500px;
position: absolute;
top: 0;
right: 0;
display: block;
background-color: var(--color-black);
overflow: auto;
padding: 30px 20px;
opacity: 1;
background: blue;
opacity:0.8;
}
<div class="flexrow">
<div class="pagetoplayout">
<div class="tophalf">Container 1</div>
<div class="bookingside">Container 2 </div>
</div>
<div class="navbar--visible">
asa
</div>
<div>
Your navbar(blue) has position: absolute; applied which removes it from layout calculations. That's the reason it is shown over top of the other elements and doesn't affect the layout.
Sorry, another flexbox related question :)
I have two flex elements :
A container (red) containing a centered div (yellow)
A footer (blue) with an undefined height
The red container has a flex-grow:1 attribute, forcing it to take the remaining space on the screen
The issue happens when the yellow element is bigger than the screen size. I would like my red container to grow based on its content. Any idea of how I could do that ?
HTML:
<div class="container">
<div class="content"></div>
</div>
<div class="footer"></div>
CSS:
body,
html {
margin: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.container {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
background: red;
}
.content {
background: yellow;
height: 2000px;
width: 100px;
}
.footer {
flex-shrink: 0;
height: 50px;
background-color: blue;
}
https://codepen.io/stepinsight/pen/roRVGQ
== EDIT ==
Andre helped me find the answer, thanks heaps !
The only thing you need to change in the code above is to replace height by min-height and the % by vh for the body/html tags 🎉
body,
html {
margin: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
}
Simply remove the height property on the body element and add height: 100% to html
* { box-sizing: border-box; }
html {
height: 100%
}
body {
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
}
.container {
display: flex;
align-items: center;
justify-content: center;
background: red;
}
.content {
background: yellow;
height: 2000px;
width: 100px;
}
.footer {
height: 50px;
background-color: blue;
}
Corrected: https://codepen.io/ferreirandre/pen/maoVvb
Feel free to play around with the height of .content
I'm trying to make a child div of a flexbox layout fill its parent. In any other context setting the width/height to 100% causes a div to fill its parent... I only wish to use flexbox for my top level layout.
Problems
#map-container div will not fill #col1 even though it has height 100% set.
#controls div appears outside #col1 completely. I've previously used absolute layout to align boxes to corners without problems. Being inside a flexbox grand-parent seems to cause issues.
What I'm expecting is #map-container and #map to fill #col1 and #controls to align to bottom right-hand corner of #map.
.wrapper, html, body {
height:100%;
margin:0;
}
#col1 {
display: flex;
}
#map-container {
background-color: yellow;
width: 100%;
height: 100%;
}
#map {
background-color: purple;
width: 100%;
height: 100%;
}
#controls {
background-color: orange;
position: absolute;
right: 3px;
bottom: 3px;
width: 100px;
height: 20px;
}
.wrapper {
display: flex;
flex-direction: column;
}
#row1 {
background-color: red;
}
#row2 {
flex:2;
display: flex;
}
#col1 {
background-color: green;
flex: 1 1;
}
#col2 {
background-color: blue;
flex :0 0 240px;
}
<div class="wrapper">
<div id="row1">Header</div>
<div id="row2">
<div id="col1">
<div id="map-container">
<div id="map">
Map
</div>
<div id="controls">Controls</div>
</div>
</div>
<div id="col2">Sidebar</div>
</div>
</div>
#map-container div will not fill #col1 even though it has height 100% set.
It won't work that way, because for a percentage unit to work, it needs to have height set on its parent all the way up. This fights against the flex model, where the flex-items are distributed and arranged by the flex-box layout and have no dimensions set. Why use a flex layout when all your elements are 100%? Either do a 100% on all your element all the way up, or do a flex on all containers.
If you stick to flex layout, then you will have to get into nested flex. Otherwise, you will get #map-container to fill-up, but not the #map.
This fiddle http://jsfiddle.net/abhitalks/sztcb0me illustrates that problem.
#controls div appears outside #col1 completely. I've previously used absolute layout to align boxes to corners without problems. Being
inside a flex-box grand-parent seems to cause issues.
The only issue is that you are positioning it absolutely, but in relation to what? You need to position your #map-container relatively for that to work.
Here is how:
Fiddle: http://jsfiddle.net/abhitalks/sztcb0me/1/
Snippet:
* { box-sizing: border-box; padding: 0; margin: 0; }
html, body, .wrapper { height:100%; width: 100%; }
.wrapper { display: flex; flex-direction: column; }
#row1 { flex: 0 1 auto; background-color: red; }
#row2 { flex: 2 0 auto; display: flex; }
#col1 { flex: 1 0 auto; display: flex; background-color: green; }
#col2 { flex: 0 0 240px; background-color: blue; }
#map-container {
flex: 1 0 auto; display: flex;
position: relative; background-color: yellow;
}
#map { flex: 1 0 auto; background-color: purple; }
#controls {
background-color: orange;
position: absolute;
right: 3px; bottom: 3px;
width: 100px; height: 20px;
}
<div class="wrapper">
<div id="row1">Header</div>
<div id="row2">
<div id="col1">
<div id="map-container">
<div id="map">
Map
</div>
<div id="controls">Controls</div>
</div>
</div>
<div id="col2">Sidebar</div>
</div>
</div>
the problem is that it's wrapped in #map-container
.wrapper, html, body {
height:100%;
margin:0;
}
#col1 {
display: flex;
}
#map-container {
background-color: yellow;
width: 100%;
height: 100%;
}
#map {
background-color: purple;
width: 100%;
/* height: 100%; */
display: flex;
flex-wrap: wrap-reverse;
justify-content: space-between;
}
#controls {
background-color: orange;
position: relative;
/*right: 3px;
bottom: 3px;*/
width: 100px;
height: 20px;
}
.wrapper {
display: flex;
flex-direction: column;
}
#row1 {
background-color: red;
}
#row2 {
flex:2;
display: flex;
}
#col1 {
background-color: green;
flex: 1 1;
}
#col2 {
background-color: blue;
flex :0 0 240px;
}
<div class="wrapper">
<div id="row1">Header</div>
<div id="row2">
<div id="col1">
<!-- <div id="map-container"> -->
<div id="map">
Map
<div id="controls">Controls</div> <!-- add it here -->
</div>
<!-- <div id="controls">Controls</div> -->
<!--</div> -->
</div>
<div id="col2">Sidebar</div>
</div>
</div>
adding an absolute position controls in that way is not optimal (in the snippet I commented it out) ; you can place the controlsnested in #map (and use flex properties for correcting placement)
This question already has answers here:
HTML5 flexible box model height calculation
(2 answers)
Closed 4 years ago.
I have a container flex with content flexes. How do i make content flex occupy full width and height of container flex.
<div id="main">
<div id="main-nav">
</div>
<div class="container">
<div class="content"></div>
<div class="content"></div>
</div>
</div>
#main{
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
#main-nav{
width: 100%
height: 50px;
}
.container{
display: flex;
flex-direction: row;
flex-wrap: wrap;
flex: 1;
}
.content{
display: flex;
width: 100%;
height: 100%;
}
The above code makes content to occupy 100% width of container but height is based on the text within the content. I tried the solutions mentioned from similar questions but had no luck and it was still the same.
Basically, I want each of the content to occupy the same height as occupied by the container in the viewport height. I also tried jQuery,
var rht = $("#container").height();
$(".content").height(rht);
It changes the height properly but adds a horizontal scroll bar with increase in width.
After several updates to the original question:
* {
box-sizing: borderbox;
margin: 0;
padding: 0;
}
#main {
display: flex;
flex-direction: column;
border: 1px solid red;
min-height: 100vh;
}
#main-nav {
flex: 0 0 50px;
}
.container {
display: flex;
flex-direction: column;
flex: 1;
border: 1px solid green;
}
.content {
flex: 1;
border: 1px solid orange;
}
<div id="main">
<div id="main-nav"></div>
<div class="container">
<div class="content"></div>
<div class="content"></div>
</div>
</div>
JSfiddle Demo
You cannot set width or height of flex's child is bigger (size of flex)/(number of flex's childs) but you can add position: absolute into .content and position: relative into .container then set width and height for .content. First .content is under second .content, you can use propety z-index or display: none to control.
* {
box-sizing: borderbox;
margin: 0;
padding: 0;
}
#main {
display: flex;
flex-direction: column;
background: red;
min-height: 100vh;
}
#main-nav {
flex: 0 0 50px;
}
.container {
position: relative;
display: flex;
flex: 1;
background: green;
}
.content {
position: absolute;
left: 0px;
top: 0px;
height: 100%;
width: 100%;
flex: 1;
background: orange;
}
<div id="main">
<div id="main-nav"></div>
<div class="container">
<div class="content">left</div>
<div class="content">right</div>
</div>
</div>
Hello fellow programmers!
I've got a simple box-layout which I would love to achieve using flexbox, but I simply can't figure it out. It should look like this image.
So basically a row and two columns, with the row being fixed at lets say 100px in height, but all in one container. My code so far is:
#productShowcaseContainer {
display: inline-flex;
flex-flow: row wrap;
height: 600px;
width: 580px;
background-color: rgb(240, 240, 240);
}
#productShowcaseTitle {
display: inline-block;
height: 100px;
width: 100%;
background-color: rgb(200, 200, 200);
}
#productShowcaseDetail {
flex: 3;
background-color: red;
}
#productShowcaseThumbnailContainer {
flex: 2;
background-color: blue;
}
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div id="productShowcaseDetail"></div>
<div id="productShowcaseThumbnailContainer"></div>
</div>
I know this can be achieved in many ways, but I would really prefer to use CSS Flex.
You've almost done it. However setting flex: 0 0 <basis> declaration to the columns would prevent them from growing/shrinking; And the <basis> parameter would define the width of columns.
In addition, you could use CSS3 calc() expression to specify the height of columns with the respect to the height of the header.
#productShowcaseTitle {
flex: 0 0 100%; /* Let it fill the entire space horizontally */
height: 100px;
}
#productShowcaseDetail,
#productShowcaseThumbnailContainer {
height: calc(100% - 100px); /* excluding the height of the header */
}
#productShowcaseContainer {
display: flex;
flex-flow: row wrap;
height: 600px;
width: 580px;
}
#productShowcaseTitle {
flex: 0 0 100%; /* Let it fill the entire space horizontally */
height: 100px;
background-color: silver;
}
#productShowcaseDetail {
flex: 0 0 66%; /* ~ 2 * 33.33% */
height: calc(100% - 100px); /* excluding the height of the header */
background-color: lightgray;
}
#productShowcaseThumbnailContainer {
flex: 0 0 34%; /* ~ 33.33% */
height: calc(100% - 100px); /* excluding the height of the header */
background-color: black;
}
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div id="productShowcaseDetail"></div>
<div id="productShowcaseThumbnailContainer"></div>
</div>
(Vendor prefixes omitted due to brevity)
Alternatively, if you could change your markup e.g. wrapping the columns by an additional <div> element, it would be achieved without using calc() as follows:
<div class="contentContainer"> <!-- Added wrapper -->
<div id="productShowcaseDetail"></div>
<div id="productShowcaseThumbnailContainer"></div>
</div>
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 600px; width: 580px;
}
.contentContainer { display: flex; flex: 1; }
#productShowcaseDetail { flex: 3; }
#productShowcaseThumbnailContainer { flex: 2; }
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 600px;
width: 580px;
}
.contentContainer {
display: flex;
flex: 1;
}
#productShowcaseTitle {
height: 100px;
background-color: silver;
}
#productShowcaseDetail {
flex: 3;
background-color: lightgray;
}
#productShowcaseThumbnailContainer {
flex: 2;
background-color: black;
}
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div class="contentContainer"> <!-- Added wrapper -->
<div id="productShowcaseDetail"></div>
<div id="productShowcaseThumbnailContainer"></div>
</div>
</div>
(Vendor prefixes omitted due to brevity)
Just use another container to wrap last two divs.
Don't forget to use CSS prefixes.
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 600px;
width: 580px;
background-color: rgb(240, 240, 240);
}
#productShowcaseTitle {
height: 100px;
background-color: rgb(200, 200, 200);
}
#anotherContainer{
display: flex;
height: 100%;
}
#productShowcaseDetail {
background-color: red;
flex: 4;
}
#productShowcaseThumbnailContainer {
background-color: blue;
flex: 1;
}
<div id="productShowcaseContainer">
<div id="productShowcaseTitle">1</div>
<div id="anotherContainer">
<div id="productShowcaseDetail">2</div>
<div id="productShowcaseThumbnailContainer">3</div>
</div>
</div>
This is copied from above, but condensed slightly and re-written in semantic terms. Note: #Container has display: flex; and flex-direction: column;, while the columns have flex: 3; and flex: 2; (where "One value, unitless number" determines the flex-grow property) per MDN flex docs.
#Container {
display: flex;
flex-direction: column;
height: 600px;
width: 580px;
}
.Content {
display: flex;
flex: 1;
}
#Detail {
flex: 3;
background-color: lime;
}
#ThumbnailContainer {
flex: 2;
background-color: black;
}
<div id="Container">
<div class="Content">
<div id="Detail"></div>
<div id="ThumbnailContainer"></div>
</div>
</div>