Maintain Hover / Active over entire parent li element? - html

I want it so that when I hover over a <li>, the entire element has a highlight of blue, and that the text within the <li> turns from black to white. I also want it so that when I click on the <li>, the <li> becomes active and the blue highlight and change from black to white text stays. I understand I have to use the :hover and :active attributes. Here is my attempt therefore:
HTML:
<div class="facet">
<ul>
<li>
<a href="" class="link">
Name<span class="count">Count</span>
</a>
</li>
</ul>
</div>
CSS:
//Changes the LINK text to white
.link:hover {
background-color: #2897C5;
color: #ffffff;
}
//Attempt to change the entire parent element text to white and have a blue highlight, but this doesn't seem to work
.facet li:active {
background-color: #2897C5;
color: #ffffff;
}
//Normal CSS for the link when it is not hovered over or clicked on
.link {
font-size: 14px;
line-height: 1.3;
text-decoration: none;
display: block;
color: #000;
}
//White text when you hover over the count
.count:hover {
color: #ffffff;
}
//Normal CSS when you don't hover over the count
.count {
position: relative;
float: right;
color: #bdbdbd;
}
NowI have a variety of issues with my attempt above.
1. When I hover over the <li>, the entire thing turns blue which is great, and the "Name" text also turns white. However, the "Count" text only turns white when I have my mouse hover over that portion of the <li>.
2. When I click on the <li>, the element does not apply the active state (which is all white text and blue highlight) to the entire element.
Any ideas on how I can improve? Thanks!

Here's a better version with a lot less CSS: (no solution for the active-bit, but that will have to be solved outside CSS)
ul {
list-style-type: none;
}
.facet li:hover,.facet li:hover .link,.facet li:hover .count {
background-color: #2897C5;
color: #FFF;
}
.link {
font-size: 14px;
line-height: 1.3;
text-decoration: none;
display: block;
color: #000;
padding: .2em;
}
.count {
position: relative;
float: right;
color: red;
}
<div class="facet">
<ul>
<li>
<a href="#" class="link">
Name<span class="count">Count</span>
</a>
</li>
</ul>
</div>

Related

Changing color of menu on text hover

I want to change the color of the menu on text hover. But not when the menu text is hovered but another heading. I have a heading "Not a restaurant, but here for them." and when the user hovers the word "restaurant" the menu text color should change to white and the word "restaurant" to red and the rest of the heading to white. The second part (that "restaurant" changes to red and the rest of the heading to white) already works. But how can I make it that also the color of the menu changes?
.headingRestaurant:hover {
color: red;
}
.headingRestaurant {
cursor: pointer;
}
.textb {
pointer-events: none;
}
.headingRestaurant {
pointer-events: initial;
}
.textb:hover {
color: white;
}
<nav>
<ul>
<li>
Home
</li>
<li>
About
</li>
</ul>
</nav>
<h1 class="textb">
Not a <span id="heading1" class="headingRestaurant">restaurant</span>,
<br> but here for them.
</h1>
Since CSS can only interact with things inside or below the current element, the easiest solution would be to use Javascript to handle the hover for you.
You can use the function addEventListener to add both a mouseover and a mouseout event on your restaurant text to add/remove a hover class to whichever element you want to hover.
var nav = document.querySelector('nav');
var headingRestaurant = document.querySelector('.headingRestaurant');
headingRestaurant.addEventListener('mouseover', function() {
nav.classList.add('hover');
});
headingRestaurant.addEventListener('mouseout', function() {
nav.classList.remove('hover');
});
.headingRestaurant:hover {
color: red;
}
.headingRestaurant {
cursor: pointer;
}
.textb {
pointer-events: none;
}
.headingRestaurant {
pointer-events: initial;
}
.textb:hover {
color: white;
}
nav.hover,
nav.hover a {
color: red;
}
<nav>
<ul>
<li>
<a
href="file:///C:/Users/.../index.html"
>Home</a
>
</li>
<li>
<a
href="file:///C:/Users/.../about.html"
>About</a
>
</li>
</ul>
</nav>
<h1 class="textb">
Not a <span id="heading1" class="headingRestaurant">restaurant</span>,
<br />
but here for them.
</h1>
If you'd like to use html and css only, you'd have to reverse the html flow so that the element you want to change is coded below the element you're hovering over.
In this case I've moved the nav and h1 to a container div and swapped them around so that the h1 is coded above the nav. The display order is then fixed by using both the properties display: flex and flex-direction: column-reverse. The hover in this method uses the css selector ~ which matches an selector that is preceded by another selector. In the case of .textb:hover ~ nav it would select any nav element that is preceded by a .textb which is hovered over. Since the part after the ~ is still a selector, you could also change a specific menu item.
.headingRestaurant {
cursor: pointer;
pointer-events: initial;
}
.textb {
pointer-events: none;
}
.textb:hover {
color: white;
}
.textb:hover .headingRestaurant {
color: red;
}
.textb:hover ~ nav,
.textb:hover ~ nav a {
color: red;
}
.textb:hover ~ nav a.about {
color: purple;
}
.reversed {
display: flex;
flex-direction: column-reverse;
}
<div class="reversed">
<h1 class="textb">
Not a <span id="heading1" class="headingRestaurant">restaurant</span>,
<br />
but here for them.
</h1>
<nav>
<ul>
<li>
<a class="about" href="file:///C:/Users/.../index.html">Home</a>
</li>
<li>
About
</li>
</ul>
</nav>
</div>
:has is definitely the way to go here but there are some clever cookies out there who might come up with something innovative. Note that this isn't fully supported yet.
/* This is just making things pretty */
nav ul li {
display: inline-block;
padding: 0.5rem 1rem;
margin: 0;
border: 1px dotted red;
}
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
}
nav ul li a {
text-decoration: none;
color: inherit;
}
/* This is the functional stuff */
.headingRestaurant:hover {
color: red;
}
.headingRestaurant {
cursor: pointer;
}
.textb {
pointer-events: none;
}
.headingRestaurant {
pointer-events: initial;
}
.textb:hover {
color: white;
}
/* This colours the menu on hover */
body:has(.headingRestaurant:hover) nav {
background-color: lightblue;
}
<nav>
<ul>
<li>
Home
</li>
<li>
About
</li>
</ul>
</nav>
<h1 class="textb">
Not a <span id="heading1" class="headingRestaurant">restaurant</span>,
<br> but here for them.
</h1>
Replace target with whatever class/id you are using to identify your menu element and it will control the styling when hovering on the .headingRestaurant element.
.headingRestaurant:hover target {
}

