Link to wrap around li with padding - html

I have an unordered list with a lot of list items. Some of the list items are links, some are not. I want to add padding to the list items so the appearance is consistent regardless of whether it is a link or not, i.e. I do not want to add padding to the anchor, but to the list and for the anchor to wrap around the link AND padding.
Despite using display:block on hover the background color is only around the text inside the link. It ignores the padding. Is there a way to get the link to include the padding (without putting padding on the link)?
ul li {
float: left;
line-height: 5em;
padding: 0 2em;
}
a:link {
display: block;
}
a:visited {
display: block;
}
a:hover {
display: block;
background-color: rgb(245, 245, 245);
}
a:active {
display: block;
background-color: rgb(245, 245, 245);
}
<ul>
<li>Item 1
</li>
<li>Item 2
</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5
</li>
</ul>

You can use the hover the li instead of the a to correct the background-color applied on hover by using:
li:hover a {
display: block;
}
li:hover {
background-color: rgb(245, 245, 245);
}
instead of:
a:hover {
display:block;
background-color:rgb(245,245,245);
}
See demo below:
ul li {
float: left;
line-height: 5em;
padding: 0 2em;
}
a:link {
display: block;
}
a:visited {
display: block;
}
li:hover a {
display: block;
}
li:hover {
background-color: rgb(245, 245, 245);
}
a:active {
display: block;
background-color: rgb(245, 245, 245);
}
<ul>
<li>Item 1
</li>
<li>Item 2
</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5
</li>
</ul>

Here you go, my comments should explain everything but feel free to ask.
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
ul{
list-style-type: none; /* Feel free to remove this, just easier without bullets */
}
ul li {
float: left;
line-height: 5em; /* Should be the same as height */
padding: 0 2em;
position: relative; /* Make sure a & a:before can stay contained */
height: 5em; /* Should be same as line-height */
white-space: nowrap; /* Ensure that your items don't wrap and mess up width */
z-index: -1; /* So that a:before is able to trigger with :hover */
}
a{
position: relative; /* Make sure a:before can stay contained */
display: block; /* Ensures that a can expand to full size of container */
}
a:before{
content: ""; /* Necessary for :before element to be created */
position: absolute; /* Vital - allows positioning */
top: 0;
right: -2em; /* Minus same padding as li has */
bottom: 0;
left: -2em; /* Minus same padding as li has */
z-index: -1; /* Makes sure :before doesn't go above anchor text */
}
a:hover:before,
a:active:before {
background-color:rgb(245,245,245);
}

Related

Flexbox space-evenly selector for gaps of element?

Hi i have a navbar created by flex box. Items are space-evenly. I need fill gaps around element with same blue color. And also after hover color will change so i need to select both li elements and gaps is there any way how to select them?.
#menu{
display: flex;
margin-top: 0;
padding: 0;
justify-content: space-evenly;
}
#menu li {
height: 100%;
list-style-type: none;
background:rgba(5, 151, 242, 1);
}
#menu li a{
color:white;
text-decoration: none;
text-transform: uppercase;
line-height: 6.5;
width: 100%;
height: 100%;
}
<ul id="menu">
<li>Link 1</li>
<li>Link 2</li>
<li>Longer Link 3</li>
<li>Link 4</li>
</ul>
Your problem is that you are thinking to complex. you don't need the justify-content: space-evenly;, but you need to let the li-elements grow with: flex-grow: 1;
Also you don't need to use rgba, if you don't use transparency you can use rgb
#menu{
display: flex;
margin-top: 0;
padding: 0;
}
#menu li {
height: 100%;
list-style-type: none;
background:rgb(5, 151, 242);
flex-grow: 1;
text-align: center;
}
#menu li:hover {
background:rgba(155, 5, 242);
}
#menu li a{
color:white;
text-decoration: none;
text-transform: uppercase;
line-height: 6.5;
width: 100%;
height: 100%;
display: block;
}
<ul id="menu">
<li>Link 1</li>
<li>Link 2</li>
<li>Longer Link 3</li>
<li>Link 4</li>
</ul>
EDIT:
I made the whole block clickable as requested additionally. This is done by adding display: block; to the a-elements. A link is normally an inline-element, so this switches it to behave like a block element witch listens to the width/height settings already present in the question.
Instead of using justify-content: space-evenly, you can use flex: 1 for each <li>. You can center the text using text-align: center.
Then, you create your hover effect for each item.
#menu{
display: flex;
margin-top: 0;
padding: 0;
}
#menu li {
height: 100%;
list-style-type: none;
background:rgba(5, 151, 242, 1);
flex: 1;
text-align: center;
transition: 0.3s;
}
#menu li a {
border-left: 1px solid red;
border-right: 1px solid red;
color: white;
text-decoration: none;
text-transform: uppercase;
line-height: 6.5;
height: 100%;
display: inline-block;
}
#menu li:hover {
background: rgba(5, 151, 242, 0.8);
}
<ul id="menu">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
</ul>

