Center items correctly when using justify-content: space-between - html

I created a header bar and want to place 3 items there. The first should be aligned on the left side, the second in the middle of the header and the third on the right side.
I went for this
body{
background: #eeeeee;
}
#header {
background: #ffffff;
height: 53px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.headerEle {
}
<div id="header">
<img class="headerEle" src="https://cdn.discordapp.com/attachments/316916526760591362/390814093340311565/unknown.png">
<a class="headerEle" href="https://www.google.de/">Google</a>
<button class="headerEle">Logout</button>
</div>
but when using justify-content: space-between; the items don't get centered correctly. The image takes a bigger place than the small button on the right.
So the link in the middle is not centered correctly, it overlaps the right side. I want the link being in the horizontal center of the page.

You can do something like this:
body {
background: #eee;
}
#header {
background: #fff;
height: 53px;
display: flex;
/*flex-direction: row; not necessary, by default*/
align-items: center;
justify-content: space-between;
}
#header > span {flex: 1} /* each 33.33% of the parent's width */
img {display: block; max-width: 100%; max-height: 100vh} /* responsiveness; "display: block" removes bottom margin/whitespace */
.link {
display: flex;
justify-content: center; /* horizontally centered */
}
.btn {
display: flex;
justify-content: flex-end; /* placed far right */
}
<div id="header">
<span>
<img class="headerEle" src="https://cdn.discordapp.com/attachments/316916526760591362/390814093340311565/unknown.png">
</span>
<span class="link">
<a class="headerEle" href="https://www.google.de/">Google</a>
</span>
<span class="btn">
<button class="headerEle">Logout</button>
</span>
</div>

You can use absolute positioning for the <a> element to exactly center the link on the header:
body{
background: #eeeeee;
}
#header {
background: #ffffff;
height: 53px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
position:relative;
}
#header a {
position:absolute;
left:50%;
top:50%;
transform:translate(-50%, -50%);
}
<div id="header">
<img class="headerEle" src="https://cdn.discordapp.com/attachments/316916526760591362/390814093340311565/unknown.png">
<a class="headerEle" href="https://www.google.de/">Google</a>
<button class="headerEle">Logout</button>
</div>

Is this what you are looking to do?
body{
background: #eeeeee;
}
#header {
background: #ffffff;
height: 53px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
#header > div {
-webkit-flex: 1; /* Safari 6.1+ */
-ms-flex: 1; /* IE 10 */
flex: 1;
text-align: center;
}
<div id="header">
<div>
<img class="headerEle" src="https://cdn.discordapp.com/attachments/316916526760591362/390814093340311565/unknown.png">
</div>
<div>
<a class="headerEle" href="https://www.google.de/">Google</a>
</div>
<div>
<button class="headerEle">Logout</button>
</div>
</div>

Related

aligning the last object in css-grid or flexbox

I'm trying to tidy up my code and I have a menu that I would like to organise a little better.
Is there a way of aligning the menu at the start, end or or center while having the last item in the menu aligned to the end?
I've currently stripped out everything and kept the basics. If I remove margin-top: auto from the last div, all items are aligned in the center as stated in the .menu css.
If I keep margin-top: auto from the last div, the last div is aligned where I want it but the other items are aligned at the top and not where it's supposed to.
Here's my code:
HTML
<div class="header">
<div class="one">one</div>
<div class="two">two</div>
</div>
<div class="menu">
<div class="one">one</div>
<div class="two">two</div>
<div class="three">three</div>
</div>
CSS
.header{
height:70px;
background: red;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-evenly;
}
.header .one {
background: blue;
display: flex;
align-items: center;
padding: 0.5rem 1rem;
}
.header .two {
background: green;
display: flex;
align-items: center;
padding: 0.5rem 1rem;
}
.menu {
width:70px;
height: 100vh;
background: blue;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
}
.three {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
}
.menu div:last-of-type {
margin-top: auto;
}
Here it is in action: Fiddle
Add the following and this will work. You may want to add a padding to match your header, in this case 70px.
.menu {
padding-top: 70px;
}
.menu div {
margin-top: auto;
margin-bottom: auto;
}
.menu div:last-of-type {
margin-top: auto;
margin-bottom: 0;
}

