I have been reading up on flex-boxes in order to solve a problem I have been having. The main article I have read up on /used as research for the problem is this.
I recently brought this topic up in this and this questions and thanks to the help of @Michael_B, it was worked out how to center an element (in this case an <h2>
) in a flex-box as long as there are always and only three flex-items in the flex-box (in this layout: <div><h2><div>
).
I wanted to expand upon these points as I realized there might be a solution which could solve if there are more or (more realistically) less than 3 total flex-items.
It involves using margins. If you use margin: auto;
on a flex item, it acts to center an item on the main axis (see following picture for how a flex-box works).
img {
width: 100%;
height: 100%;
}
<img src="https://i.stack.imgur.com/9Oxw7.png" alt="flex-box demo" />
(That was the best way I could figure out how to get a dropdown-photo...)
From what I am understanding, using margin: auto
is the current counterpart to the align-self
property for the cross axis.
Thus one could do this to center a flex item in a flex box in these ways:
$(document).on('click', 'button', function(e) {
$this = $(this);
if ($this.attr('id') === 'button1') {
$('h2').parent().attr("class", "");
$('h2').attr("class", "toggle1");
}
if ($this.attr('id') === 'button2') {
$('h2').parent().attr("class", "");
$('h2').attr("class", "toggle1");
}
if ($this.attr('id') === 'button3') {
$('h2').parent().attr("class", "toggle3");
$('h2').attr("class", "");
}
if ($this.attr('id') === 'button4') {
$('h2').parent().attr("class", "toggle4");
$('h2').attr("class", "");
}
if ($this.attr('id') === 'button0') {
$('h2').parent().attr("class", "");
$('h2').attr("class", "");
}
});
div:not(.cont),
div:not(.cont) * {
border: 1px dotted red;
}
div {
align-items: center;
display: flex;
}
button {
margin: 16px;
}
.toggle1 {
margin: auto;
}
.toggle2 {
flex: 1;
}
.toggle3 {
justify-content: center;
}
.toggle4 {
justify-content: space-between;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div>
<h2>I'm an h2</h2>
</div>
<div>
<span>I'm a span!</span>
<h2>I'm an h2</h2>
<span>I'm a span!</span>
</div>
<div>
<span>I'm a span!</span>
<span>I'm a span!</span>
<h2>I'm an h2</h2>
<span>I'm a span!</span>
<span>I'm a span!</span>
</div>
<div class="cont">
<button id="button0">clear</button>
<button id="button1">margins</button>
<button id="button2">flex-grow</button>
</div>
<div class="cont">
<button id="button3">justify-content: center
<br />(on parent)</button>
<button id="button4">justify-content: space-around
<br />(on parent)</button>
</div>
As you can see from the above snippet, it only works if there are the same amount of flex-items on each side of the <h2>
(and you can also see that justify-content: space-around
does not work with just one object).
But what if there are an unbalanced amount of flex items on each side of the object you are trying to center? - Sure, you could put blank elements there and use
flex: 1;
, but that seems a bit hacky.
My idea is to make use of negative-margins. I read a great article (here) about using negative-margins and how they can pull objects towards them, etc. (plus, even w3 says they are legitimate code - not hacky).
The idea is to set <h2>
to margin: auto;
and then somehow (I emphasis somehow as with all the research I have been doing I am starting to lose hope...) take the width of any sibling flex-item and negate that from the <h2> margin: auto;
... sounds hacky and hopefully there is a way to do it without JS/jQuery or a CSS compiler.
Does anyone know of a way to negate from the margin of a flex item the width of a sibling flex item in the same flex-box?
Thank you.
P.S./UPDATE
There might be a way to accomplish this with the position
property; however, all the testing I have done has produced no results... Maybe someone else has been successful with this method?
` in a flex box with an uneven number of spans either side then maybe you could place each `` in a `` on either side with a width of 50%. Here is a [JSFiddle](https://jsfiddle.net/ToddNewent/p8vjazLu/) of what I am trying to explain.
– Todd Nov 06 '16 at 14:33