Diamond shape layout with CSS

I am attempting to layout an unordered list in a diamond form.
I cannot figure out how to do this without adding hacky <div>'s all over the place.
I'd rather keep it semantically a clean ul.
Code example (I can add id's, that is no problem.)
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
I want it to look like this:
Perhaps something like this can be achieved with display: flex? Perhaps display: table-cell? I have tried everything so far, I cannot figure it out.
The layout can be achieved with flexbox all the way through:
ul {
display: flex;
flex-direction: column; /* 1 */
flex-wrap: wrap; /* 1 */
height: 200px; /* 2 */
list-style: none;
padding: 0; /* 3 */
}
li {
flex: 0 0 100%; /* 4 */
display: flex;
justify-content: center; /* 5 */
align-items: center; /* 5 */
background-color: lightyellow;
}
li:not(:first-child):not(:last-child) { /* 6 */
flex-basis: 50%;
}
span {
height: 50px;
width: 100px;
background-color: lightgreen;
border: 1px solid black;
display: flex; /* 7 */
justify-content: center; /* 7 */
align-items: center; /* 7 */
}
* { box-sizing: border-box; }
/* grid lines
ul { border: 1px dashed black; }
li { border: 1px solid red; }
*/
<ul>
<li><span>item 1</span></li>
<li><span>item 2</span></li>
<li><span>item 3</span></li>
<li><span>item 4</span></li>
</ul>
jsFiddle
Notes:
Set the container to column wrap.
For flex items to know where to wrap, a height must be defined on the container.
Remove ul default padding.
Make list items consume all column space.
Center spans vertically and horizontally.
Make second and third list items consume half column space, so both fit in one column.
Center text vertically and horizontally.
I'm interested in seeing if anyone comes up with something a little more clever. Here's the simplest route that came to mind - just using absolute positioning.
ul {
list-style: none;
padding: 0;
position: relative;
width: 200px;
height: 80px;
}
li {
border: 2px solid #000;
font-size: 18px;
padding: 4px;
position: absolute;
}
li:nth-child(1) { top: 50%; left: 0; transform: translateY(-50%); }
li:nth-child(2) { top: 0; left: 50%; transform: translateX(-50%); }
li:nth-child(3) { bottom: 0; left: 50%; transform: translateX(-50%); }
li:nth-child(4) { top: 50%; right: 0; transform: translateY(-50%); }
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
ul li{
position:absolute;
}
#item1{
margin-left:10%;
}
#item2{
margin-top:5%;
}
#item3{
margin-top:5%;
margin-left:20%;
}
#item4{
margin-top:10%;
margin-left:10%;
}
<ul >
<li id=item1>item 1</li>
<li id=item2>item 2</li>
<li id=item3>item 3</li>
<li id=item4>item 4</li>
</ul>
here is my version ... just made it work ... you can find a better way or make it better...
another approach with flex (for info since another one is already given):
ul {
display:inline-flex;/* or flex + margin:auto for the demo*/
flex-flow:column;
flex-wrap:wrap;
height:6.25em;/* an height is required to force wraping into columns , mind basic margin, padding and lines wanted /set for li */*/
padding:0;
margin:0;
width:25em;/* whatever you want*/
background:gray;
}
li {
display:block;/* removes the bullet */
padding:0.25em;
border:solid;
width:32%;
margin:0.5em;/* whatever, just mind for ul height*/
box-sizing:border-box;/* includes padding and borders into height calculation .... */
}
li:first-of-type,li:last-of-type {
margin:2em 0;/* increase at least margin-top */
}
body {
text-align:center;/* to center inline-flex-container and li's text */
}
ul:hover {
font-size:1.25em;/* see behavior when font-size is different */
}
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
You can just change the 2nd and 3rd <li>'s into <span>'s and wrap them in a <li>:
ul {
list-style: none;
}
li {
display: inline-block;
padding: 0;
vertical-align: middle;
}
li > span {
display: block;
}
li:not(:nth-of-type(2)),
li > span {
border: 2px solid black;
margin: 4px;
}
<ul>
<li>item 1</li>
<li>
<span>item 2</span>
<span>item 3</span>
</li>
<li>item 4</li>
</ul>
It's simple, quick, and doesn't require any sort of weird positioning.
To be fully semantically correct, you should technically use an ol, since you have an order to your items:
Usage note: The <ol> and <ul> elements both represent a list of items. They differ in that, with the <ol> element, the order is meaningful. As a rule of thumb to determine which one to use, try changing the order of the list items; if the meaning is changed, the <ol> element should be used, otherwise you can use <ul>.

