How to vertically align and evenly distribute two buttons? - html

I'm trying to align the two buttons to be horizontally centered, and evenly distributed vertically on the browser window like the following photo:
#buttonArea {
display: flex;
flex-direction: column;
}
#addButton {
margin: auto;
display: block;
}
#eraseButton {
margin: auto;
display: block;
}
<div id="buttonArea">
<button id="addButton">ADD</button>
<button id="eraseButton">ERASE</button>
</div>
The buttons are horizontally centered, but I don't know how to vertically align them so they are evenly distributed. (e.g. ADD: 33.33%, ERASE: 66.66%)
How can I align the buttons like my photo?

Use justify-content: space-around to distribute equal vertical space around each button and align-items: center to horizontally align the elements.
Just a side note, justify-content applies to the main axis and align-items applies to cross axis. Normally, justify-content applies to the x-axis since the default value for flex-direction is row. However, since we used flex-direction: column, the main axis is now the y-axis.
#buttonArea {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 100%;
height: 100vh;
border: 1px solid black;
}
<div id="buttonArea">
<button id="addButton">ADD</button>
<button id="eraseButton">ERASE</button>
</div>

HTML
<div id="Area">
<div class="container">
<button id="addButton">ADD</button>
<button id="eraseButton">ERASE</button>
</div>
</div>
CSS
#Area {
width: 100vw;
height: 100vh;
}
.container{
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center
}
addButton, eraseButton{
width: 50px;
display: inline-block,
}
What I am doing is
You need to set the width the height of the page so that you can set the items in place you want.
Then will set the container of button to height: 100% because u want to align horizontally centered, and evenly distributed vertically.
Next most important thing is justify-content: space-around; Since you are using flex I hope you know this

You need to add position:relative to the parent div and then for the buttons add position: absolute; and use the top: xx %; property to align it vertically at 33% and 66% of the height.
#buttonArea {
display: flex;
justify-content: center;
align-items: center;
height: -webkit-fill-available;
width: 100%
position:relative;
text-align:centre;
}
#addButton {
display: block;
top: 33.33%;
position:absolute;
}
#eraseButton {
top: 66.66%;
position:absolute;
display: block;
}
<div id="buttonArea">
<button id="addButton">ADD</button>
<button id="eraseButton">ERASE</button>
</div>
Hope this helps. Cheers!

Use position:relative and manage the coordinates accordingly

Related

Horizontal Margins going outside of parent div in flexbox

I'm getting some unexpected behavior with my margins using flex and I would like some help in understanding why.
I'v got some simple html like so:
<div className="dashboard">
<div className="dashboard__inner-container">Inner Container</div>
</div>
And my scss file looks like this:
.dashboard {
text-align: center;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex: 1 1 auto;
background-color: #f4f6f8;
}
.dashboard__inner-container {
display: flex;
flex-direction: column;
background-color: #ffffff;
flex: 1 1 auto;
width: 100%;
margin: 100px 50px;
}
What I am expecting is that the inner container will completely fill up the parent container, minus 100px on the top and bottom and 50px on the right and left. The vertical margin works as expected, but the horizontal margin actually extends out of the parent div, so that the inner container still appears to be taking up the entire width of the parent div.
I'm not sure if this is related to flexbox or not.
Here is an isolated CodePen https://codepen.io/MaxMillington2/pen/EQWZoj
When using align-items: center with column direction, the item will collapse to its content width, instead of with its default, stretch, which makes it fill its parent's width.
Additionally, when setting width: 100% to the inner, it will override the default stretch, which will make the item be 100% of parent's width + margin.
For the expected output, remove align-items: center on the outer and width: 100% on inner.
Stack snippet
html {
height: 100%;
overflow: auto;
}
.outer {
display: flex;
justify-content: center;
flex-direction: column;
background-color: #f4f6f8;
height: 100%;
}
.inner {
display: flex;
flex-direction: column;
background-color: #ffffff;
flex: 1 1 auto;
text-align: center;
margin: 100px 80px;
}
<div class='outer'>
outer
<div class='inner'>
inner
</div>
</div>

Why isn't my flex item aligning in the center?

