css flexbox equal height columns not working - css

I am trying to get css3 flexbox working (for the first time) to make equal height columns (for those browsers that support it).
I have seen various examples across the web but I cant get any to work.
Here is my code (followed by a jsfiddle link)
<div>
<span><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p></span>
<span>col2</span>
<span>col3</span>
</div>
div { background:red; float:left;
-webkit-display:flex;
-moz-display:flex;
display:flex;
}
span { display:block; background:yellow; float:left; width:100px; margin:0 10px;
-webkit-flex:1;
-moz-flex:1;
flex:1;
}
http://jsfiddle.net/38kbV/
Any pointers would be greatly appreciated.

The float is causing the entire thing to fall apart in Firefox. If you need it to appear inline with other content, you'll need to use the inline display property instead (inline-flex, inline-flexbox, inline-box).
When you're following the modern Flexbox draft, you need to stick with all of the properties that belong to that draft. If you try to mix and match, they won't work as expected. There are 3 different drafts that have been implemented in various browsers, each with different property names and values (see: https://gist.github.com/cimmanon/727c9d558b374d27c5b6)
http://tinker.io/11122/2
div {
background: red;
display: -webkit-box;
display: -moz-box;
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
span {
display: block;
background: yellow;
float: left;
width: 100px;
margin: 0 10px;
-webkit-box-flex: 1;
-moz-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}

Related

flexbox adding 1px left margin in Safari

I'm having trouble with Safari adding a 1px margin/gap to the left on the first element in a flexbox row. I've attached an image below of the issue:
The flex box css is:
.equal-height {
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
-webkit-flex-direction: row;
-webkit-flex-wrap: wrap;
flex-direction: row;
flex-wrap: wrap;
}
The child elements are set to the following:
.child-div {
float: left;
display: block;
width: 33.3333%;
box-sizing: border-box;
}
But they I have noticed that they are computed with no float
file: style.css;
line: 1028
.row:before, .row:after{
content: " ";
display: table;
}
add:
width: 100%
and now the "margin" is solved.
The grid system you used has problems with safari: change it.
Hope I've helped you.
I've noticed this as well. Here's what worked for me:
.row:before, .row:after {
display: none;
}
The reason they are computed with no float is that flex cancels them.
As per flexbox spec:
float and clear have no effect on a flex item, and do not take it
out-of-flow. However, the float property can still affect box
generation by influencing the display property’s computed value.
So 100% width on the flex container as per Michael is ok, but if you want flexbox, what you want is:
.child-div {
width: 33.3333%;
box-sizing: border-box;
-webkit-box-flex: 1;
-moz-box-flex: 1;
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
}
i.e. You need to use either floats or flex, but not both.
You may want to have a look at this flexbox generator to understand how flex works.

CSS tables displaying strangely

I am trying to get two columns of content the same height using the CSS tables method. However, for some reason, the first column has extra padding at the bottom, the second column has extra padding at the top.
I am using the same code I usually do and cannot find the source of the problem when inspecting the code. I have double checked my code and look at other examples but cannot find the cause of this problem.
The code I am using is:
.archive-post{
display:table;
vertical-align: top;
padding:20px 0px;}
.archive-post .left-column{
display:table-cell;
width:60%;}
.archive-post .right-column{
display:table-cell;
width:40%;
padding-left:20px;}
Or you can see a live link here.
Use vertical align
.archive-post .left-column,
.archive-post .right-column {
vertical-align: top;
}
This should to the trick.
Just a small idea.. have you tried flexbox, for that? It's really a simple and easiest way to do that. Plus you can use position:absolute; inside the columns (display:table and display:table-cell do not allow that).
* {
box-sizing: border-box;
line-height: 2;
}
main {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 1.25em 0em;
}
section {
background-color: #ccc;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
aside {
background-color: #ccc;
margin-left: 20px;
width: 40%;
}
<main>
<section>
left column.<br>higher then the other
</section>
<aside>
right column
</aside>
</main>

Reorder div table-cells using media queries

I have a div table with two cells. Now I want to show the second cell at the top and the first cell at the bottom of page, when my page is displayed on a smartphone:
<div class="table">
<div class="cell1"></div>
<div class="cell2"></div>
</div>
.table {
display: table;
}
.table .cell1,
.table .cell2 {
display: table-cell;
}
#media (max-width: 480px) {
.table .cell1,
.table .cell2 {
width: 100%; // must be full width on smartphones
display: block;
}
// how to display cell2 at top and cell1 at bottom?
}
I tried to add float properties like float: left and float: right, but it doesn't work.
PS
I cannot just remove table layout and only use floats. There is a reason it must be displayed as table on desktop.
You can do this with the flexbox model. The new flexbox model is not yet widely supported (especially not by older browsers, as the specification has changed recently), but since you mention that it is meant to work on smartphones, this solution might do the trick for you.
I believe most smartphone browsers would support this solution, the one browser which I am not so sure about is Windows Phone 8's version of IE10, IE10 does support this approach, but I'm not sure if the Windows Phone 8 version of IE10 behaves exactly the same as the desktop version.
Setting the variously prefixed display property value and the flex-direction property on the containing element ensures that the container behaves like a flex box in a column direction.
Setting the variously prefixed order property to 1 on .cell1 ensures that the initial value of 0 on .cell1 is overwritten, and therefore it pushes cell1 past .cell2 in the order, as its order value is higher than cell2's order value (which is still equal to its initial value of 0).
Here's a jsFiddle demonstrating this approach.
CSS:
.table {
display: table;
}
.table .cell1, .table .cell2 {
display: table-cell;
}
#media (max-width: 480px) {
.table {
display: -webkit-box;
-webkit-flex-direction: column;
display: -moz-box;
-moz-flex-direction: column;
display: -ms-flexbox;
-ms-flex-direction: column;
display: -webkit-flex;
display: flex;
flex-direction: column;
}
.table .cell2, .table .cell1 {
width: 100%;
display: block;
}
.table .cell1 {
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
}
}

Sorting divs in grid format using only CSS

I have a problem in sorting the div(s), i have two types a, b
a - should always be at the front (all a types)
b - should be following all a types.
HTML:
<div class="" style="">
<div class="a">a</div>
<div class="a">a</div>
<div class="b">b</div>
<div class="a">a</div>
</div>
CSS:
.a, .b {
display:inline-block;
width:50px;
height:50px;
padding:15px;
margin:5px;
}
.a {
float:left;
background-color: blue;
}
.b { background-color: red; }
This seems to work fine in a line:
But breaks as a grid:
Desired result (number of boxes is irrelevant):
JsFiddle: http://jsfiddle.net/kQkn9/
How would i go about fixing this problem?
If you're looking for a pure CSS solution, your only option is to use Flexbox.
http://jsfiddle.net/kQkn9/2/
.container { /* parent element */
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
#supports (flex-wrap: wrap) {
.container {
display: flex;
}
}
.a, .b {
display: inline-block;
width: 50px;
height: 50px;
padding: 15px;
margin: 5px;
}
.a {
background-color: blue;
}
.b {
-webkit-flex-order: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
background-color: red;
}
Browser support: Chrome, Opera, IE10. http://caniuse.com/#feat=flexbox
don't believe this is possible with CSS and HTML alone. My recommendation would be to sort the a's and b's, without changing your css as you have it then re-insert them into the DOM in their new, sorted order.
something to this effect: (in JQ)
var listOfAs = $('.a').clone();
var listOfBs = $('.b').clone();
var parent = $('.a').first().parent('div');
$('.a, .b').remove();
parent.append(listOfAs);
parent.append(listOfBs);
I know this is a touch cumbersome and not super 'responsive' but as i said, don't think its possible with CSS alone...this is just a quick-and-dirty implementation to get you started.
PS: updated your fiddle http://jsfiddle.net/kQkn9/6/
EDIT: clearly this IS possible in newer browsers (thanks to #cimmanon). If you need to support older browsers, you'll have to do something like this (which is definitely less cool)

even spacing between floated divs

Im wanting to float 3 divs evenly(or more generally speaking) .
Im building a responsive theme (kinda) and i want specific items to adjust accordingly based on widths available.
now Yes i can start with taking random screen measurements and make calculations for "breaking points" (what i normally do) but with so many devices, im trying to see if i can make something truly flex in a smarter way which for me, would be something more automatic.
Like when one does even alignment with say margin 0px auto; etc...
so for example. if i have parent div at 1000px wide, and div1, div2, div3, div4 that i want floated at say, 240px wide, and "even" spacing, id maybe do it like this.
div1{ float:left; max-width:XXX; min-width:XXX; margin-right:10px; }
div2{ float:left; max-width:XXX; min-width:XXX; margin-right:10px; }
div3{ float:left; max-width:XXX; min-width:XXX; margin-right:10px; }
div4{ float:right; max-width:XXX; min-width:XXX; }
which will give me more or less my even spacing. If i wanted to adjust to different screens, id maybe do a media queries and blah blah blah
then id have to start with math to make good breaking points that look even.
is there a way to make it so that the spacing between divs floated remains even reguardless of the screen width without having to get into specific numbers?? as an example again, like when one does margin 0px auto; for example???
It may have been asked before, i apologize if it has.
Thanks in advanced.
If your markup looks similar to this...
<div class="parent">
<div>a</div>
<div>b</div>
<div>c</div>
<div>c</div>
</div>
Flexbox can do this very easily, and you won't need to use media queries for narrower devices. It just redistributes the free space for you.
http://jsfiddle.net/END8C/ (all prefixes included)
.parent {
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
-webkit-flex-pack: justify;
-ms-flex-pack: justify;
-webkit-justify-content: space-between;
justify-content: space-between;
margin: -5px; /* optional */
overflow: hidden; /* optional */
}
.parent div {
-webkit-flex: 0 0 240px;
-ms-flex: 0 0 240px;
flex: 0 0 240px;
margin: 5px;
}
You're still free to use floats on the child elements as a fall back for browsers that don't support flexbox (see: http://caniuse.com/#search=flexbox). Only thing to be aware of is that Firefox doesn't support wrapping so you'll have to use a #supports block for the unprefixed version (see: http://www.sitepoint.com/supports-native-css-feature-detection/).
You can get a similar effect by using justification:
http://jsfiddle.net/END8C/1/
.parent {
text-align: justify;
margin: -5px; /* optional */
}
.parent:after {
content: " ";
display: inline-block;
width: 100%;
}
.parent div {
display: inline-block;
margin: 5px;
width: 240px;
}
You'll need to comment out or remove any whitespace after the last child element or they won't line up right when the children wrap.
Try this, it will work for dynamic width,
#parent
{
width:99%;
text-align:center;
border-style:solid;
}
.kids
{
width:23%;
border-style:solid;
height:100px;
display:inline-block;
}

Resources