How can i add a sub-sub menu with CSS

Im trying to do a sub-sub menu in a webpage. I tried following the help in this post: how do I make a sub sub menu with css? but to be honest i didnt understand what code i had to add in each class and when i tried it didnt show anything. Here is the code of the menu:
<div class="l7menu">
<ul class="dpdown">
<li class="mainlist">Hombres
<ul class="sub_menu">
Prueba
Here goes the sub-submenu
<ul>
<li> Item 1 </li>
<li> Item 2 </li>
</ul>
</ul>
</li>
</ul>
</div>
Also the CSS of the classes are these ones (The sub_menu and l7menu class dont have any style applied):
.mainlist {
border-bottom: 2px solid #EAD704;
background: none;
margin-left: 2px !important;
}
.mainlist:hover {
color: #EAD704 !important;
}
ul.dpdown {
float: right;
position: relative;
z-index: 1000;
}
ul.dpdown li {
font-weight: bold;
float: left;
zoom: 1;
display: inline;
line-height: 20px;
list-style: none outside none;
margin-left: -25px;
}
ul.dpdown a:hover {
color: #EAD704;
}
ul.dpdown a:active {
color: #FFFFFF;
}
ul.dpdown li a {
color: #e8e8e8;
display: block;
padding-bottom: 4px;
text-align: center;
width: 150px;
}
ul.dpdown li:last-child a {
border-right: none;
} /* Doesn't work in IE */
ul.dpdown li.hover, ul.dpdown li:hover {
color: black;
position: relative;
}
ul.dpdown li.hover a {
color: white;
}
/*
LEVEL TWO
*/
ul.dpdown ul {
width: 150px;
visibility: hidden;
position: absolute;
top: 100%;
left: 0;
}
ul.dpdown ul li {
font-weight: normal;
background: #333;
color: #000;
float: none;
}
/* IE 6 & 7 Needs Inline Block */
ul.dpdown ul li a {
background-color: #101010;
border-right: medium none;
display: inline-block;
margin-top: 2px;
padding: 10px 0;
width: 150px;
font-size: 13px;
color: #999999;
}
ul.dpdown ul li a:hover {
background-color: #222222;
}
/*
LEVEL THREE
*/
ul.dpdown ul ul {
left: 100%;
top: 0;
}
ul.dpdown li:hover > ul {
visibility: visible;
}
As always thank you very very much !
Here's a FIDDLE, I fixed your CSS a little.
Your HTML should look like this
<div class="l7menu">
<ul class="dpdown">
<li class="mainlist">Hombres
<ul class="sub_menu">
<li>Prueba</li>
<li>Here goes the sub-submenu
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</li>
</ul>
</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>

align ul next to each other dropdown menu

