Z index isn't working in flexbox

Z index isn't working in flexbox
0

#1

I am trying to center a div with the id #controller on top of other divs all with the class .color, but when I centered the div, even with a higher z index the layout breaks. I was having a similar problem before but adding box-sizing: border box to everything fixed it. I’m not sure how to fix this and would appreciate help, Here is a link to my codepen: https://codepen.io/icewizard/pen/JLBpNQ

*{
    box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
body{
    background-color: gray;
}

.centered {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.outer{
    height: 30em;
    width:30em;
    background-color:rgba(21, 56, 41, 1);
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    border-radius: 50%;
    border-style: solid;
    border-width: 10px;
}

/*=============Color buttons=================*/

.color{
    flex-grow:1;
    flex-shrink: 1;
    flex-basis: 50%;
    z-index: -1;
}

#green{
    background-color:green;
    border-bottom-left-radius: 100%;
    border-top: 10px solid;
    border-right:10px solid
}

#blue{
    background-color:blue;
    border-top-left-radius: 100%;
    border-right:10px solid
}

#yellow{
    background-color:yellow;
    border-bottom-right-radius: 100%;
    border-top: 10px solid;
}

#red{
    background-color:red;
    border-top-right-radius: 100%;
}


/*=============Controller=================*/

#controller{
    align-self: center;
    height:2em;
    width:4em;
    background-color:gray;
    z-index: 2;
}
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8'>
        <title>Simon Game</title>
        <link rel='stylesheet' href='./main.css'>
        <script type='text/javascript' src='./simon.js' async></script>
    </head>
    <body>
        <div class='container outer centered'>
            <div id = 'blue' class= 'color shade'></div>
            <div id = 'red'  class= 'color shade'></div>
            <div id = 'controller'></div>
            <div id = 'green'  class= 'color shade'></div>
            <div id = 'yellow'  class= 'color shade'></div>
        </div>
    </body>
</html>

#2

z-index only works if you apply position: (relative/fixed/absolute). Flex is for positioning things side-by-side, not on top of each other


#3

I tried applying position:relative to .color and #controller, but nothing changed. What am I supposed to add it to? Also tried the other positions but nothing is working.


#4

Flex is for positioning things side-by-side, not on top of each other

You need to use something other than flex to do what you’re trying to do here


#5

adding this to controller top: 50%; left: 50%; transform: translate(-50%, -50%);
position: absolute; works, but in a stackoverflow post I’ve seen z index work with flex, but I can’t get mine to do the same with similar css.


#6

Yes, but the problem you have is that flex is designed to allow flex elements to automatically resize to fill available space along one axis - this is what I mean by flex being designed for positioning things side-by-side, in one dimension - think a menu bar. Whereas what you are trying to do is carefully position five elements in a 2d space. It is possible, it’s just that you will be fighting to try to get flex to do something it’s not designed to do

Edit: if I remove the CSS for curved borders, just so it’s easier to see layout, this is the current placement (the little grey rectangle being your controller):

Flex is working fine, it’s automatically distributing into the available space. But if you used position: absolute instead, it would be a lot easier. As soon as you start to try to delicately position the buttons & controller using flex, things are going to break down fast, and as soon as you start adding in content rather than just empty blocks, it will get even worse. If you really want to use flex, then move the controller out of the container and just position it on top of everything else.


#7

Alright thanks for the explanation I appreciate it.


#8

As an example, using flex to centre the whole thing (body gets display: flex; min-height: 100vh, outer gets margin: auto). Then outer has position relative. Then container just has the buttons, and position absolute, which lets you use height/width 100% to snap it into outer. And that has display flex, which now works. Then controller can use position absolute as well to sit over the top.


#9

I think my fix for it looks cleaner I just added the center class to it, but thanks https://codepen.io/icewizard/pen/JLBpNQ