I am trying to center a red box in the middle of the page.
I have set the flex container to 100% in height, and have also set the html,body to 100%, and it still does not align center.
Can anyone please help me understand why its not working? Thanks!
html, body {
height: 100%;
}
.flex-container {
display: flex;
flex-flow: column;
justify-content: center;
height: 100%;
}
.box {
flex: 0 0 100px;
background: red;
width: 100px;
}
<div class='flex-container'>
<div class='box'></div>
</div>
You use justify-content to align flex items on the main axis.
You use align-items to align flex items on the cross axis.
Since your flex container is flex-direction: column:
the main axis is vertical, and
the cross axis is horizontal.
justify-content: center is working fine.
You just need to add align-items: center.
html, body {
height: 100%;
}
.flex-container {
display: flex;
flex-flow: column;
justify-content: center; /* centers flex items vertically, in this case */
align-items: center; /* NEW */ /* centers flex items horizontally, in this case */
height: 100%
}
.box {
flex: 0 0 100px;
background: red;
width: 100px;
}
<div class='flex-container'>
<div class='box'></div>
</div>
Here's a more detailed explanation:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
You need to add align-items to .flex-container
align-items: center;
See here for an example https://jsfiddle.net/x9gyheo6/1/

Flexbox not vertically centering inline-block spans

I have a dashboard I am setting up that has wrapper blocks with a sprite icon that should be centered vertically and horizontally inside its parent.
I got the blocks to be placed how I want and wrapping how I want using flexbox.
I also have the icon centered horizontally using the text-align property, but for some reason justify-content: center doesn't do anything when I add it to the .view or .sprite-icon elements; adding it to the .views element also doesn't center things how I want and it breaks the padding between the .view blocks.
See my JSFiddle I set up showing the issue here: https://jsfiddle.net/efarley/k0m4nxny/
.views {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
}
.view {
height: 105px;
text-align: center;
width: 105px;
}
.sprite-icon {
background-image: url('http://67.media.tumblr.com/b2336d673e315081b6d657f8258c313d/tumblr_mv98xzSiJu1qhori9o1_500.jpg');
display: inline-block;
height: 35px;
width: 35px;
}
.sprite-icon.one {
background-position: 0 0;
}
.sprite-icon.two {
background-position: 0 35px;
}
.sprite-icon.three {
background-position: 0 70px;
}
<div class='views'>
<div class='view'>
<span class='sprite-icon one'></span>
</div>
<div class='view'>
<span class='sprite-icon two'></span>
</div>
<div class='view'>
<span class='sprite-icon three'></span>
</div>
</div>
You need to make your view a flex container, then add flex centering properties.
.view {
height: 105px;
text-align: center;
width: 105px;
display: flex; /* new */
align-items: center; /* new */
justify-content: center; /* new */
}
revised fiddle
Note that the justify-content property only applies to flex containers. In your question, you were applying it to a flex item. That's why it failed.
Learn more about flex centering:
How to Center Elements Vertically and Horizontally in Flexbox
Methods for Aligning Flex Items
Try these settings:
.sprite-icon {
display: block;
position: relative;
margin: 35px auto;
background-image: url('http://67.media.tumblr.com/b2336d673e315081b6d657f8258c313d/tumblr_mv98xzSiJu1qhori9o1_500.jpg');
height: 35px;
width: 35px;
}
margin 35px auto centers it horzontally (when position is relative) and moves it down 35px, which centers it vertically, but only since display is now block. I erased text-align: center in .view
Fiddle: https://jsfiddle.net/0t4vbzxb/1/

Vertically centering with flexbox