I have the next fiddle: http://jsfiddle.net/cristi_mvp/e8UkN/4/
I want the columns to be displayed next to each other, instead of one over another.
Each column has different widths.
I tried different things but they dont work.
Also I do not want to use css column.
It should be simple, but i just can't find the answer.
Thank you.
Here is the HTML code:
<div class="header-main">
<div class="header-main-menu">
<ul class="menu">
<li> <a href='#' title='Menu 1'> Menu 1</a>
<ul>
<li>Column 1 lenght xxxx</li>
<li>Column 1</li>
<li>Column 1</li>
<li>Column 1</li>
<li>Column 1</li>
<li>Column 1</li>
</ul>
<ul>
<li>Column 2 lenght</li>
<li>Column 2</li>
<li>Column 2</li>
<li>Column 2</li>
</ul>
<ul>
<li>Column 3</li>
<li>Column 3</li>
<li>Column 3</li>
<li>Column 3</li>
<li>Column 3</li>
</ul>
</li>
<li> <a href='#' title='Menu 2'> Menu 2</a>
<ul>
<li>Column 1-2</li>
<li>Column 1-2</li>
<li>Column 1-2</li>
<li>Column 1-2</li>
</ul>
<ul>
<li>Column 2-2</li>
<li>Column 2-2</li>
<li>Column 2-2</li>
</ul>
</li>
</ul>
</div>
</div>
Here is my css:
.header-main-menu .menu {
color: #fff;
float: left;
margin: 0;
}
.header-main-menu .menu li {
display: inline-block;
float: left;
position: relative;
margin: 0;
padding: 0;
}
.header-main-menu .menu li a {
display: block;
color: #00000;
text-decoration: none;
font-size: 15px;
line-height: 15px;
height: 20px;
padding: 10px 24px 6px 10px;
display: block;
}
.header-main-menu .menu ul {
background-color:rgba(0, 0, 0, 0.9);
position: absolute;
left: -9999px;
/* Hide off-screen when not needed (this is more accessible than display:none;) */
-webkit-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
z-index: 5000;
}
.header-main-menu .menu ul li {
/*padding-top: 1px;*/
/* Introducing a padding between the li and the a give the illusion spaced items */
float: none;
background-image: none;
display: block;
min-width: 120px;
}
.header-main-menu .menu ul a {
white-space: nowrap;
/* Stop text wrapping and creating multi-line dropdown items */
display: block;
font-size: 13px;
line-height: 13px;
padding: 6px 24px 2px 14px;
}
.header-main-menu .menu li:hover ul {
/* Display the dropdown on hover */
left: 0;
/* Bring back on-screen when needed */
fload:left;
}
.header-main-menu .menu li:hover a {
/* These create persistent hover states, meaning the top-most link stays 'hovered' even when your cursor has moved down the list. */
}
.header-main-menu .menu li:hover ul a {
/* The persistent hover state does however create a global style for links even before they're hovered. Here we undo these effects. */
text-decoration: none;
background: none;
}
.header-main-menu .menu li:hover ul li a:hover {
/* Here we define the most explicit hover states--what happens when you hover each individual link. */
background: #FF0000;
}
.header-main-menu .menu li a:hover {
background-color: #000;
}
.header-main-menu .menu li:hover {
background: #000;
}
.header-main-menu .menu ul li:hover {
background: none;
}
Please add padding: 0 to your code. Like this:
.header-main-menu .menu ul {
color: #fff;
float: left;
margin: 0;
padding: 0;
}
.menu
{
display:block;
}
ul
{
list-style-type:none;
}
ul li
{
float:left;
width:80px;
padding:10px;
background-color:#003366;
color:white;
text-align:center;
}
a
{
color:white;
text-decoration:none;
}
ul li ul
{
display:none;
}
ul li:hover ul
{
display:block;
margin-left:-50px;
}
fiddle

li alignment behaves strange if remove new lines after items

I have next navigation block in html template
<nav class="navigation">
<ul class="nav">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
</nav>
with css
.navigation {
padding: 0 0 19px;
}
.nav {
font: 20px/22px "futura_demi_c", Arial, Helvetica, sans-serif;
text-align: justify;
text-align-last: justify;
list-style-type: none;
padding: 0;
margin: 0;
}
.nav:after {
content: "";
display: inline-block;
width: 100%;
overflow: hidden;
}
.nav li {
display: inline-block;
}
.nav a {
color: #020202;
}
Items have to be aligned justify in navigation block and occupy all entire width. And they are, if I use the code above.
But if i remove new lines after each 'li' all items move to the right without spaces between them
<nav class="navigation">
<ul class="nav">
<li>Item 1</li><li>Item 2</li><li>Item 3</li><li>Item 4</li><li>Item 5</li><li>Item 6</li>
</ul>
</nav>
Is it normal behaviour or my css is wrong?
Behaviour is the same for all browsers.
Jsfiddle examples: correct - http://jsfiddle.net/x9zfP/1 wrong - http://jsfiddle.net/AMK8z/1/
Tnx!
The behaviour is expected, because of the display: inline-block. This means whitespace between the elements will be considered.
See also CSS-Tricks - Fighting the Space Between Inline Block Elements
your css is wrong, "." is for class and "#" for id.
your ul has an id, so first replace all occurencies of ".nav" with "#nav"
here the correct css:
.navigation {
padding: 0 0 19px;
}
#nav {
font: 20px/22px "futura_demi_c", Arial, Helvetica, sans-serif;
text-align: justify;
text-align-last: justify;
list-style-type: none;
padding: 0;
margin: 0;
width:100%;
display:table
}
/* useless
#nav:after {
content: "";
display: inline-block;
width: 100%;
overflow: hidden;
}
*/
#nav li {
display: table-cell;
}
#nav a {
color: #020202;
}
basically your parent element need to have a width, and child need the property "display:table-cell".
The behavior is normal because your li has no padding or margin, so there's nothing there to keep the split apart.
This fixes your issue:
.nav li {
display: inline-block;
padding: 0 30px;
}
http://jsfiddle.net/AMK8z/1/