Exclude height of existing div when setting viewport height for another div

I'm working on a page that has a header nav, then two rows of banner images, then a couple more divs below the banners.
What I'd like to achieve is to have the nav div be a set height (90px) and then have the two rows of banners evenly split the remaining viewport height of the user's browser. Then, have the two divs below the banners also be fixed pixel heights.
Here's a snippet of my stripped down code:
html, body {
margin: 0;
padding: 0;
}
.nav {
background: red;
height: 90px;
display: flex;
justify-content: center;
align-items: center;
}
.banners-row-1 {
background: green;
display: flex;
justify-content: center;
align-items: center;
height: 50vh;
}
.banners-row-2 {
background: orange;
display: flex;
justify-content: center;
align-items: center;
height: 50vh;
}
.mailing-list {
height: 115px;
background: pink;
display: flex;
justify-content: center;
align-items: center;
}
.footer {
height: 117px;
background: lightblue;
display: flex;
justify-content: center;
align-items: center;
}
<div class="nav">
This is the nav
</div>
<div class="banners-row-1">
Banners Row 1
</div>
<div class="banners-row-2">
Banners Row 2
</div>
<div class="mailing-list">
Mailing List
</div>
<div class="footer">
Footer
</div>
As you can see, the two banner rows are set to 50vh, which is close to what I want - but, is there a way to somehow incorporate the 90px nav div when the banner divs calculate the viewport height?
Essentially, what I'm after is something along the lines of 50% of 'viewport height minus 90px'...?
Thanks
Wrap your nav and banners to wrapper and use following flex properties:
html, body {
margin: 0;
padding: 0;
}
.nav {
background: red;
height: 90px;
display: flex;
justify-content: center;
align-items: center;
}
.wrap {
display: flex;
flex-direction: column;
height: 100vh;
}
.ban {
flex: 1;
}
.banners-row-1 {
background: green;
display: flex;
justify-content: center;
align-items: center;
}
.banners-row-2 {
background: orange;
display: flex;
justify-content: center;
align-items: center;
}
.mailing-list {
height: 115px;
background: pink;
display: flex;
justify-content: center;
align-items: center;
}
.footer {
height: 117px;
background: lightblue;
display: flex;
justify-content: center;
align-items: center;
}
<div class="wrap">
<div class="nav">
This is the nav
</div>
<div class=" ban banners-row-1">
Banners Row 1
</div>
<div class="ban banners-row-2">
Banners Row 2
</div>
</div>
<div class="mailing-list">
Mailing List
</div>
<div class="footer">
Footer
</div>
It works, because space in .wrap is splitted like:
.nav has fixed 90px
.bans have equal left space (100vh - 90px) / 2

Container stretching with flex display

