How to use safe center with flexbox? - css

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.

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

(Yet Another) Flexbox & Position: Sticky

I have (yet another) position: sticky / display: flex conundrum to add to the pile.
A section of a webpage I'm working on has a standard flex box layout: a single outermost flex container set to flex-direction: row in which I've nested two flex containers set to flex-direction: column.
The first/left nested column contains a bunch of text.
The second/right nested column contains two additional nested flex containers with images and/or text, and I've used justify-content: space-around to "push" these nested containers to the top and bottom of the second column.
What I'm trying to do is to set the second/right column's first/top flex container to position: sticky such that it sticks to the top of the second/right column (its parent flex container) at top: 50px.
Because there is significantly more content in first/left column than the second/right column, setting justify-content: space-around on the second/right column creates a good amount of white space between the second/right column's nested first/top and second/bottom flex containers. My thinking here is that setting the second/right column's first/top flex-container to position: sticky will allow the first/top flex container to "traverse" this white space as a user reading the text in the left-hand column scrolls down.
I realize that's a bit difficult to visualize using text alone, so here's a rough sketch of the layout:
In terms of the CSS associated with each flex box, here's what I'm currently using:
1. Outmoster Flex Container (Row):
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
height: 100%;
overflow: visible;
2a. First / Left Nested Flex Container (Column)
flex-direction: column;
justify-content: center;
align-items: center;
max-width: 60ch;
padding: 25px;
background: var(--gray_card);
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
2b. Second / Right Nested Flex Container (Column)
flex-direction: column;
justify-content: space-between;
padding: 25px;
3a. First / Top Flex Container
position: -webkit-sticky;
position: sticky;
top: 50px
flex-direction: column;
align-self: center;
justify-content: space-evenly;
margin: 10px 0px;
border: 1px solid lightgray;
border-radius: var(--border_radius);
background: var(--white);
3b. Second / Bottom Flex Container
flex-direction: column;
justify-content: center;
align-content: center;
align-self: center;
border-radius: var(--border_radius);
padding: 35px;
background: var(--gray_card);
4. Flex Container (Row)
align-self: center;
justify-content: space-evenly;
margin: 10px 0px;
border: 1px solid lightgray;
border-radius: var(--border_radius);
background: var(--white);
I suspect the reason position: sticky isn't working on Flex Container 3a has something to do with the logic of flexbox, but after hacking away at this all morning, and after consulting similar Stack Overflow posts, I'm afraid I'm stumped. Nothing I've tried (including setting overflow: visible on parent items all the way up to the main, body, & html elements) seems to work.
Hopefully someone here will see something I've missed, as I also suspect there's an easy fix to this I simply don't know.
Many thanks in advance for taking the time!
UPDATE: Found the problem.
It turns out the the main element on this page was set to overflow: hidden...on another Sass partial further down in the page's head element. This second Sass partial was overwriting the changes I was making to the main element further up in the head. Duh.
I applied an #id to the main element, used that #id to set overflow: visible in my page-specific stylesheet and everything worked just fine.
A rookie mistake, but one I'm happy to have publicly made if reminds other devs that, when all else fails, check the order in which your CSS is being loaded into the browser.
If, like me, you're loading your base styles & resets after page-specific CSS, it pays to do a quick search for overflow: hidden in those files if display: flex & position: sticky aren't playing well with one another.
If that doesn't work, then it's probably time to explore some of the other solutions mentioned elsewhere on Stack Overflow, such as this post.
Although the solution in my case ended up being a simple oversight on my part, the fact remains the way display: flex & position: sticky interact is a CSS gotcha all devs will encounter at one point or another.

How can i make a flex item grow to both ways

I would like to grow an item (.sub-container) to the both ways when I validate my form, top and bottom, but when the error mesage appear, it only grow to bottom and I'm here all day long and I already change everything in my code but it didn't grow the both ways, it just grew bottom, the ".container" is where everything are inside, pls someone know how to do it?
.container{
width: 80%;
padding: 70px 0;
flex-direction: row;
align-items: center;
justify-content: center;
}
.sub-container{
display: flex;
flex-direction: column;
flex-grow: 1;
width: 50%;
}
before validate
after validate
The Flexible Box Layout Module, makes it easier to design flexible
responsive layout structure without using float or positioning.
Source # https://www.w3schools.com/css/css3_flexbox.asp
What you're trying to do as nothing to do with flexbox.
what you call "grow" is just default css behaviour. The only way to achieve what you want (Enlarging both height and width upon form submission) is realized by using javascript.

