I am using ZURB foundation 6 with XY grid and have run into a little problem and most likely something I'm doing wrong.
I want to center elements vertically so I use
<div class="flex-container">
<div class="grid-x grid-padding-x align-middle">
<div class="small-6 cell">Vertically Centered Left Column</div>
<div class="small-6 cell">Vertically Centered Left Column</div>
</div>
</div>
And using jQuery I set the height of flex-container by using windowHeight = $(window).innerHeight();
Voila the items are vertically aligned... However two issues arise from this:
small-6 cell has a width of 50% that is not being respected and shrinks down to the approx length of the text.
flex-container unlike grid-container does not have a width or padding.
To resolve the issue I added some CSS like so:
.flex-container .align-middle {
max-width: 62.5rem;
margin: 0 auto;
width: 100%;
}
So while I've patched the issue I can't help thinking that there must be an easier way, a proper way using just classes. It seems odd that grid-container is setup to do so but flex-container is not.
The main problem here is that with flex-container, the grid-x element will, along being a flex container of its own, also become a flex row item, having the default flex item value 0 1 auto.
This means the grid-x won't grow wider than its content, hence width: 50% won't work on its children (small-6), as their parent doesn't have a width set.
By adding e.g. flex-child-grow or cell to the grid-x element, it will fill its parent's width, and the inner flex items will start behave as expected.
Note 1: With grid-container this is not needed since it is not a flex container, where the grid-x is a normal div, displayed as flex, which, like a block element, by default take full width of its parent.
Note 2: Both flex-container and grid-container does have a default width of 100%, it is the grid-x, when being a flex item, that cause the issue not taking its parent's width by default.
Stack snippet
/* for demo purpose */
body { margin: 0; }
.flex-container { height: 100vh; }
.grid-x { border: 1px solid red; }
.small-6 { border: 1px solid blue; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.css" rel="stylesheet"/>
<div class="flex-container">
<div class="flex-child-grow grid-x grid-padding-x align-middle">
<div class="small-6 cell">Vertically Centered Left Column</div>
<div class="small-6 cell">Vertically Centered Left Column</div>
</div>
</div>
Related
I'm reproducing a golden spiral using CSS flexbox and percentage size for cells.
The round shape is drawn using a regular border and border-radius combination.
Everything is proportional until I resize the window to smaller widths.
I tried removing borders completely and turns out the layout is still losing proportions at some point.
Big container:
Small container:
Demo:
https://jsfiddle.net/s09rkwub/1/
html
<div class="wrapper">
<div class="rows fib">
<div class="cols fill">
<div class="rows fill">
<div class="fr tl">3</div>
<div class="fill cols">
<div class="fc bl">4</div>
<div class="fill rows">
<div class="fill cols">
<div class="fill tl fr">7</div>
<div class="fc tr">6</div>
</div>
<div class="fr br">5</div>
</div>
</div>
</div>
<div class="fc tr">2</div>
</div>
<div class="fr br">1</div>
</div>
</div>
css
.rows {
flex-direction: column;
}
.cols {
flex-direction: row;
}
.rows,
.cols {
display: flex;
.fill {
flex: 1;
}
> * {
outline: solid 1px rgba(127,127,127, 0.3);
}
}
...
Update:
Working demo with applied solution.
Update 2
Thanks to Your support guys. I could finish my fib spiral codepen.
Solution
Add this to your code:
* {
flex-shrink: 0;
min-width: 0;
min-height: 0;
}
revised fiddle
Explanation
Two concepts to consider:
An initial setting of a flex container is flex-shrink: 1.
This means that, by default, flex items are allowed to shrink below any defined width, height or flex-basis.
To prevent this behavior use flex-shrink: 0.
More details here: What are the differences between flex-basis and width?
An initial setting of a flex item is min-width: auto.
This means that, by default, a flex item cannot be smaller than the size of its content (regardless of flex-shrink or flex-basis).
To allow flex items to shrink past their content use min-width: 0 (row direction), min-height: 0 (column direction), or overflow: hidden (other values also work, except visible).
More details here: Why doesn't flex item shrink past content size?
With the adjustment below, your flex items can shrink past the text you have in your divs, allowing the scaling to continue without any obstacles:
* {
flex-shrink: 0;
min-width: 0;
min-height: 0;
}
Taking <div class="fr br">5</div> as an example, it's min-width is 26px. Thus, scaling the spiral down to a level, where the mentioned div's height becomes less than 26px, it's getting distorted.
If you change the border width to 1px instead of 5px, you'll see, that suddenly, it's able to scale down to 18px perfectly fine and breaks in smaller sizes.
That's why you probably tried to reduce the border. However, the reason for the distortion is much simpler: You have content inside the divs and they do require some space (even if the font color is transparent). If you remove all the numbers from the div elements, you get the desired result. See the demo at https://jsfiddle.net/s09rkwub/2/
I have the following HTML and CSS layout:
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 100px;
}
.col-md-6 {
display: flex;
justify-content: center;
}
.container_flex {
display: flex;
align-items: center;
justify-content: center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
<div class="container-fluid">
<div class="container_flex">
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
Which provides the following result:
Bootply
My aim of using Flexbox is to vertically center the contents of "row" inside the container-fluid. However, this results in the columns adopting a compressed look when in desktop mode. When in mobile view, the columns do stack as expected. I would be grateful if someone could explain why this compressed/stubby look comes about?
In contrast, if I remove the row class, this stubby compressed look no longer is brought about as shown:
Bootply
However, the columns no longer stack when in mobile view. Is there any way that I can rectify this?
If anyone has any tips/pointers on how to effectively use FlexBox with Bootstrap to vertically and horizontally center in a more effective way than what I have attempted here, I would be very grateful.
When you remove the row element the .col elements become your flex-items. In order to get flex-items to wrap in a flex container you need to use the flex-wrap property. However, I don't think removing the row element and using flex-wrap is what you really want.
With regards to your question. The reason it looks stubby in your first example is because you are making the row element your 'flex-item'. The width of the row item then sizes to its contents because you have not set the flex property which controls its size. Once you set the flex property properly then you will see the desired results:
.container_flex {
display: flex;
align-items: center;
justify-content:center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
.row {
flex: 1;
}
<div class="container-fluid">
<div class="container_flex">
<!-- Note that if using Flexbox, then do not need to wrap col- in row class but then does not stack columns on mobile... use #media? -->
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
Here is a brief explanation why: flex:1 is a shortcut property that sets three separate flex-item properties to:
flex-grow: 1; If the size of the flex-item is smaller than available space within the flex container then setting this to a value greater than 0 makes the item stretch to fill the available space. If there are multiple flex-items in the same container they grow to share the available space in proportion to the value of their flex-grow property.
flex-shrink: 1; If the size of the flex-item is larger than the available space within the flex container then setting this to a value greater than 0 makes the item shrink to fit the available space. If there are multiple flex-items in the same container they will shrink to share the available space in proportion to the value of their flex-shrink property.
flex-basis: 0%; Defines the starting size of the element before being "flexed".
For general informanton on using flex-box take a look at this article over at css tricks by Chris Coyier; he does a great job explaining how flex-box works.
If you are looking for information on using bootstrap and flex-box together I recommend reading this article as well!
I hope this helps.
you need to give flex:1 to .row which it shorthand for flex-grow, flex-shrink and flex-basis combined. Default is 0 1 auto, using flex:1 means it will be 1 1 0
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 100px;
}
.row {
flex: 1
}
.col-md-6 {
display: flex;
justify-content: center;
}
.container_flex {
display: flex;
align-items: center;
justify-content: center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid">
<div class="container_flex">
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
You may also use the flex built-in library from bootsrap (it will also be responsive):
http://v4-alpha.getbootstrap.com/layout/flexbox-grid/#responsive-flexbox
.col-md-6.col-xs-12{border:solid}/* CSS neede cause border are not set by default in bootsrap :) */
<link href="http://v4-alpha.getbootstrap.com/assets/css/docs-flexbox.min.css" rel="stylesheet"/>
<link href="http://v4-alpha.getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<p>To see cols side by side, run snippet in full page mode and reduce it down to average 720px width to see col stacking </p>
<div class="row">
<div class="col-md-6 col-xs-12" >
col 1
</div>
<div class="col-md-6 col-xs-12" >
col 2
</div>
</div>
</div>
Is it possible to have 3 items in a flex container but have them displayed like this:
1 3
2 3
Basically, where items 1 & 2 are on the left and about whatever height they each need to be, then item 3 is right-aligned but stretches the full height of the flex container?
Here's a codepen to illustrate: http://codepen.io/anon/pen/RrORbj
Here is a jsFiddle using flexbox.
<div class="container">
<div class="col">
<div class="box one">
one
</div>
<div class="box two">
two
</div>
</div>
<div class="col">
<div class="box three">
three
</div>
</div>
</div>
First, you set the container to a flexbox. Note, that the default value of flex-direction is row (horizontal). Setting the child element (col) with flex: 1 makes the columns flexible in the direction of the parents flex direction.
Note also, that the default value of align-items on the container is stretch. What this does is set the height of all child elements (col's) to the height of the tallest col.
.container {
display: flex; //make container a flexbox
}
.col {
flex: 1; //make columns flexible (horizontally)
}
Next, we will use the same approach as before to spread box three vertically across the column.
.container {
display: flex;
}
.col {
flex: 1;
display: flex; //make col a flexbox
flex-direction: column; //make the children of col flex vertically
}
Here we have added display: flex and flex-direction: column to turn column into a verticale flexbox. The last thing to do is make the box you want to be full height flexible vertically.
.three {
flex: 1; //make it flexible
}
.three is flexible vertically (not the default horizontal) due to setting the flex direction on its parent.
EDIT:
Personally, I would set the class box to have flex: 1 as shown in this updated jsFiddle. This allows any number of columns to flex vertically (while still allowing boxes of the "taller" column to grow as they need.
I have two variable-width elements that I'm trying to position the following way:
If they fit next to each other on the screen or in their common container, I want them align to the opposite sides of it (i.e. the second one aligned to right).
If they don't, I want them one above the other, but both aligned to the left.
Something as simple as:
<div class="container">
<div style="display: inline-block;">
I'm a variable width left element
</div>
<div style="display: inline-block; float:right;">
I'm right-floating if there's space
</div>
</div>
takes care of the first case, but obviously when the container is small enough for the second div to be rendered below the first one, it's still right-floating which is not what I want.
Is this even possible with pure CSS? I can't use media queries because of unknown/variable widths.
This layout and behavior is possible without media queries and pure CSS using flexbox.
HTML
<!-- horizontal alignment when two boxes fit -->
<div class="container">
<div class="box box1"><span>1</span></div>
<div class="box box2"><span>2</span></div>
</div>
<!-- vertical alignment when two boxes don't fit -->
<div class="container">
<div class="box box3"><span>1</span></div>
<div class="box box4"><span>2</span></div>
</div>
CSS
.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
width: 700px; /* for demo only; can be relative length, as well */
}
.box1 { width: 100px; }
.box2 { width: 150px; }
.box3 { width: 400px; }
.box4 { width: 500px; }
DEMO
NOTES:
When there is enough space to fit both variable-width elements on the same row, they are aligned at opposite ends of the container with justify-content: space-between.
When there is not enough space to fit both elements, they wrap with flex-wrap: wrap and align-left because the justify-content: space-between rule will left-align an element when it is alone on the row.
Note that flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, post your CSS in the left panel here: Autoprefixer.
I use Bootstrap 4 flexbox enabled. I can not make row > col > div box equal heights.
I have tried position: absolute but it is not the best.
Here's a screenshot:
<div class="row" >
<div class="col-xs-12" >
<div class="home_category" ></div>
</div>
<div class="col-xs-12" >
<div class="home_category" ></div>
</div>
</div>
col-xs-12's height always equals but .home_category height varies based on content size.
I'm looking for a solution to have 100% height for .home_category. Same height as col-xs-12.
Live demo at https://officestock.ca/
I appreciate your feedbacks.
In reviewing your code, the boxes are currently getting their height from the content. You'll notice that some image labels are two-line and others are three-line. The differences in those line numbers are causing differing heights for the boxes.
To apply full, equal height to all boxes simply make this adjustment to your CSS:
#media (min-width: 48em) {
.col-md-6 {
flex: 0 0 50%;
display: flex; /* NEW */
}