CSS flexbox centering [duplicate] - html

This question already has answers here:
Keep the middle item centered when side items have different widths
(12 answers)
Closed 2 years ago.
I have the following code snippet (only HTML and CSS)
.container {
display: flex;
justify-content: space-between;
border: 1px solid black;
}
nav ul {
display: flex;
flex-direction: row;
justify-content: center;
padding: 0;
}
nav ul li {
list-style: none;
padding: 0 5px;
}
<div class="container">
<nav class="menu1">
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</nav>
<nav class="menu2">
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
<li>2.4</li>
<li>2.5</li>
<li>2.6</li>
<li>2.7</li>
<li>2.8</li>
<li>2.9</li>
</ul>
</nav>
<nav class="menu3">
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
<li>3.4</li>
<li>3.5</li>
<li>3.6</li>
<li>3.7</li>
<li>3.8</li>
<li>3.9</li>
</ul>
</nav>
</div>
As you notice, the middle menu (the nav with class .menu2) is equally spaced between .menu1 and .menu3 because of the CSS property justify-content: space-between; in .container. This is correct.
What I need however, is to make sure that .menu2 is in the center of .container. In other words, it will NOT be equally spaced between .menu1 and .menu3. I want it dead center inside .container (and do not worry about menu items overlapping; I will have less menu items in each menu, so they will not overlap. I just added a lot of them here to demonstrate the spacing issue). Also, .menu1 should be also left aligned, and .menu3 should be right aligned (as they are right now).
How do I do that?
Thanks.

it seems like a grid would be better than a flex in my opinion.
you can then change the initial and last ul to display: inline-flex
then, for the last ul to be aligned to the end, you add to its nav element (class='menu3') a property text-align=end
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
border: 1px solid black;
}
nav ul {
display: flex;
flex-direction: row;
justify-content: center;
padding: 0;
}
.menu1 ul{
display: inline-flex;
}
.menu3{
text-align: end;
}
.menu3 ul{
display: inline-flex;
}
nav ul li {
list-style: none;
padding: 0 5px;
}

Do you have to use flex? Otherwise it is possible to move menu 2 to the center with position absolute.
.container {
display: flex;
justify-content: space-between;
border: 1px solid black;
position: relative;
}
nav ul {
display: flex;
flex-direction: row;
justify-content: center;
padding: 0;
}
nav ul li {
list-style: none;
padding: 0 5px;
}
.menu2 {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
<html>
<body>
<div class="container">
<nav class="menu1">
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</nav>
<nav class="menu2">
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
<li>2.4</li>
<li>2.5</li>
<li>2.6</li>
<li>2.7</li>
<li>2.8</li>
<li>2.9</li>
</ul>
</nav>
<nav class="menu3">
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
<li>3.4</li>
<li>3.5</li>
<li>3.6</li>
<li>3.7</li>
<li>3.8</li>
<li>3.9</li>
</ul>
</nav>
</div>
</body>
</html>

I know it is not Flexbox but you may want to look at CSS grid-layout.
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
border: 1px solid black;
}
nav ul {
padding: 0;
}
nav ul li {
display: inline-block;
list-style: none;
padding: 0 5px;
}
<html>
<body>
<div class="container">
<nav class="menu1">
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</nav>
<nav class="menu2">
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
<li>2.5</li>
<li>2.9</li>
</ul>
</nav>
<nav class="menu3">
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
<li>3.4</li>
<li>3.5</li>
<li>3.6</li>
<li>3.7</li>
<li>3.8</li>
<li>3.9</li>
</ul>
</nav>
</div>
</body>
</html>

I would set the .menu1-3 to different flex rules, having those on the outside trying to talk equally much of the space while the one in the middle takes just what it needs.
The overflow: hidden is important to make sure content doesnt over-span the flex-base. But there are other rules with same effect depending on what behaviour of the items you want (like flex-wrap to wrap the items to the next line)
Depending on what you want you can consider giving the middle column a specific flex-base like fixed pixel or percentage (like all 3 .menu get 33.33%). Add margin (to middle column) as well if needed.
The solution with grid and the absolute positions might also do the job depending on that you want. Position: absolute has the best browser support, my flex solution works on most browsers these days. Grid also should but has the worst coverage as far as i know
.container {
display: flex;
justify-content: space-between;
border: 1px solid black;
}
nav ul {
display: flex;
flex-direction: row;
justify-content: center;
padding: 0;
}
nav ul li {
list-style: none;
padding: 0 5px;
}
.menu1, .menu3 {
flex: 1 1 50%;
overflow: hidden;
}
.menu1 ul {
justify-content: flex-start
}
.menu2 ul {
justify-content: flex-end
}
.menu2 {
flex: 0 0 auto;
}
<html>
<body>
<div class="container">
<nav class="menu1">
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</nav>
<nav class="menu2">
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
<li>2.4</li>
<li>2.5</li>
<li>2.6</li>
<li>2.7</li>
<li>2.8</li>
<li>2.9</li>
</ul>
</nav>
<nav class="menu3">
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
<li>3.4</li>
<li>3.5</li>
<li>3.6</li>
<li>3.7</li>
<li>3.8</li>
<li>3.9</li>
</ul>
</nav>
</div>
</body>
</html>

