This question already has answers here:
Vertically center ul in div
(5 answers)
Closed 3 years ago.
I have this unordered list and I want to display it vertically and also make it completely centered inside the parent container. I've managed to make it display vertically and be centered on the x-axis, but not on the y-axis. "vertical-alignment: middle;" doesn't seem to do what I want.
Consider this html-code:
div {
margin: auto;
width: 90%;
height: 200px;
background-color: lightblue;
}
ul {
list-style: none;
height: 100%;
width: 100;
padding: 0;
text-align: center
}
ul li {
display: inline;
margin-right: 20px;
vertical-align: middle;
}
<div>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
</div>
To vertically align on y-axis add the below given css to ul:
display:flex;
justify-content:center;
align-items:center;
And remove width:100; from ul tag.
Demo
div {
margin: auto;
width: 90%;
height: 200px;
background-color: lightblue;
}
ul {
list-style: none;
height: 100%;
padding: 0;
display:flex; /*add this */
justify-content:center; /*add this */
align-items:center; /*add this */
text-align: center
}
ul li {
display: inline;
margin-right: 20px;
vertical-align: middle;
}
<div>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
</div>
You can use display: flex for the div and margin: auto for the ul. And remove height and width rules from ul. here's the working Fiddle
<div>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
</div>
div {
display: flex;
margin: auto;
width: 90%;
height: 200px;
background-color: lightblue;
}
ul {
margin: auto;
list-style: none;
padding: 0;
text-align: center
}
ul li {
display: inline;
margin-right: 20px;
vertical-align: middle;
}
To align vertically u can use line-height.
use line-height instead of height in div tag.
div {
margin: auto;
width: 90%;
line-height: 200px; /*change this */
background-color: lightblue;
}
div {
margin: auto;
width: 90%;
line-height: 200px;
background-color: lightblue;
}
ul {
list-style: none;
height: 100%;
padding: 0;
text-align: center
}
ul li {
display: inline;
margin-right: 20px;
vertical-align: middle;
}
<div>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
</div>
Related
I have a list which has six li elements. These by default all appear on one row.
On screen resize 540px, I want the last li item (item 6) to go onto another row, but be center aligned (so below item 3).
Unsure what I'm doing wrong here:
.container {
display: flex;
justify-content: center;
}
ul {
display: inline-block;
list-style: none;
margin: 0;
padding: 0;
line-height: 1em;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
ul li {
margin-right: .5em;
border: 1px solid #a2a4a5;
padding: 15px;
}
#media (max-width: 540px) {
ul li {
border: 1px solid blue;
align-items: center;
}
}
<div class="container">
<ul>
<li>Text 1</li>
<li>Text 2</li>
<li>Text 3</li>
<li>Text 4</li>
<li>Text 5</li>
<li>Text 6</li>
</ul>
</div>
Try to add
justify-content: center
Or
justify-content: space-between //This will look close to what you actually have in responsive mode
to your ul
There is no way to achieve it without touching to all the other flex items
You need the container to have a height of 100%, I used 100vh here for simplicity.
Your flex element also need to have a height of 100%, and because the flex-direction is row, you should use align-items: center to vertically center the content
.container {
display: flex;
height: 100vh;
justify-content: center;
}
ul {
display: inline-block;
list-style: none;
justify-content: center;
align-items: center;
margin: 0;
padding: 0;
line-height: 1em;
display: flex;
height: 100%;
flex-direction: row;
flex-wrap: wrap;
}
ul li {
margin-right: .5em;
border: 1px solid #a2a4a5;
padding: 15px;
}
#media (max-width: 540px) {
ul li {
border: 1px solid blue;
align-items: center;
}
}
<div class="container">
<ul>
<li>Text 1</li>
<li>Text 2</li>
<li>Text 3</li>
<li>Text 4</li>
<li>Text 5</li>
<li>Text 6</li>
</ul>
</div>
I have a hoverable menu as you can see in the code. However, I got a problem when I hover, which the hover content goes out of the page. When I use "position: relative" for the div(content) it is okay but then the text "Example" goes to the left, wonder how to fix.
When I use position: absolute:
When I use position: relative:
ul {
float: right;
position: relative;
}
div {
display: none;
background-color: red;
position: relative;
width: 200px;
}
ul:hover div {
display: block;
}
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
due to lack of space u'r getting this issue make width:200px; for ul
ul {
float: right;
position: relative;
width: 200px;
}
div {
display: none;
background-color: red;
position: relative;
width: 200px;
}
ul:hover div {
display: block;
}
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
You could use position absolute, and manipulate its positions setting a negative margin...
ul {
float: right;
position: relative;
}
div {
display: none;
background-color: red;
position: absolute;
width: auto;
margin-left: -26px;
}
ul:hover div {
display: block;
}
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
Erase the div, apply the width to the ul and apply the display: none and hovering to the ol.
ul {
float: right;
width: 200px;
}
ol {
display: none;
background-color: red;
}
ul:hover ol {
display: block;
}
<ul>
<li>Example</li>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</ul>
Second version: If you want everything to be floated right, apply float: right; to ul and li in the HTML structure as used before:
ul {
float: right;
}
ol {
display: none;
background-color: red;
}
li {
float: right;
clear: right;
}
ul:hover ol {
display: block;
}
<ul>
<li>Example</li>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</ul>
It's natural behavior, it will depend on header text lenght, it will set your max lenght for below text, you'll need to define a fixed width for the header element and not on child one as you did.
Example of dynamic width (natural div property as a flex container):
ul {
float: right;
position: relative;
}
div {
display: none;
background-color: red;
position: relative;
}
ul:hover div {
display: block;
}
<ul>
<li>ExampleOfMagicMenu</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
Second example, setting fixed width to the parent box, letting child/s element/s with auto-width (they will never occupy more width than parent, as they can grow in height, overriding height auto with a fixed one will cause overflow):
ul {
float: right;
position: relative;
width: 100px;
text-align: right;
list-style: none;
}
div {
display: none;
background-color: red;
position: relative;
}
ul:hover div {
display: block;
}
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
You can do it with the Flexbox without unnecessary floats and positioning.
Solution with the container as you wrote in the comment:
.container {
max-width: 960px;
margin: 0 auto;
border: 1px solid;
}
ul {
display: flex; /* displays children inline by default that's why you need to change its direction */
flex-direction: column; /* stacks children vertically */
align-items: flex-end; /* places them far right */
}
ul > div { /* modified for accuracy */
display: none;
background-color: red;
width: 200px;
}
ul li:hover + div { /* modified for accuracy since the inner div is the next element after the li */
display: block;
}
li + div:hover {display:block} /* needs to be in order to be displayed when hovering over */
<div class="container">
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
</div>
If you don't fancy the above solution then you can simply add right: 0 to the absolutely positioned div:
.container {
max-width: 960px;
margin: 0 auto;
border: 1px solid;
}
.container:after {
content: "";
display: block;
clear: both;
}
ul {
float: right;
position: relative;
}
ul > div {
display: none;
background-color: red;
position: absolute;
right: 0; /* added */
width: 200px;
}
ul:hover div {
display: block;
}
<div class="container">
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
</div>
I'm trying to create a navigation bar, a logo at the left and the links centered in the remaining space. I followed the instructions in this thread:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
and used margin:auto; for the ul in order to get it centered. This worked fine so far but when I add margin or padding anywhere inside the ul the list of links wraps. I tried box-sizing:border-box; for the ul but no success. How can I fix this?
Fiddle: http://jsfiddle.net/30sy5dmy/5/
nav img {
height: 60px;
}
nav {
display: flex;
align-items: center;
justify-content: space-between;
}
.links {
margin: auto;
}
nav ul li {
display: inline-block;
list-style: none;
margin: 0 2%;
}
<nav>
<img src="https://teststein.000webhostapp.com/Logo.png">
<ul class="links">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 2</li>
<li>Link 2</li>
</ul>
</nav>
The list items are wrapping because you're using percentage margins.
When you give the items horizontal margins of 2%, the browser calculates the length of that 2% after the size of the container has been determined. In other words, the percentages are not factored into the container width.
Therefore, when the 2% length is added to the items, the total length exceeds that of the container and wrapping occurs.
Solution #1: white-space: nowrap
One way to fix the problem is by suppressing line breaks in the container using the white-space property. This forces all items to stay on the same line, overflowing the container if necessary.
nav {
display: flex;
align-items: center;
justify-content: space-between;
border: 1px dashed black; /* for demo only */
}
nav img {
height: 60px;
}
.links {
margin: auto;
white-space: nowrap; /* NEW */
padding: 0; /* optional; remove default indentation on list elements */
border: 1px dashed red; /* for demo only */
}
nav ul li {
display: inline-block;
list-style: none;
margin: 0 2%;
}
<nav>
<img src="http://lorempixel.com/output/nature-q-c-60-60-1.jpg">
<ul class="links">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 2</li>
<li>Link 2</li>
</ul>
</nav>
Solution #2: Don't use percentage values
If you use any value other than percentages, the list items won't wrap because, unlike percentage values, they can expand the container for accommodation.
nav {
display: flex;
align-items: center;
justify-content: space-between;
border: 1px dashed black; /* for demo only */
}
nav img {
height: 60px;
}
.links {
margin: auto;
padding: 0; /* optional; remove default indentation on list elements */
border: 1px dashed red; /* for demo only */
}
nav ul li {
display: inline-block;
list-style: none;
margin: 0 1em; /* adjustment */
}
<nav>
<img src="http://lorempixel.com/output/nature-q-c-60-60-1.jpg">
<ul class="links">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 2</li>
<li>Link 2</li>
</ul>
</nav>
Solution #3: Use flexbox
An initial setting of a flex container is flex-direction: row and flex-wrap: nowrap. This means that flex items will line up horizontally and cannot wrap.
nav {
display: flex;
align-items: center;
justify-content: space-between;
border: 1px dashed black; /* for demo only */
}
nav img {
height: 60px;
}
.links {
margin: auto;
padding: 0; /* optional; remove default indentation on list elements */
border: 1px dashed red; /* for demo only */
display: flex; /* new */
}
nav ul li {
display: inline-block;
list-style: none;
margin: 0 1em; /* adjustment; avoid percentage margins on flex items;
see this post:
https://stackoverflow.com/q/36783190/3597276 */
}
<nav>
<img src="http://lorempixel.com/output/nature-q-c-60-60-1.jpg">
<ul class="links">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 2</li>
<li>Link 2</li>
</ul>
</nav>
Solution #4: Clean and Efficient Method
This solution attempts to use the least possible code to achieve the goal. Hope it helps.
nav { display: flex; align-items: center; }
nav img { height: 60px; }
a:first-of-type { margin-left: auto; }
a:last-of-type { margin-right: auto; }
a + a { margin-left: 1em; }
<nav>
<img src="http://lorempixel.com/output/nature-q-c-60-60-1.jpg">
Link 1
Link 2
Link 2
Link 2
</nav>
Simply add display: flex to the links, and then, as using percent for margins on flex items doesn't render the same cross browser, use i.e. viewport units instead.
nav img {
height: 60px;
}
nav {
display: flex;
align-items: center;
}
.links {
display: flex;
margin: auto;
}
nav ul li {
list-style: none;
margin: 0 2vw;
}
<nav>
<img src="http://lorempixel.com/output/nature-q-c-60-60-1.jpg">
<ul class="links">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 2</li>
<li>Link 2</li>
</ul>
</nav>
This question already has an answer here:
Keep one element centered between two elements of different widths in flexbox
(1 answer)
Closed 6 years ago.
For an odd number of flex items I want the middle one to be in perfect center and other items just flow around it. The middle item has fixed width, all the rest are fluid and must stick to the middle item so the paddings are fixed.
/* CSS */
.flex-holder {
display: flex;
justify-content: center;
}
.middle-item {
width: 75px;
}
<!-- HTML -->
<ul class="flex-holder">
<li>Item 1</li>
<li>Some item</li>
<li class="middle-item">Middle</li>
<li>Very long text item</li>
<li>Test</li>
</ul>
Is it actually possible with flexbox? If no, please suggest another solution.
One solution would be to use position: absolute on middle element and center it with transform: translate() but there will be overflow of elements on small window size which you can fix with media queries.
.flex-holder {
display: flex;
justify-content: space-around;
position: relative;
list-style: none;
padding: 0;
}
.middle-item {
width: 75px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
<ul class="flex-holder">
<li>Item 1</li>
<li>Some item</li>
<li class="middle-item">Middle</li>
<li>Very long text item</li>
<li>Test</li>
</ul>
Another solution that will get result close to desired result is to wrap li's left and right of middle li in ul's and set flex: 1 on them so they take equal size and set middle div always in center.
ul, .wrap {
display: flex;
justify-content: space-around;
position: relative;
list-style: none;
flex: 1;
padding: 0;
}
.middle-item {
width: 75px;
background: lightblue;
text-align: center;
}
<ul class="flex-holder">
<li class="wrap">
<ul>
<li>Item 1</li>
<li>Some item</li>
</ul>
</li>
<li class="middle-item">Middle</li>
<li class="wrap">
<ul>
<li>Very long text item</li>
<li>Test</li>
</ul>
</li>
</ul>
The simpliest way if the middle-item is in the middle (same number of items at rigth and left):
.flex-holder {
display: flex;
justify-content: center;
list-style: none;
padding:0;
}
.flex-holder li {
flex: 1;
border: 1px solid red;
}
li.middle-item {
flex: 0 0 100px;
background-color: #ccc;
}
<ul class="flex-holder">
<li>Item 1</li>
<li>Some text</li>
<li class="middle-item">Middle</li>
<li>Very long text item bla bla bla bla bla bla.</li>
<li>Test</li>
</ul>
Also you can force to the middle nesting elements. For example:
body {
background: url(http://placehold.it/1x200) no-repeat center;
}
.flex-holder {
display: flex;
list-style: none;
padding: 0;
}
.flex-holder li {
display: flex;
flex: 1;
border: 1px solid red;
justify-content: flex-end;
padding: 0 1em;
}
.flex-holder li div {
border: 1px solid green;
padding: 0 1em;
}
li.middle-item {
flex: 0 0 auto;
background-color: #ccc;
text-align: center;
justify-content: center;
}
li.middle-item ~ li {
justify-content: flex-start;
}
<ul class="flex-holder">
<li>
<div>Item 1 </div>
<div> Some item</div>
</li>
<li class="middle-item">Middle</li>
<li>
<div>
Very long text item </div>
</li>
</ul>
I am trying to build CSS nav bar but i am in a bit trouble. In my code, background box is collapsing with content inside it .My question is why it is collapsing and can it be solved by not giving height to the box.Here is my code.
HTML
<div class="item">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
CSS
body {
color: #648;
}
.item ul {
list-style: none;
padding: 0;
margin: 0;
}
* {
}
.item {
padding: 20px;
width: 70%;
/* height: 65px; */
background-color: blanchedalmond;
margin: 50px auto;
border-radius: 10px;
}
.item li {
float: left;
width: 45px;
margin: 10px;
border-radius: 10px;
padding: 20px;
background-color: aqua;
}
Use display:inline or display:inline-block instead of float:left.
http://jsfiddle.net/x2ubrrh3/
Update
When display:flex is used you have to stop the elements from floating afer your list is finished (clear:both)
See here: http://jsfiddle.net/x2ubrrh3/1/