CSS/HTML: a tag with a span inside, span margin creating white space on hover underline

I have a link with a span inside, I want to place a margin on the span so it is distanced from the link title, however, when I use the :hover for underline, a white space is created where there is no underline. I want the underline to be the full width of the link element. How do I do this? Thank you.
http://jsfiddle.net/EY387/
HTML
<div>
<a href="#" class="link-1">
<span class="span-1">1</span>
Hello
</a>
</div
CSS
.link-1 {
font-size: 16px;
text-decoration: none;
}
.link-1:hover {
text-decoration: underline;
}
.span-1 {
font-size: 12px;
margin-right: 5px;
}
Though it may not be exactly what you're looking for, why not try a border?
HTML
<div>
<a href="#" class="link-1">
<span class="span-1">1</span>
Hello
</a>
</div>
CSS
.link-1 {
font-size: 16px;
text-decoration: none;
}
.link-1:hover {
border-bottom:1px solid #000;
}
.span-1 {
font-size: 12px;
margin-right: 5px;
}
Demo
As #DavidThomas explained, if having a border move elements underneath is a problem, the use of a box-shadow could be easily swapped for the border-bottom.
Illustrated here
Remove margin to span. margin space not taking underline on hover.
For space use . As in this following markup:
<div>
<a href="#" class="link-1">
<span class="span-1">1 </span>
Hello
</a>
</div>
Css:
.link-1 {
font-size: 16px;
text-decoration: none;
}
.link-1:hover {
text-decoration: underline;
}
.span-1 {
font-size: 12px;
}
DEMO

How to change the color of an anchor tag in a list for being active while already set to another color?