Related

How do I center a UL/LI in the same row as left-aligned text?

I've been trying to write a menubar that has two groupings in the same row across the top of a webpage: on the left is the site name and in the center should be the menu options (a ul/li). So far, following similar issues, I've written the following, which appears on first glance to do exactly what I'm seeking.
HTML:
<div class="menubar">
SITE NAME
<ul class="ul">
<li>MENU 0</li>
<li>MENU 1</li>
<li>MENU 2</li>
<li>MENU 3</li>
</ul>
</div>
CSS:
.menubar {
width: 100%;
height: 50px;
line-height: 50px;
vertical-align: middle;
background-color: #fff;
border-bottom: 1px solid #f5f5f5;
position: fixed;
top: 0;
display: flex;
flex-flow: row nowrap;
}
.logo {
width: 33.33%;
float: left;
margin-left: 20px;
font-size: 24px;
}
.ul {
font-size: 18px;
list-style: none;
padding: 0;
margin: 0;
}
.ul li {
margin-left: 15px;
margin-right: 15px;
display: inline-block;
}
However, if you look carefully in the JSFiddle (more apparent when widening browser windows or shrinking the window down just before the items begin wrapping), the 'centered' ul/li is not actually centered—it's closer to the left side of the browser window than the right. How do I fix this so that the ul/li remains truly centered in the menubar (as if the site name doesn't exist) with the left-aligned site name, regardless of what the browser window's width is? (I'm assuming within non-wrapping reason, since I plan to adjust sizes and behavior for smaller devices.)
JSFiddle
You're using a lot of margins, width and stuff. Check out flex here and you can get the same thing, properly aligned using flex and directions.
<!-- NEW CODE -->
<nav>
<div class="logo">
<span>Your Company</span>
</div>
<ul class="nav-items">
<li class="nav-item"> Menu 1 </li>
<li class="nav-item"> Menu 2 </li>
<li class="nav-item"> Menu 3 </li>
<li class="nav-item"> Menu 4 </li>
</ul>
</nav>
<!-- OLD CODE -->
<nav>
<div class="logo">
<img src="https://placehold.it/200x200" alt="logo">
</div>
<div class="menu-items">
<div class="menu-item"> Menu 0 </div>
<div class="menu-item"> Menu 1 </div>
<div class="menu-item"> Menu 2 </div>
<div class="menu-item"> Menu 3 </div>
</div>
</nav>
and the css
// MORE PROPERTIES
nav {
align-items: center;
}
nav div.logo {
position: absolute;
}
// OLD-NEW CSS
nav {
display: flex;
border: 1px solid pink;
}
nav div.logo {
border: 1px solid green;
display: flex;
align-items: center;
}
nav div.logo span {
padding: 0 0.5rem;
}
ul.nav-items {
border: 1px solid red;
display: flex;
flex-direction: row;
list-style-type: none;
margin: 0 auto;
padding: 0;
}
ul.nav-items li {
margin: 0 0.25rem;
padding: 0.5rem;
border: 1px solid blue;
}
// OLD CSS
nav {
display: flex;
}
nav div.menu-items {
display: flex;
flex-direction: row;
margin: 0 auto;
}
nav div.menu-items div.menu-item {
margin-left: 0.25rem;
margin-right: 0.25rem;
}
Fiddle:
NEW: https://jsfiddle.net/vzgn0Lju/1/
OLD: https://jsfiddle.net/kp9nsmah/1/
I added some margins between menu options and you can tweak a little bit more but flex is way easier than using lists and lots of things. You could use spans instead of div.menu items, can remove the container for items and such. But the general idea is there.

Align image to left and navbar to right

