align horizontal list evenly (and responsive) - html

i know there are serveral ways to justify a horizontal list. but not like in my screendesign:
you see my result on top and below the screendesign. any ideas how to improve the space between the items to have them more evenly? (2nd and 3rd item is to long)
this is my code:
.navi {
text-align: center;
display: table;
width: 100%;
ul {
display:table-row;
}
li {
display:table-cell;
a {
display: block;
border: 1px solid #000;
}
}
}

While this is solved by Flexbox, you can still use CSS Tables - for the sake of browser support - to achieve the desired result:
.navi {
text-align: center;
display: table;
width: 100%;
}
.navi ul { display: table-row; }
.navi li { display: table-cell; width: 20%; }
.navi li a { display: block; border: 1px solid #000; }
<div class="navi">
<ul>
<li>Link No.1</li>
<li>Link No.2 has much text</li>
<li>Link No.3 has much more text</li>
<li>Link No.4</li>
<li>Link No.5</li>
</ul>
</div>
In order to keep text in one line, then you could give white-space: nowrap to the table-cells as follows:
.navi { text-align: center; display: table; width: 100%; }
.navi ul { display: table-row; }
.navi li { display: table-cell; width: 20%; white-space: nowrap; }
.navi li a { display: block; border: 1px solid #000; }
<div class="navi">
<ul>
<li>Link No.1</li>
<li>Link No.2 has much text</li>
<li>Link No.3 has much more text</li>
<li>Link No.4</li>
<li>Link No.5</li>
</ul>
</div>

I like the use of the table, table-row and table-cell method. In my example I have 2 links that need to be horizontally aligned but I wanted some space between them. I added an empty item between the links to create a spacer. Then added css to style only the odd cells.
<div class="aff">
<ul class="buttons">
<li>Link1</li>
<li> </li>
<li>Link 2</li>
</ul>
</div>
.aff {display:table; text-align:center; width:100%; box-sizing:border-box;}
.aff ul.buttons {display:table-row;list-style-type:none; margin:0; padding:0;}
.aff ul.buttons li:nth-child(odd) {display:table-cell; width:47%; background:#acacac; padding:10px; border-radius:.44em}
.aff ul.buttons li a {display:block; line-height:45px; font-size:1.2em; text-decoration:none; font-weight:bold;}
.aff ul.buttons li a:hover {text-decoration:underline;}

Related

Hoverable menu goes out of page

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>

Get a UL to be centered and have two li's per row

I'm trying to show a UL with two LI's per row and have all of the text centered. So far the LI's simply go to the left side of the UL.
ul {
text-align: center;
list-style-type: none;
width: 100%;
}
ul li {
display: inline;
}
ul li:nth-child(2n+1) {
clear: both;
}
<ul style="">
<li>item
</li>
<li>item
</li>
<li>item
</li>
<li>item
</li>
</ul>
You need to float the lis (and not make them inline), and clear the left of odd lis
ul
{
list-style:none;
text-align: center;
}
ul li
{
float: left;
}
ul li:nth-child(2n+1) { /*or ul li:nth-child(odd)*/
clear: left;
}
https://jsfiddle.net/nivas/yyt46dkL/
* {
margin: 0;
padding: 0;
}
body {
text-align: center;
}
ul {
display: inline-block;
list-style-type: none;
overflow: hidden;
}
li {
width: 50%;
float: left;
}
a {
display: block;
border: 1px solid;
margin: .25em;
}
a:hover {
background-color: silver;
}
a:link, a:visited, a:hover, a:active {
text-decoration: none;
}
<ul>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
<li>Forth item</li>
</ul>
Figured it out.
ul {
text-align: center;
list-style-type: none;
width: 100%;
}
ul li {
display: inline;
}
ul li:nth-child(2n+1) {
clear: both;
}
ul li:nth-child(2n+1)::before{
display: block;
content: ' ';
}
<ul style="">
<li>item
</li>
<li>item
</li>
<li>item
</li>
<li>item
</li>
</ul>

Align spans of a list

I have this:
http://jsfiddle.net/Lehqyf1t
<ul class="myclass">
<li><span style="background-color:#f608ff"></span>Text 1</li>
<li><span style="background-color:#f608ff"></span>Text 2</li>
</ul>
css:
.myclass li span {
width: 25px;
height: 25px;
display: block;
float: left;
margin-right: 10px;
}
No matter what I try I cannot get both lines to be aligned properly. How could I solve it?
You have to clear the float in <li>.
http://jsfiddle.net/Lehqyf1t/2/
You can swap out the float for display:inline-block and then you don't have to worry about clearing floats at all.
li {
list-style:none;
}
.myclass li span{
width: 25px;
height: 25px;
display: inline-block;
vertical-align: middle;
margin-right: 10px;
background-color:#f608ff;
}
<ul class="myclass">
<li><span></span>Text 1</li>
<li><span></span>Text 2</li>
</ul>

How can I expand li elements to container size?

I have the following HTML:
#main-menu {
background-color: blue;
border: 1px solid black;
width: 600px;
}
.menu {
list-style: none outside none;
text-align: center;
}
.menu-item {
float: left;
}
.menu-item a {
border: 1px solid red;
}
<div id="main-menu">
<ul class="menu">
<li class="menu-item">Item #1</li>
<li class="menu-item">Item #2</li>
<li class="menu-item">Item #3</li>
<li class="menu-item">Item #4</li>
</ul>
</div>
How do I make the li elements automatically expand euqally to the fixed width of the container?
Thanks in advance! :-)
CodePen link: http://codepen.io/anon/pen/JoKgXz
I've updated you codepen codes..
CSS
#main-menu {
background-color: blue;
border: 1px solid black;
width: 600px;
overflow: hidden;
}
ul, li{
margin:0;
padding:0;
}
.menu {
list-style: none outside none;
text-align: center;
}
.menu-item {
float: left;
width:25%;
}
.menu-item a {
border: 1px solid red;
}
Demo
Ensure you have a proper CSS reset and use the box-sizing:border-box property.
This option has the virtue of not requiring set widths on the li
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main-menu {
background-color: blue;
border: 1px solid black;
width: 600px;
}
.menu {
list-style: none outside none;
text-align: center;
display: table;
width: 100%;
}
.menu-item {
display: table-cell;
}
.menu-item a {
border: 1px solid red;
color: white;
display: block;
}
<div id="main-menu">
<ul class="menu">
<li class="menu-item">Item #1
</li>
<li class="menu-item">Item #2
</li>
<li class="menu-item">Item #3
</li>
<li class="menu-item">Item #4
</li>
</ul>
</d
First remove all margin and padding from the .menu. As you have four items in the menu, add width: 25% to the .menu-item. I've added a display: block to the <a> tag to make it fill the entire width of the .menu-item. As you use float: left the menu-items won't make the .menu container grow. The .menu:after adds a clearfix to have the menu contain all menu items.
Instead of float: left you could also have opted for a display: inline-block. In this case the clearfix wouldn't be necessary, but you need to make sure that the menu items don't have any whitespace (e.g. a newline) between them. Put them on one line like ...</li><li>... otherwise there will be some space between the menu items.
If you need some padding on the menu item make sure to add box-sizing: border-box as otherwise the width will refer to the content only. This means that after adding the padding the menu item will take up more than 25% of the width, which makes the last menu item wrap to a new line.
#main-menu {
background-color: blue;
border: 1px solid black;
width: 600px;
}
.menu {
list-style: none;
text-align: center;
margin: 0;
padding: 0;
}
.menu:after {
content: '';
display: block;
clear:both;
}
.menu-item {
float: left;
width: 25%;
}
.menu-item a {
display: block;
border: 1px solid red;
}
<div id="main-menu">
<ul class="menu">
<li class="menu-item">Item #1</li>
<li class="menu-item">Item #2</li>
<li class="menu-item">Item #3</li>
<li class="menu-item">Item #4</li>
</ul>
</div>