I'm trying to center a div on a webpage using flexbox. I'm setting the following CSS properties. I see that it's being centered horizontally, but not vertically.
.flex-container {
display: flex;
align-items: center;
justify-content: center;
}
Here's the fiddle: JSFIDDLE
Can you explain what I'm doing wrong?
A <div> element without an explicit height defaults to the height of it's contents, as all block elements do. You'd probably want to set it to 100% of it's parent, the <body>, but that's not enough, since that is also a block element. So again, you need to set that to 100% height, to match it's parent, the <html>. And yet again, 100% is still required.
But once all that is done, you get that annoying vertical scroll bar. That's a result of the default margin the body has, and the way the box model is defined. You have several ways you can combat that, but the easiest is to set your margins to 0.
See corrected fiddle.
html, body {
height: 100%;
margin: 0px;
}
.flex-container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.item {
background-color: blue;
height: 50px;
width: 50px;
}
<div class="flex-container">
<div class="item">
</div>
</div>
You just need to set html, body, and your flex container to height: 100%. The reason it wasn't working is that your flex container didn't have an explicit height set, so it defaulted to the height of its contents.
Live Demo:
html, body {
height: 100%;
}
.flex-container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.item {
background-color: blue;
height: 50px;
width: 50px;
}
<div class="flex-container">
<div class="item">
</div>
</div>
JSFiddle Version: http://jsfiddle.net/d4vkq3s7/3/

Flexbox wrap - different alignment for last row

I'm using flex box to align two items to left and right of the container, while vertically centre-aligning them. Here's a very simple example of what I'm trying to achieve.
HTML:
<div class="container">
<div class="first"></div>
<div class="second"></div>
</div>
CSS:
.container {
width:100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
.first {
background-color: yellow;
width: 200px;
height: 100px;
}
.second {
background-color: blue;
width: 200px;
height: 100px;
}
Here's the jsfiddle of the example.
This works perfectly well if the screen is wide enough to fit both internal divs on one row. However when the screen size is small (e.g. a mobile phone) and the divs wrap onto the second line, the second one also becomes aligned to the left side (i.e. flex-start). How can I force the second div to always be aligned against the right border, regardless of whether it's on the first row or wrapped onto the second one?
EDIT: In the example, I assigned fixed width to the two child elements - this is for simplicity only. In the real life application, all widths are dynamically changing based on the content read from the database at run-time. Hence, any solution that's based on fixed sizes will not work.
You can try adding some left margin to push your .second element to the right:
.second {
margin-left: auto;
}
.container {
width:100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
.first {
background-color: yellow;
width: 200px;
height: 100px;
}
.second {
background-color: blue;
width: 200px;
height: 100px;
margin-left: auto;
}
<div class="container">
<div class="first"></div>
<div class="second"></div>
</div>
Or, similarly, justify all elements to the right but push .first element to the left:
.container {
justify-content: flex-end;
}
.first {
margin-right: auto;
}
.container {
width:100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-end;
align-items: center;
}
.first {
background-color: yellow;
width: 200px;
height: 100px;
margin-right: auto;
}
.second {
background-color: blue;
width: 200px;
height: 100px;
}
<div class="container">
<div class="first"></div>
<div class="second"></div>
</div>
I found a solution but it is rather "hacky" in nature (see demo here, explanation later), in the sense that it requires you to explicitly know the width of the parent container which will trigger a layout change based on #media.
The reason why your code is not working is because of the confusion over how align-self works. In the flexbox model, "align" refers to alignment along the cross-axis (i.e. in a conventional sense of a "row" layout direction, that will refer to vertical alignment), while "justify" refers to alignment along the main axis (i.e. the row). To better explain my point, I hereby attach an image made by Chris Coyier from his flexbox guide:
Therefore, align-self: flex-start means telling the .first to align to the top of the container, and align-self: flex-end means telling .second to align to the bottom of the container. In this case, since you have not declared an explicit height for the parent, the parent will take on the height of its tallest child. Since both .first and .second are 100px tall, the parent will also have a computed height of 100px, therefore making no difference in the alignment (because both with be flush with the start and end of the cross axis).
A hack would be switching the flex-direction to row, with the following restrictions: You know how wide your container will be, or the explicit widths of its children. In this case the breakpoint will be at 400px, where .first and .second will intersect each other.
.container {
width:100%;
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: space-between;
height: 100px;
}
.first {
background-color: yellow;
width: 200px;
height: 100px;
align-self: flex-start;
}
.second {
background-color: blue;
width: 200px;
height: 100px;
align-self: flex-end;
}
#media screen and (max-width: 400px) {
.container {
height: 200px;
}
}
Then again, here is a proof-of-concept fiddle, modified from your original one: http://jsfiddle.net/teddyrised/cncozfem/2/