I need to have image on left side and navbar on right side... but the navbar must be vertically centered with image.. On jsfiddle I made it up to set navbar vertically to center but I am not able to put it on the right side... I will be glad for any help.
JSFiddle: https://jsfiddle.net/polluxik/0Lqubpe6/20/
ul {
display: flex;
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
align-items: center;
}
ul img {
height: 100px;
}
li a {
display: block;
color: #262353;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
<ul>
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Google_Images_2015_logo.svg/640px-Google_Images_2015_logo.svg.png">
<li><a class="active" href="#">test</a></li>
<li>test2</li>
<li>test3</li>
<li>test4</li>
</ul>
*in jsfiddle I used random image from google as a placeholder
One approach is below, with corrected HTML (the only valid child of a <ul> or <ol> is an <li>, so the <img> is now appropriately wrapped):
ul {
display: flex;
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
align-items: center;
/* aligning the content of the <ul> to the end
of the inline axis: */
justify-content: end;
}
ul img {
height: 100px;
}
li a {
display: block;
color: #262353;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li:first-child {
/* setting the margin of the inline-end of the
first-child <li> element to 'auto', in order
to push the first-child away from the rest of
the content: */
margin-inline-end: auto;
}
<ul>
<!-- wrapped the <img> in another <li> element for validity: -->
<li><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Google_Images_2015_logo.svg/640px-Google_Images_2015_logo.svg.png"></li>
<li><a class="active" href="#">test</a></li>
<li>test2</li>
<li>test3</li>
<li>test4</li>
</ul>
JS Fiddle demo.
References:
justify-content.
margin-inline-end.
We can define the image and navbar items in different div and then using flexbox we can align the two div horizontally using justify-content:space-between.
ul {
display: flex;
justify-content: space-between;
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
align-items: center;
}
.nav {
display: flex;
gap: 10px;
}
ul img {
height: 50px;
}
<ul>
<div class='logo'>
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Google_Images_2015_logo.svg/640px-Google_Images_2015_logo.svg.png">
</div>
<div class='nav'>
<li><a class="active" href="#">test</a></li>
<li>test2</li>
<li>test3</li>
<li>test4</li>
</div>
</ul>

How to arrange the list in my navbar horizontally?

I am fairly new to css and while working on a project I couldn't get the Inline-block code to work, and I cant understand why. I want to arrange the links in my navbar menu horizontally rather than vertically.
<nav class="navbar">
<div class="max-width">
<div class="logo">Roulathul <span>Uloom.</span></div>
<ul class="menu">
<li>Home</li>
<li>About</li>
<li>Services</li>
<li>Skills</li>
<li>Teams</li>
<li>Contact</li>
</ul>
</div>
</nav>
This is my navbar HTML code.
.navbar .menu .li{
list-style: none;
display: inline-block;
}
And this is where I used the inline block. Any Tips?
Use:
.menu {
display: flex;
}
This is how I mainly center my navbars, just use the display: flex and justify-content: to either space out the elements or center them.
More info on the flex property
.menu{
list-style: none;
display: flex;
justify-content: space-evenly;
}
I added padding for space and removed the default list styling, hope this helps:-
.navbar {
display: flex;
align-items: center;
top: 0px;
}
.navbar ul {
display: flex;
}
.navbar ul li {
list-style: none;
}
.navbar ul li a {
display: block;
padding: 5px 22px;
text-decoration: none;
}
<nav class="navbar">
<div class="logo">
<a href="#">Roulathul <span>Uloom.</span>
</a>
</div>
<ul>
<li class="item">About</li>
<li class="item">Services</li>
<li class="item">Skills</li>
<li class="item">Teams</li>
<li class="item">Contacts</li>
</ul>
</nav>

css html ul menu with separator aligned with the container

for now i have generated the menu in this way:
nav{
width:1024px;
margin: 0 auto;
}
ul{
display: flex;
justify-content: space-between;
}
li {
border-right: 1.1px solid #333333;
margin: 0 auto;
padding: 0 1em;
text-align: center;
flex-grow: 1;
flex-basis: initial;
text-align: center;
}
the html is:
<nav id="menu">
<ul>
<li>Home</li>
<li>Training & Support</li>
<li>Templates & Forms</li>
<li>Policy Documents</li>
<li>Payment Administration</li>
<li>Tax Compliance</li>
<li>News</li>
</ul>
</nav>
The result is:
But i want that the first and last child are aligned at the start and at the end of the ul container like in the image below
How can i do this?
Have you tried removing text-align: centre; ???Or in li try something like padding-right: 0;Tell me how it works out.

How to evenly space <li> item in a nav bar using Flexbox? HTML

I'm trying to create a simple nav bar for a portfolio site. My HTML and CSS is below. I can not figure out how to evenly space the '''li''' item evenly. I can't apply justifiy-content:space-evenly to the UL because the same code is being applied to the '''div class="headerContainer'''
.headerContainer {
display: flex;
background-color: lightblue;
justify-content: space-between;
align-items: center;
}
ul {
list-style-type: none;
display: flex;
}
li a {
text-decoration: none;
}
<header>
<div class="headerContainer">
<div class="logo">Robert Emmet</div>
<nav>
<ul>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
</nav>
</div>
</header>
.headerContainer {
display: flex;
background-color: lightblue;
justify-content: space-between;
align-items: center;
}
ul {
list-style-type: none;
display: flex;
width: 100%;
justify-content: space-evenly;
}
nav {
width: 100%;
}
<header>
<div class="headerContainer">
<div class="logo">Robert Emmet</div>
<nav>
<ul>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
</nav>
</div>
</header>