Make secondary navigation stay in place when primary category is hovered using only CSS

I'm trying to create a navigation panel where you hover over the category you want and the list of pages for that category appears underneath, horizontally. I have the main bulk of it down but I don't know how to make the list of pages (secondary navigation part) stay in place after a category has been hovered over without using Javascript.
I'm developing using an old version of Firefox (10.0.1) due to work limitations.
Here is what I have:
<style>
body,a,ul,li{margin:0;padding:0;text-decoration: none}
*{font-family: verdana;font-size: 12px;color:#333;}
#nav{
margin-left: 20px;
width: 400px;
height: 50px;
}
#nav:after{
position: absolute;
content: "";
width: 400px;
height: 30px;
background: #888;
z-index: 0;
}
#nav > ul{
position: relative;
}
#nav > ul:before{
content: "";
display: table-cell;
width: 100%;
}
#nav > ul > li{
background: #ccc;
height: 50px;
display: table-cell;
white-space: nowrap;
vertical-align: middle;
padding: 0 15px 0 15px;
}
#nav > ul > li > ul{
background: #bbb;
position: absolute;
left: 0;
display: table-cell;
height: 30px;
bottom: -30px;
z-index: 1;
}
#nav > ul > li > ul > li{
background: #aaa;
display: none;
height: 30px;
padding: 0 10px 0 10px;
vertical-align: middle;
}
#nav > ul > li:hover > ul > li{
display: table-cell;
}
</style>
<div id="nav">
<ul>
<li>Cat 1
<ul>
<li>Link 1</li>
<li>Link 2</li>
</ul>
</li>
<li>Cat 2</li>
<li>Cat 3
<ul>
<li>Link 3</li>
<li>Link 4</li>
<li>Link 5</li>
</ul>
</li>
</ul>
</div>
JsFiddle Link
I found a solution:
#nav > ul > li:hover > ul:after{
display: table-cell;
content: "";
width: 1000px;
}
This fills up the remaining whitespace in the second ul which makes it stay active when the cursor is over it.