I have the following in my HTML file:
<div class="container-box">
<div class="profile-box">
<div class="image-container">
<div class="profile-picture"></div>
</div>
</div>
</div>
In my CSS file, I have the following:
.container-box {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.profile-box {
height: 350px;
width: 500px;
background-color: white;
padding: 20px;
display: flex;
flex-direction: column;
flex: 1;
}
This results in my profile-box being center-aligned, but I also want it vertically aligned. I have tried changing the flex-direction to row, but that only stretches it to take over all the horizontal space.
Here is a codepen: https://codepen.io/Humad/pen/rKLMeo
It is already centered, but your body and .container-box do not have a height set for it go in the center.
JSFiddle demo
body, html {
height: 100%; /* added */
width: 100%; /* added */
margin: 0; /* added */
}
.container-box {
height: 100%; /* added */
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: black;
}

CSS Flexbox annoying slight offset of row elements [duplicate]

This question already has answers here:
White space under image [duplicate]
(5 answers)
Remove white space from image
(3 answers)
Closed 5 years ago.
So I have two divs in a full width container that I want to give variable sizing with flexbox, but no matter what I do, there is an annoying offset at the bottom. Using margins I can come close to fixing the problem, but it's never perfect.
If you run the code snippet below and scroll to the bottom you can see it, the image and the black content container are not aligned at the bottom.
What's going on?
#container {
width: 100%;
display: inline-flex;
flex-direction: row;
}
#image-wrapper {
flex-grow: 3;
max-width: 1000px;
position: relative;
/*background-color: black;*/
}
#menu {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 50px;
background-color: #101010;
color: #fefefe;
align-items: stretch;
display: flex;
margin-bottom:7px;
}
#form {
width: 100px;
}
#image {
width: 100%;
}
<div id="container">
<div id="image-wrapper">
<img id="image" src="http://imgsv.imaging.nikon.com/lineup/lens/zoom/normalzoom/af-s_dx_18-140mmf_35-56g_ed_vr/img/sample/sample1_l.jpg"/>
</div>
<div id="menu">
<div id="form">
CONTENT<br>CONTENT<br>
</div>
</div>
</container>
There is some space below the image since the image is an inline-element and as such there is some space reserved below the (invisble) baseline that the image is aligned to vertically. To avoid that, there are two possible solutions:
1.) Apply display: block; to the image (see first snippet)
or
2.) Apply font-size: 0 to the image container (see second snippet)
#container {
width: 100%;
display: inline-flex;
flex-direction: row;
}
#image-wrapper {
flex-grow: 3;
max-width: 1000px;
position: relative;
/*background-color: black;*/
}
img {
display: block;
}
#menu {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 50px;
background-color: #101010;
color: #fefefe;
align-items: stretch;
display: flex;
}
#form {
width: 100px;
}
#image {
width: 100%;
}
<div id="container">
<div id="image-wrapper">
<img id="image" src="http://imgsv.imaging.nikon.com/lineup/lens/zoom/normalzoom/af-s_dx_18-140mmf_35-56g_ed_vr/img/sample/sample1_l.jpg" />
</div>
<div id="menu">
<div id="form">
CONTENT<br>CONTENT<br>
</div>
</div>
</div>
SECOND SOLUTION:
#container {
width: 100%;
display: inline-flex;
flex-direction: row;
}
#image-wrapper {
flex-grow: 3;
max-width: 1000px;
position: relative;
/*background-color: black;*/
font-size: 0;
}
#menu {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 50px;
background-color: #101010;
color: #fefefe;
align-items: stretch;
display: flex;
}
#form {
width: 100px;
}
#image {
width: 100%;
}
<div id="container">
<div id="image-wrapper">
<img id="image" src="http://imgsv.imaging.nikon.com/lineup/lens/zoom/normalzoom/af-s_dx_18-140mmf_35-56g_ed_vr/img/sample/sample1_l.jpg" />
</div>
<div id="menu">
<div id="form">
CONTENT<br>CONTENT<br>
</div>
</div>
</div>
#container {
width: 100%;
display: inline-flex;
flex-direction: row;
}
#image-wrapper {
flex-grow: 3;
max-width: 1000px;
position: relative;
/*background-color: black;*/
}
#menu {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 50px;
background-color: #101010;
color: #fefefe;
align-items: stretch;
display: flex;
margin-bottom:4px;
}
#form {
width: 100px;
}
#image {
width: 100%;
}
<div id="container">
<div id="image-wrapper">
<img id="image" src="http://imgsv.imaging.nikon.com/lineup/lens/zoom/normalzoom/af-s_dx_18-140mmf_35-56g_ed_vr/img/sample/sample1_l.jpg"/>
</div>
<div id="menu">
<div id="form">
CONTENT<br>CONTENT<br>
</div>
</div>
</container>
Looks like the margin is just a bit off