Why doesn't this CSS flexbox example work on IE 11?

I am using a flexbox layout that is usually presented as a row but when the screen is a certain width it switches to column. This works fine in Chrome, Firefox, Safari and Edge but on IE 11 the flex elements will not center even though I am using justify-content: space-around;
I have looked at https://github.com/philipwalton/flexbugs and other websites that list flexbox bugs and I can't seem to find the solution.
I have distilled it down to a simple example to demonstrate the problem.
First we have a container that spans the width of the screen with the following properties:
.container {
display: flex;
flex-direction: column;
justify-content: space-around;
text-align: center;
width: 100%;
}
Then inside it we have four cells with the following properties:
.cell {
flex-grow: 2;
text-align: center;
display: inline-block;
background-color: green;
margin: 5px auto;
min-width: 50px;
max-width: 20%;
}
On IE the four cells are aligned left, but on any of the other browsers the cells are center aligned.
Here is an artist's impression of the situation
I have created a JSFiddle that demonstrates the issue at https://jsfiddle.net/8w1gf7vx/4/
You are using the wrong property - justify-content is for alignment on the main axis. Your flex-direction is column, therefor the main axis goes from top to bottom - and so all justify-content does here is influence the distribution of space above and below your items.
You want to align your items on the cross axis - and the property to achieve that is align-items.
.container {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
https://jsfiddle.net/8w1gf7vx/6/
text-align: center; and display:inline-block from the items can be removed - unless you want to use those as a fallback for browsers that don't understand flexbox. (I suspect they might be the reason that what you had seemed to work as intended in other browsers. As Oriol pointed out in comment, that's rather due to margin-left/-right being auto - and that IE doesn't seem to support that.)
http://flexboxfroggy.com/ is a nice way to get a better understanding of what the different flex properties do, in the form of a little game - might be worth a look for anyone who still struggles a bit with flexbox now and then (and that includes myself ;-)
Disclaimer: I am not affiliated with that site in any way, I just think it is quite useful in gaining a better understanding of flexbox.

Flexbox centering items is causing overlapping content

When I try to use flexbox to center items there is some overlapping content and misalignment.
https://jsfiddle.net/a9oc6gL8/1/
.footer_3 {
position: relative;
display: flex;
align-items: top;
justify-content: center;
top: 220px;
padding-bottom:100px;
}
.footer_4 {
position: relative;
display: flex;
align-items: top;
justify-content: center;
top: 190px;
}
To explain, I've drawn some extra rectangles to demonstrate what goes wrong.
The top-left and top-right columns together are as wide as the bottom-left and bottom-right bar, but are not the same ratio.
Now I could go and explain how to fix this, but I've noticed that you've been making a lot of mistakes throughout the document. I think it's more important that you try to get a little better at the basics, than trying the get the hang of flexbox.
Besides that. I've created a Fiddle that shows a fixed situation. I've given it a complete overhaul without flexbox.
What I've done, is create two columns that are both exactly 50% wide. They both float to the left. Like this, the text of the left and right side are always at the same spot. I've cleaned up the code (you were switching ul and li, using unnecessary classes, you used a plain ampersand (&) whilst you should type & when creating one... There was a lot wrong). Also. The '01', '02' etc. are now automatically generated with CSS.
The document has changed as a whole. I advise looking into it, and trying to understand what happens with every line of code. It'll sure teach you a thing or two.
Hope this helps
I've simplified your code. With these adjustments, your desired alignments come together:
CSS
.footer_3 {
display: flex;
width: 75%;
margin: 220px auto 50px;
}
.footer_4 {
display: flex;
width: 75%;
margin: 0 auto;
}
.about_description {
width: 100%;
}
DEMO

Resources