Aligning elements left, center and right in flexbox - html

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>

Related

Remove spaces between items in div

I have problem with my CSS of navigation bar. I want to align items to the center of purple div, but there are spaces between texts. How I can achieve alignment without these spaces?
Screen:
Code:
<div class="navbar">
<h1 class="logo">ab</h1>
<p class="items">O nás</p>
<p class="items">Reference</p>
<p class="items">Blog</p>
</div>
<style>
.navbar{
margin: 30px;
padding: 10px;
height: 100px;
background: red;
display: flex;
}
.navbar .logo{
font-size: 50px;
}
.navbar .items{
float: left;
display: flex;
flex-grow: 1;
justify-content:center;
background: blueviolet;
align-items: center;
}
</style>
The flex-box always takes as much space as it needs to fill the box.
All your p.items are flex and the covered div is also flex.
The p has flex-grow: 1 so they will have the same width inside the covered div.
The solution to this problem is create another div to cover all your items and remove display: flex and flex-grow: 1 from your items class, so the spaces between your text will be removed.
<div class="navbar">
<h1 class="logo">ab</h1>
<div class="d-flex">
<p class="items">O nás</p>
<p class="items">Reference</p>
<p class="items">Blog</p>
</div>
</div>
<style>
.navbar{
margin: 30px;
padding: 10px;
height: 100px;
background: red;
display: flex;
}
.navbar .logo{
font-size: 50px;
}
.navbar .d-flex {
display: flex;
flex-grow: 1;
background: blueviolet;
justify-content: center;
align-items: center;
}
.navbar .items{
margin: 0 10px;
}
</style>

How to place an item under another item using flxbox?

I have a JS fiddle here and it's pretty simple what I want to happen but difficult for me to execute it. In the fiddle, you notice there is a red box. I want that red box to be displayed under the text "Join Balance...". I am not sure how to do this.
Can somebody help me?
Fiddle: https://jsfiddle.net/f2h390wc/
HTML and CSS:
/* newsletter section */
#custom_html-5 {
width: 100%;
background-color: #f2f2f2;
padding-bottom: 40px;
padding-top: 20px;
margin-bottom: 70px;
padding-left: 70px !important;
padding-right: 20px !important;
}
.newsletter_inner_section {
display: flex;
}
.newsletter_gif {
width: 200px;
height: auto;
}
.newsletter_left,
.newsletter_center,
.newsletter_right {
display: inline-flex;
}
.newsletter_left {
width: auto;
}
.newsletter_center {
width: 100%;
align-items: center;
}
.newsletter_right {
background: red;
width: 40%;
justify-content: flex-end;
}
.newsletter_text_section {
color: black !important;
font-size: 24px !important;
font-weight: bold;
}
.eVEmvD.eVEmvD.eVEmvD.eVEmvD.eVEmvD.eVEmvD {
width: fit-content !important;
padding: 0 20px;
}
.fGCWnQ.fGCWnQ {
justify-content: flex-end;
}
.kvTDNe.kvTDNe {
display: unset;
}
/* Media Newsletter section only */
#media (max-width:1144px) {
#custom_html-5 {
padding-left: 20px !important;
padding-right: 20px !important;
}
.newsletter_inner_section {
width: 100% !important;
justify-content: center;
display: flex;
}
.newsletter_center,
.newsltter_right {
flex-direction: column !important;
}
}
<!-- newsletter section -->
<div class="newsletter_section">
<div class="newsletter_inner_section">
<div class="newsletter_left">
<img src="https://balancecoffee.co.uk/wp-content/themes/balancecoffeechild/img/newsletternnobkg2.gif" alt="Balance Newsletter" style="padding-right:30px;" class="newsletter_gif">
</div>
<div class="newsletter_center">
<p class="newsletter_text_section">Join Balance and get 20% off your first order</p>
</div>
<div class="newsletter_right">
<div class="newsletter_input_section">
<div class="klaviyo-form-Rrsqsh"></div>
</div>
</div>
</div>
</div>
If you want the text and the red box on the right to form a column, then they both need to be in a flexbox with flex-direction: column;.
I created a sample from scratch because there is a lot of superfluous stuff in your JSFiddle.
.group {
display: flex;
flex-direction: row;
width: 100%;
}
.content-box {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
padding: 40px;
}
.left {
background-color: blue;
}
.right {
flex-grow: 1;
display: flex;
flex-direction: column;
}
.top-right {
background-color: green;
}
.bottom-right {
background-color: red;
}
<div class='group'>
<div class='left content-box'>
Content
</div>
<div class='right'>
<div class='top-right content-box'>
Content
</div>
<div class='bottom-right content-box'>
Content
</div>
</div>
</div>
https://www.w3schools.com/cssref/css3_pr_flex-direction.asp
display: flex;
flex-direction: column;

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

how to text-align: center with this flex schema?

Is this scenario doable with flex? Cause I can't text-align:center item2 (full width).
<div class="container">
<div class="item1"></div>
<div class="item2"></div>
</div>
EDIT:
I did change the image cause container color was white (as page background)...
You can make both item1 and item2 as display:flex and make justify-content:center and align-items:center that would center the content on those divs
check the snippet
.container {
display: flex;
}
.container div {
background: black;
color: red;
}
.item1 {
width: 50px;
height: 50px;
align-items: center;
display: flex;
justify-content: center;
}
.item2 {
margin-left: 10px;
width: 100%;
height: 70px;
align-items: center;
display: flex;
justify-content: center;
}
<div class="container">
<div class="item1">text</div>
<div class="item2">text</div>
</div>
hope it helps
Here's an example using flex: grow; for .item1 and .item2
CSS:
.container {
display: flex;
flex-wrap: wrap-reverse;
width: 700px;
background-color: black;
padding:33px;
vertical-align:middle;
}
.item1 {
flex-grow: 1;
background: yellowgreen;
height:200px;
margin: 15px;
text-align: center;
display: flex;
align-items: center;
justify-content: center
}
.item2 {
flex-grow: 2;
background: aquamarine;
height:200px;
margin: 15px;
display: inline-block;
text-align: center;
display: flex;
align-items: center;
justify-content: center
}
HTML
<div class="container">
<div class="item1">text</div>
<div class="item2">text</div>
</div>
JSFiddle