'How to align one flex child as flex-start and other in center?
I have a sidebar that is set to flex with direction column. I am trying to get my menu ul
to be vertically centered, and my .logo-container
to be on the top of the page.
Is there any way to get one child to flex-start and another one centered?
Code:
<aside class="side-bar">
<nav class="navigation">
<div class="logo-container">
<a href="index.html" class="link">
<img src="http://unsplash.it/30/30" class="logoimg" alt="">
<h6 class="logoname">My<span class="lastname">Name</span></h6>
</a>
</div>
<ul class="nav-list">
<li class="item"><a href="#" class="link">Menuitem1</a></li>
<li class="item"><a href="#" class="link">Menuitem2</a></li>
<li class="item"><a href="#" class="link">Menuitem3</a></li>
<li class="item"><a href="#" class="link">Menuitem4</a></li>
</ul>
</nav>
</aside>
CSS:
html {
box-sizing: border-box;
}
* {
margin: 0;
padding: 0;
}
.side-bar {
width: 35%;
height: 100vh;
background-color: blue;
}
.navigation {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
}
.logoname {
display: inline-block;
}
* {
color: black;
}
ul {
list-style: none;
}
Many thanks!
Solution 1:[1]
What you can do is to create an empty/invisible element as a third flex item inside the flex parent (in my example below it's the div
with class xxx
) and apply justify-content: space-between
to the flex parent (instead of center
).
Depending on your actual code and content you should make sure that that additional element has the same height as the nav
element (30px in your and my example). And again, depending on the situation you might want to add visibility: hidden;
to the additional element (xxx
) to make it invisible but still have its height included in the flex
position calculations:
html {
box-sizing: border-box;
}
* {
margin: 0;
padding: 0;
}
.side-bar {
width: 35%;
height: 100vh;
background-color: blue;
}
.navigation {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
height: 100%;
}
.logoname {
display: inline-block;
}
* {
color: black;
}
ul {
list-style: none;
}
.xxx {
height: 30px;
visibility: hidden;
}
<aside class="side-bar">
<nav class="navigation">
<div class="logo-container">
<a href="index.html" class="link">
<img src="http://unsplash.it/30/30" class="logoimg" alt="">
<h6 class="logoname">My<span class="lastname">Name</span></h6>
</a>
</div>
<ul class="nav-list">
<li class="item"><a href="#" class="link">Menuitem1</a></li>
<li class="item"><a href="#" class="link">Menuitem2</a></li>
<li class="item"><a href="#" class="link">Menuitem3</a></li>
<li class="item"><a href="#" class="link">Menuitem4</a></li>
</ul>
<div class="xxx"></div>
</nav>
</aside>
Solution 2:[2]
You can try this approach.
html {
box-sizing: border-box;
}
* {
margin: 0;
padding: 0;
}
.side-bar {
width: 35%;
height: 100vh;
background-color: blue;
}
.navigation {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
}
* {
color: black;
}
ul {
list-style: none;
}
.logo-container {
display:grid;
justify-content:space-around;
margin:0 auto;
padding-top: 20px;
}
.logo-container img {
text-align:center;
padding:5px;
}
<aside class="side-bar">
<div class="logo-container">
<a href="index.html" class="link">
<img src="http://unsplash.it/30/30" class="logoimg" alt="">
<h6 class="logoname">My<span class="lastname">Name</span></h6>
</a>
</div>
<nav class="navigation">
<ul class="nav-list">
<li class="item"><a href="#" class="link">Menuitem1</a></li>
<li class="item"><a href="#" class="link">Menuitem2</a></li>
<li class="item"><a href="#" class="link">Menuitem3</a></li>
<li class="item"><a href="#" class="link">Menuitem4</a></li>
</ul>
</nav>
</aside>
Solution 3:[3]
All you have to do is to have the logo and ul in separate divs within the parent div that has the column direction styling, apply flex-shrink:0 to the div containing the logo and flex-grow: 1 to the other div.
That will allow the logo to be at the top and the other div to take the rest of the space - then you can apply flex styling in the navigation -container to center the ul within that div.
UPDATE - the OP wanted the ul centered into the height of the viewport - as noted in the comments this is as simple as offsetting the position of the ul in the bottom div by half the height of the top div - so in this case - moving it up by 20px) because the top div is 40px in height. This allows centering of the ul into the viewport height without resorting to adding empty divs just to get the alignment.
html {
box-sizing: border-box;
color: white;
}
* {
margin: 0;
padding: 0;
}
.side-bar {
width: 35%;
height: 100vh;
background-color: blue;
padding: 8px;
}
.navigation {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
align-items: center;
}
.logo-container {
flex-shrink:0
}
.logoname {
display: inline-block;
padding : 8px;
color: lime;
}
.navigation-container {
flex-grow:1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
ul {
list-style: none;
position: relative;
top: -20px
}
li a{ color: white; }
<aside class="side-bar">
<nav class="navigation">
<div class="logo-container">
<a href="index.html" class="link">
<img src="http://unsplash.it/30/30" class="logoimg" alt="">
<h6 class="logoname">My<span class="lastname">Name</span></h6>
</a>
</div>
<div class="navigation-container">
<ul class="nav-list">
<li class="item"><a href="#" class="link">Menuitem1</a></li>
<li class="item"><a href="#" class="link">Menuitem2</a></li>
<li class="item"><a href="#" class="link">Menuitem3</a></li>
<li class="item"><a href="#" class="link">Menuitem4</a></li>
</ul>
</div>
</nav>
</aside>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Johannes |
Solution 2 | Crystal |
Solution 3 |