I have already set the text color of anchor tag in a list as BLACK in the CSS file. Now I want to declare a list item as active and change its text color, but it doesn't work. Help please!
Here's the preset color:
#already-set li a
{
font: normal 14px Arial;
border-top: 1px solid #ccc;
display: block;
color: black;
text-decoration: none;
line-height:26px;
padding-left:5px;
}
And here's the code to change active list item color:
a#active
{
background-color: #d11250;
color: white;
font-weight:bold;
}
And here's my HTML:
<ul id="already-set">
<li> List Item </li>
</ul>
You are getting confused with the a:active.
Please check this EXAMPLE which will make it a bit more clear. I have added jQuery to change the active element on the fly when clicked.
$(function() {
$("a").click(function() {
// remove classes from all
$("a").removeClass("active");
// add class to the one we clicked
$(this).addClass("active");
});
});
#already-set li a {
font: normal 14px Arial;
border-top: 1px solid #ccc;
display: block;
color: black;
text-decoration: none;
line-height: 26px;
padding-left: 5px;
}
a.active {
background-color: #d11250;
color: white;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="already-set">
<li> List Item 1
</li>
<li> List Item 2
</li>
<li> List Item 3
</li>
</ul>
The text color remains black because of the css in the list. If you want to change the text color to white in the selected element please make the following change as the EXAMPLE 2
Change a.active to #already-set li a.active.
Change a#active to a:active this will solve your problem.

Sprites and Absolute Positioning issue: 2 work and 2 don't?

sorry I know sprites are covered quite a lot but I haven't been able to find an answer out there with my specific context.
I have 4 absolutely positioned buttons using the same .png file with 3 states (link,hover,active) for the 'home' button the hover works but the hover area is not the whole button, for the 'cars' button the hover is all of the button, but the other 2 buttons have no clickable or hoverable area.
Most articles dealing with this problem say to adjust the height/width, but all that does for me is move the image but not the text and doesn't change any of the hovering issues... not sure what else to try..
necessary style:
span.nav-button-adjust { display:block;
position:relative;
top:3px;
left:9px;
}
span.nav-button a:link,
span.nav-button a:visited { display:block;
width: 91px; height: 30px;
background-image: url(images/nav-button.png);
background-position: top;
background-repeat: no-repeat;
font-family:arial black;
text-decoration:none;
color:#1461b2;
}
span.nav-button a:hover { background-image: url(images/nav-button.png);
background-position: center;
}
span.nav-button a:active { background-image: url(images/nav-button.png);
background-position: bottom;
}
necessary html:
<span class="nav-button"><span class="nav-button-adjust"> HOME</span></span>
<span class="nav-button"><span class="nav-button-adjust"> ABOUT</span></span>
<span class="nav-button"><span class="nav-button-adjust"> CARS</span></span>
<span class="nav-button"><span class="nav-button-adjust">SEARCH</span></span>
EDIT: per request:
the image I am using: https://dl.dropboxusercontent.com/u/12017360/cars/images/nav-button.png
You have too much going on with your CSS and especially your HTML. You can tidy up what you want to do with the following. You don't need to use absolute positioning.
In the following jsFiddle you'll notice that when you hover or click a link, a tiny sliver of another part of the background image pokes through. That has to do with how you made/setup your sprite.
http://jsfiddle.net/ucsNH/
Not sure if those links have to be 30px tall. If not you can fix them by setting #nav a { height: 29px; line-height: 29px; and adjusting the background-positions by 1px so they'd be 0 -1px, 0 -30px, 0 -59px. See second jsFiddle.
http://jsfiddle.net/ucsNH/2/
CSS
ul, li {
margin: 0;
padding: 0;
list-style: none;
font: 12px/1.5em Arial, sans-serif; /* this should be inherited */
}
#nav {
width: 202px; /* ( 5px + 91px + 5px ) x 2 */
}
#nav li {
float: left;
margin: 5px;
}
#nav a:link,
#nav a:visited {
display: block;
width: 91px;
height: 30px;
line-height: 30px; /* vertically centers text */
text-transform: uppercase;
color:#1461b2;
background: url(images/nav-button.png) no-repeat 0 0;
text-decoration: none;
text-align: center;
font-weight: bold;
}
#nav a:hover {
background-position: 0 -29px;
}
#nav a:active {
background-position: 0 -58px;
color: white;
}
.home,
.about {
position: relative;
left: 25%;
}
HTML
<ul id="nav">
<li class="home">Home</li>
<li class="about">About</li>
<li>Cars</li>
<li>Search</li>
</ul>
That HTML is a lot tidier wouldn't you say?
Navigation should be placed in an un-ordered list <ul>. Please avoid inline styles like you have on your anchor <a> tags. The span tag is not need inside the anchor tag and you should not use to push things (text) around. If you need some space use margin and padding. That's what they're for!
Here you go i created a jfiddle with all the hover buttons working, just click on it to check, is this what you were looking for? If yes then please select this as the correct answer by clicking on the tick to the left.
The only changes i made were to the positioning,
<span class="nav-button"><a href="home.php" style="position:absolute;left:220px;top:17px"><span class="nav-button-adjust"> HOME</span>
</a>
</span>
<span class="nav-button"><a href="about.php" style="position:absolute;left:322px;top:17px"><span class="nav-button-adjust"> ABOUT</span>
</a>
</span>
<span class="nav-button"><a href="cars.php" style="position:absolute;left:192px;top:59px"><span class="nav-button-adjust"> CARS</span>
</a>
</span>
<span class="nav-button"><a href="search.php" style="position:absolute;left:296px;top:59px"><span class="nav-button-adjust">SEARCH</span>
</a>
</span>

CSS: Class of first menu layer applied on submenu