Aligning elements left, center and right in flexbox

I'm trying to create this top header using flexbox.
Basically I would like to center the <div class="header-title"> (Institution institution 1) on the line with the 3 other elements you see. (Institutioner, Ledere and Log ud) like you see on the image.
.nav {
background: #e1e1e1;
}
ol, ul {
list-style: none;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.header-title {
justify-content: center;
align-self: center;
display: flex;
}
.nav ul li.logout {
margin-left: auto;
}
.nav ul li a {
text-decoration: none;
padding: 0px 20px;
font-weight: 600;
}
<div class="nav mobilenav">
<div class="header-title">
Institution institution 1
</div>
<ul>
<li>Institutioner</li>
<li>
Ledere
</li>
<li class="logout">
<a class="button-dark" href="/user/logout">Log ud</a>
</li>
</ul>
</div>
Demo - JSFiddle
Use nested flex containers and flex-grow: 1.
This allows you to create three equal-width sections on the nav bar.
Then each section becomes a (nested) flex container which allows you to vertically and horizontally align the links using flex properties.
Now the left and right items are pinned to the edges of the container and the middle item is perfectly centered (even though the left and right items are different widths).
.nav {
display: flex;
height: 50px; /* optional; just for demo */
background: white;
}
.links {
flex: 1; /* shorthand for: flex-grow: 1, flex-shrink: 1, flex-basis: 0 */
display: flex;
justify-content: flex-start;
align-items: center;
border: 1px dashed red;
}
.header-title {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed red;
}
.logout {
flex: 1;
display: flex;
justify-content: flex-end;
align-items: center;
border: 1px dashed red;
}
.links a {
margin: 0 5px;
text-decoration: none;
}
<div class="nav mobilenav">
<div class="links">
Institutioner
Ledere
</div>
<div class="header-title">Institution institution 1</div>
<div class="logout"><a class="button-dark" href="/user/logout">Log ud</a></div>
</div>
jsFiddle
Use justify-content: space-between; like this:
.container {
display: flex;
justify-content: space-between;
}
<div class="container">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
Css grid will do this better than flexbox.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
}
button {
display: inline-block;
}
.short-content {
margin-left: auto;
}
<div class="grid">
<div class="long-content">
This has content that is fairly long
</div>
<button>CTA Button</button>
<div class="short-content">
Small Text
</div>
</div>
Here is a Flex solution that aligns the right and left containers while centering the middle container correctly.
.header-box {
width: 100%;
display: flex;
flex-flow: row wrap;
padding-top: 50px;
}
.left-header, .center-header, .right-header {
flex: 100px; /* adjust width if needed */
}
.header-box div:nth-of-type(1) {
text-align: left;
}
.header-box div:nth-of-type(2) {
align-self: center;
text-align: center;
}
.header-box div:nth-of-type(3) {
text-align: right;
}
<div class="header-box">
<div class="left-header">Left<br>header<br>content</div>
<div class="center-header">Center<br>header<br>content</div>
<div class="right-header">Right<br>header<br>content</div>
</div>
If you are open to changing your html, you need to put all the items in your header on the same level in the DOM.
Here's a working example
.nav {
background: #e1e1e1;
list-style: none;
display: flex;
align-items: center;
justify-content: space-between;
height: 60px;
}
.nav > div {
min-width: 0;
white-space: nowrap;
}
.header-title {
flex-basis: 80%;
text-align: center;
}
.nav div a {
text-decoration: none;
padding: 0px 20px;
font-weight: 600;
}
<div class="nav mobilenav">
<div>Institutioner</div>
<div>Ledere</div>
<div class="header-title">
Institution institution 1
</div>
<div class="logout">
<a class="button-dark" href="/user/logout">Log ud</a>
</div>
</div>