Safari 8 Flexbox float and center - css

Whatever I do, I can't seem to get the columns that float left and right to center and align to the middle of it's container. Is there a way with Flexbox only to just have a left and right column, but still align them in the middle? It works fine in Firefox and Chrome, but not on Safari 8.
https://jsfiddle.net/vhem8scs/68/
.container {
display: flex;
align-items: center;
justify-content: center;
background: #ccc;
height: 200px;
margin-top: 20px;
}
.column:after {
content: '';
display: table;
clear: both;
}
.column div {
float: left;
}
.column div:last-child {
float: right;
}
Update
I added the following line to the container.
justify-content: space-between
While it aligns to the center/middle of the container, the floats do not work now.

Unfortunately it is rather difficult to visualize what you're trying to accomplish with your styles, but here's my preliminary analysis of the issue.
Once you declare an element to be a flex container, all the children will follow flexbox rules. Float styles will essentially be ignored. As a result, what you might want to try doing is making use of the flex-grow, flex-shrink, and flex-basis properties on the children to ensure columns sit in the proper position.
If you goal is to simply put space in between the columns, utilize the justify-content property with either space-around or space-between on the parent flex element.
Hope this helps!

Related

Stop an element from moving on window resize

I am currently making the footer of my project, and somehow every element I code seems to move every time I (or the user) resizes the window.
I have tried -
margin: 0 auto;
position: relative; float: left;
EDIT:
Code:
.pdiv{
/* div might be helpful? */
}
.footer {
position: relative;
left: 300px;
}
Try to use flexbox in your footer,
footer {
display: flex;
justify-content: center; // or flex-end, flex-start of your choice how you want them to look
align-items: center; // or same as above
}
Make yourself a favor and please use flexbox instead of floats, please, floats are not meant to do layout, this is more historical as before flexbox, there was no "universal" nor "adapted" way to compose clear layouts (dont start me on table's, plz).
This may help you:
https://www.smashingmagazine.com/2017/07/enhancing-css-layout-floats-flexbox-grid/ (Float to Flexbox migration)
https://flexboxfroggy.com - A game to learn Flexbox

How to use safe center with flexbox?

Centred flexbox items can have undesirable behaviour when they overflow their container.
Several non-flex solutions have been provided for this issue, but according to MDN there is a safe value which is described as follows.
If the size of the item overflows the alignment container, the item is instead aligned as if the alignment mode were start.
It can be used as follows.
align-items: safe center;
Unfortunately, I haven't been able to find any examples or discussions of this, or determine how much browser support there is for it.
I have attempted to use safe in this CodePen. However, it doesn't work for me. The safe seems to be ignored, or perhaps the container element is improperly styled.
I'd really appreciate it if anyone could shed some light on safe and whether and how it can be used to solve the overflow problem, as demonstrated by the CodePen example.
The newer keyword safe still has bad browser support, so to get the same effect, cross browser, use auto margins for now, which should be set on the flex item.
Updated codepen
Note, to compensate for the modal's 50px top/bottom margin, use padding on modal-container.
.modal-container
{
display: flex;
flex-direction: row;
justify-content: center;
align-items: flex-start; /* changed */
position: fixed;
width: 100vw;
height: 100vh;
overflow-y: scroll;
padding: 50px 0; /* added */
box-sizing: border-box; /* added */
}
.modal-container > #modal
{
display: flex;
flex-direction: column;
align-items: center;
margin: auto 0; /* changed */
padding: 12px;
width: 50%;
background-color: #333;
cursor: pointer;
}
safe isn't implemented in most browsers yet. You can recreate some of its functionality with auto margins.
I was trying to use justify-content: safe center to have a bunch of items centered in a footer when the viewport was wide, but have them able to scroll without clipping off the left side when the viewport was small.
When I tried to fix this with auto margins as Ason suggested, it did fix the clipping, but it also spread the items out evenly, which isn't what I wanted.
I found I could simulate safe center in this context by applying auto margins to only the first and last elements.
Assuming my flex items have class "item":
.item:first-child {
margin-left: auto;
}
.item:last-child {
margin-right: auto;
}
CodePen with examples comparing each solution
Use align-items: flex-start; instead of using it with the safe keyword, Also, you can add margin/padding to get the desired behavior for the same.

Use 'ghost element' to vertically align an inline-block element of width 100% within its container

this article mentions a technique of vertically centering an element in css using a 'ghost element'.
/* This parent can be any width and height */
.block {
text-align: center;
/* May want to do this if there is risk the container may be narrower than the element inside */
white-space: nowrap;
}
/* The ghost, nudged to maintain perfect centering */
.block:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
/* The element to be centered, can also be of any width and height */
.centered {
display: inline-block;
vertical-align: middle;
width: 300px;
}
codepen here.
It doesn't work, however, when the element to be centered has width:100%, becuse the element gets pushed onto a new line. How you adapt the solution in order to work in this case? I need a solution with good browser support including IE9+
I figured it out, I was suffering from the "spacing between empty inline-block elements problem". There are a few ways to fix this, I fixed it by commenting out the whitespace between elements in the HTML.
Here is a working plunker

Defining overflow direction of vertically aligned flexbox item

I have a flexbox with a single item. This item is horizontally and vertically centered. When the item grows taller than its container it overflows equally at the top and the bottom of the container. I would like it to only overflow at the bottom, and remain anchored at the top. Any ideas?
http://codepen.io/wilsonpage/pen/LzryK (view in Chrome Canary for latest Flexbox)
Under the standard Flexbox draft, a single flex item can be vertically and horizontally centered by using margin: auto. You'll want to use this instead of the align-items property:
http://codepen.io/cimmanon/pen/EJdvn
section {
display: flex;
justify-content: center; /* you can remove this here, but its not hurting anything */
/* remove align-items */
height: 80%;
margin: 5% 0;
background: green;
}
div {
margin: auto; /* add */
}
Try setting the following on the flex item:
align-self: flex-start;

Flexible box layout model: How should auto margins in the cross-axis direction behave?

Please help me to understand one issue with the flexible box layout model for which I get different results in Firefox and Chrome.
Consider the following HTML fragment:
<body>
<header>Header</header>
<footer>Footer</footer>
</body>
styled via
body {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
}
header {
max-width: 400px;
height: 20px;
background-color: yellow;
margin: 0 auto;
}
footer {
width: 400px;
height: 20px;
background-color: green;
margin: 0 auto;
}
The header box has a maximum width constraint of 400px while the footer has a fixed width of 400px. When I try this code in Gecko-based browsers (Firefox 21 and 24 in my case) both header and footer are horizontally centered (as I hoped for by giving them left and right auto margins) but only the footer has a width of 400px while the header's width is just the width of the content even if enough horizontal space was available.
In WebKit/Blink-based browsers (Chrome 25 and 28 in my case) the header and footers are both centered and are both 400px wide (in case there is enough horizontal space), and this is exactly what I want to achieve.
Obviously, either Firefox or Chrome must be wrong. How do you understand the spec: http://www.w3.org/TR/css3-flexbox/? What is the desired behaviour?
If you want to play around, here is a JSFiddle: http://jsfiddle.net/4Rv7K/.
Note that one has to enable the flexible box layout model in the release version of Firefox. It is the setting layout.css.flexbox.enabled. (Without it, one is actually not testing anything about flexboxes.)
P.S.: The bug was in Chromium's engine and has apparently been fixed by now: https://code.google.com/p/chromium/issues/detail?id=242654
The Firefox/Gecko behavior is correct.
WebKit is stretching up to 400px (the max-width) due to the header element's default "align-self: stretch" value. However, the spec is clear that "align-self: stretch" is only supposed to stretch if you have no auto margins in the cross axis. Quoting the spec:
If a flex item has ‘align-self: stretch’, [...] and neither of its
cross-axis margins are ‘auto’, the used outer cross size is the used
cross size of its flex line, clamped according to the item's min and
max cross size properties
http://www.w3.org/TR/css3-flexbox/#cross-sizing
The exception for "neither of its cross-axis margins are auto" is what Firefox is honoring here and WebKit/Blink appear to be ignoring.
Now, to achieve your desired layout: It looks like you want both stretchiness and centering, and I don't think you can get both of those things simultaneously in the cross axis.
You can get them simultaneously in the main axis of a flex container, though -- so you can fix this by adding a horizontal flex container around the header and the footer.
I've done that here:
http://jsfiddle.net/4Rv7K/16/
The relevant code (just with the 'header' for simplicity):
body {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
}
horizFlex {
display: -webkit-flex;
display: flex;
}
header {
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
max-width: 400px;
height: 20px;
background-color: yellow;
margin: 0 auto;
}
[...]
<body><horizFlex><header>Header</header></horizFlex></body>
I think this achieves the layout you're looking for by wrapping the header and footer each in a horizontal flex container. The flex container stretches to the width of its parent (the body), and inside of it we have a single flex item (e.g. the ), which is flexible up to its max-width, and which we center (with auto margins) once it has reached its max-width.
For an element that lacks a definite size with auto margins, it looks like the element's fit-content width is supposed to be used as the element's actual width while the remaining space is counted as margin. For Chrome, it appears to be behaving inappropriately only when using flex-direction: column.
http://codepen.io/cimmanon/pen/fuhyF
ul {
display: -webkit-flex;
display: flex;
height: 5em;
background: yellow;
}
li {
margin: auto;
border: 1px solid;
}
ul.column {
-webkit-flex-direction: column;
-flex-direction: column;
}
If you look at a list with the above styles, Opera, Firefox, and Chrome agree that the li elements are shrink wrapped when the direction is row. Under the column direction, only Firefox and Opera shrink wrap the li, while Chrome has the li take the full width of the flex container.

Resources