I've got a navigation menu. But the menu get's wild.
The submenu class (this is the dropdown if you hover firstmenu). 'firstmenu' are the main areas of the site, hence the first level of the list.
Problem: Submenu get's the Firstmenus values. Even the tiny arrow background: url(images/nav-arrow.png) no-repeat center bottom; in - BUT WHY?!
We already looked into this, split up the code, removed typo3, all JavaScript and ended up with this css code:
#firstmenu {
list-style: none;
margin: 0;
padding: 0;
}
#firstmenu .firstLevel {
float: left;
}
#firstmenu .firstLevel a {
display: block;
font-size: 1.166em;
font-weight: 600;
line-height: normal;
color: #333;
padding: 41px 20px 26px;
margin-bottom: 4px;
}
#firstmenu .firstLevel .current a,
#firstmenu .firstLevel a:hover,
#firstmenu .firstLevel a.selected {
color: #fff;
background: url(images/nav-arrow.png) no-repeat center bottom;
}
#firstmenu .firstLevel a:hover,
#firstmenu .firstLevel a.selected {
background-color: #333;
}
/* Drop-Down Menus */
.submenu {
list-style: none;
margin: 0;
padding: 0;
position: absolute;
}
.submenu > ul {
top: 4px !important;
}
.submenu .secoundLevel {
width: 200px;
background: #fca500;
}
.submenu .secoundLevel a {
display: block;
color: #fff;
padding: 8px 15px;
border-top: 1px solid rgba(255,255,255,0.2);
}
.submenu .secoundLevel a:hover {
background-color: #333;
border-color: #1a1a1a;
}
.submenu .secoundLevel:first-child a {
border-top: none;
}
Anyone knows the fix?
EDIT, html:
<nav id="nav">
<ul id="firstmenu" class="clearfix">
<li class="firstLevel"><a href="index.php?id=99" >Startseite</a></li>
<li class="firstLevel current">Rootserver
<ul class="submenu">
<li class="secoundLevel"><a href="index.php?id=96" >Vergleich</a></li>
</ul>
</li>
<li class="firstLevel">Voiceserver
<ul class="submenu">
<li class="secoundLevel">Preisvergleich</li>
</ul>
</li>
</ul>
</nav>
I think the problem is a matter of understanding of CSS selectors. This selector:
#firstmenu .firstLevel a.selected {
color: #fff;
background: url(images/nav-arrow.png) no-repeat center bottom;
}
States the following: Match ALL <a> links that have a parent with class name firstLevel and it having a parent with ID firstmenu
That means this HTML bit matches:
<ul id="firstmenu" class="clearfix">
// snip
<li class="firstLevel current">Rootserver
<ul class="submenu">
<li class="secoundLevel">Vergleich</li>
</ul>
</li>
// snip
because the "secondLevel" menu has an anchor tag (<a>) that is a child (of any order, ie child, grandchild, great-grandchild, etc) of .firstLevel which is a child (of any order) of #firstmenu.
This is exactly how CSS is suppose to work but there ways to prevent what you're seeing.
The first option is to use the child selector (what I sometimes refer to as "direct descendent" selector) >
.firstLevel > a:hover{ /* code */ }
This selector specifically states: "all anchor tag that you hover which are directly descendent from .firstLevel, but no deeper.
Which means, it matches:
<li class="firstLevel">A</li>
but not the link with value "B" below
<li class="firstLevel">A
<ul>
<li><a href="#">B</b></li>
</ul>
</li>
because the second <a> tag is not directly descendant of .firstLevel, there's a <ul> and <li> between them.
The second option is to "overwrite" the previous style by having another rule with a higher CSS specificity.
#firstmenu .firstLevel .submenu a.selected {
background-image: none; /* remove the arrow from drop-down menus*/
}
There's reasons for doing one or the other.
Using the child selector is good when the styles are very specific to that element. You don't want ANY of the styles to carry over to further elements.
Use the "replacement" technique (for lack of a better term) when you're looking to modify only one specific style from another element. Ie. You want to keep the color, font, font-weight, but only want to remove the background image.
I hope that helps!
Here's some (bad) fiddles showing the base case:
http://jsfiddle.net/zTCbF/
with child selector
http://jsfiddle.net/zTCbF/1/
with the replacement technique
http://jsfiddle.net/zTCbF/2/
#firstmenu .firstLevel a {
This will target any anchor tag under .firstLevel including those under .secondLevel
So when you say...
#firstmenu .firstLevel a:hover,
You are applying your hover styles to ALL anchor tags that are descendants of .firstLevel
You want to say ...
#firstmenu .firstLevel > a {
Which will target only anchor tags that are a direct descendant of .firstLevel