z-index controls the stacking order of positioned elements only. If an element isn’t positioned then its unlikely to overlap (ignoring negative margins for now) and z-index would have no effect unless you add a value for the position property other than ‘static’.
Positioned elements will be naturally stacked with regard to their html order with elements later in the html being stacked on top of the ones before. Therefore if you want an earlier element in the html to be stacked on top of something later in the html (which also may be positioned) then you arrange the z-indexes so that the stacking order meets your requirements.
This is a simplistic view of stacking order and z-indexes because positioned elements with a z-index other than ‘auto’ become ‘atomic’ for their children and no matter the z-index of the child it cannot escape from its parents z-index in regard to other elements outside that context.
There are also special rules for certain properties that create automatic stacking indexes such as opacity and transforms etc. It’s a broad subject that needs to be studied