SCSS Change sibling color on hover - css

I have a menu where I want to change the link color on hover, but also change all of its siblings to another color. Is this possible without JS?
HTML:
<ul>
<li>
<a>lorem</a>
</li>
<li>
<a>ipsum</a>
</li>
</ul>
SCSS:
ul {
$primary-color: orange;
> li {
> a {
color: #000;
border-bottom: solid 2px transparent;
&:hover {
color: $primary-color;
border-color: $primary-color;
& + a:not(:hover) {
color: red;
}
}
}
}
}

You can not affect the other a tags when one is hovered. Your only real option here is to apply the "other" colour when the ul is hovered, and then override the "other" colour when the link is hovered.
ul > li > a {
color: #000;
border-bottom: solid 2px transparent;
}
ul > li > a:hover {
color: orange;
border-color: orange;
}
ul:hover a {
color: red;
}
<ul>
<li>
<a>lorem</a>
</li>
<li>
<a>ipsum</a>
</li>
<li>
<a>sit</a>
</li>
<li>
<a>amet</a>
</li>
</ul>
SCSS version: https://codepen.io/3rror404/pen/OJMNyJg

Related

Change color on active class when hover others li tag [duplicate]

This question already has answers here:
Is there a "previous sibling" selector?
(30 answers)
Closed 1 year ago.
I want to change the color to #000 on active class when hover others li tag
li:hover ~ li.active {
color: #000
}
li {
display: inline-block;
margin: 30px;
padding: 10px;
}
li.active {
color: red;
}
li:hover {
color: red;
}
/* How to do this */
li:hover ~ li.active {
color: #000
}
<nav>
<ul>
<li class="active">Home</li>
<li>About</li>
<li>Hello</li>
</ul>
</nav>
~ (general sibling selector) selects next siblings.
It doesn't work in your example because li.active is the first item (a previous element) and can't be selected by ~ li.active, so if you re-order your items to make li.active the last item, your code will work:
<nav>
<ul>
<li>About</li>
<li>Hello</li>
<li class="active">Home</li>
</ul>
</nav>
Check out this famous Stack Overflow thread for tricks to select a previous sibling.
As #MoaazBhnas said, ~ (general sibling selector) selects the next siblings, so it won't work with this order. However, you can change the appearance of the order by using:
ul {
transform: rotate(180deg);
}
ul > li {
transform: rotate(-180deg);
}
Then you can set your nav to position: absolute; and it will be in the initial position with your desired behavior.
li {
display: inline-block;
margin: 30px;
padding: 10px;
}
li.active {
color: red;
}
li:hover {
color: red;
}
/* How to do this */
li:hover ~ li.active {
color: #000
}
ul {
transform: rotate(180deg);
}
ul > li {
transform: rotate(-180deg);
}
nav {
position: absolute;
}
<nav>
<ul>
<li>About</li>
<li>Hello</li>
<li class="active">Home</li>
</ul>
</nav>

Hover effect that changes all of same type except selected hover [duplicate]

This question already has an answer here:
Change opacity on all elements except hovered one
(1 answer)
Closed 2 years ago.
I am trying to do a hover effect that changes other "a" tags along with the hovered "a" tag. So far I can only do the selected hover.
ul li{
list-style: none;
}
ul li a {
color: black;
}
ul li a:hover{
color: green;
background: orange;
}
ul li a:hover:not(a:hover){
color: red;
background: black;
}
<ul>
<li>
<a>test</a>
</li>
<li>
<a>test</a>
</li>
<li>
<a>test</a>
</li>
</ul>
In essense, I'd like the selected hover to be color green and background orange and then the other "a" tags to have color red and background black;
Could you set a hover rule at the ul level that changes all items to black and red, and then override it on the specific hovered item?
ul li{
list-style: none;
}
ul:hover li a {
color: red;
background: black;
}
ul li a {
color: black;
}
ul li a:hover{
color: green;
background: orange;
}
<ul>
<li>
<a>test</a>
</li>
<li>
<a>test</a>
</li>
<li>
<a>test</a>
</li>
</ul>

.li hover and colorize .a and span

I want on hover to have for example red colored .a and span, and in my case it works if .a is hovered but if you hover on span arrow, only span arrow will be red.
.menu li:hover {
color: red;
}
.menu a:hover {
color: red;
}
<div class="menu">
<ul>
<li id="menu-item">
Blog
<span class="sub-menu-open">▲</span>
</li>
</ul>
</div>
https://jsfiddle.net/fgydznrx/
You just need one more selector, when the li is hovered, select the a and color it too.
.menu li:hover>a {
color: red;
}
DEMO
.menu li:hover {
color: red;
}
.menu li:hover>a {
color: red;
}
.menu a:hover {
color: red;
}
<div class="menu">
<ul>
<li id="menu-item">
Blog
<span class="sub-menu-open">▲</span>
</li>
</ul>
</div>
This happens because the <a> element has its own style on hover, and you need to explictly overwrite it in order to get a different effect on hover.
In this case, you want its color to be the same of the parent. For this reason, you can apply color: inherit to achieve the result:
.menu li:hover {
color: red;
}
a {
color: inherit;
}
.menu a:hover {
color: red;
}
<div class="menu">
<ul>
<li id="menu-item">
Blog
<span class="sub-menu-open">▲</span>
</li>
</ul>
</div>

li marker character color not updating in chrome

I have a <ul> with a handful of <li>s. I'm adding classes to the <li>s with a very basic bit of js. (This is an example for illustrating the possible bug, not my actual use case).
In FF, IE, Safari, the class .good or .bad is added, and the <li> and <a> colors are updated.
However, in Chrome the class is added, the <a> color is updated, but the <li> color stays the same. Browser Inspector shows the li character color is the color specified in the class, however the actual window shows the old color. Toggling any class attribute with the browser inspector causes the window to re-render, with the correct colors. Likewise with resizing the codepen results window.
View a CodePen here: http://codepen.io/fontophilic/pen/EVmbWd
setTimeout(function(){
document.getElementById("bar").classList.add("bad");
document.getElementById("test").classList.add("good");
document.getElementById("foo").classList.add("good");
document.getElementById("whatevs").classList.add("good");
}, 3000);
ul li {
color: black;
}
ul li a {
color: black;
}
ul li.good {
color: green;
}
ul li.good a {
color: green;
}
ul li.bad {
color: red;
}
ul li.bad a {
color: red;
}
<ul>
<li> First</li>
<li id="test"> Two</li>
<li id="foo"> The Third</li>
<li> Quatro</li>
<li id="bar"> Fiver</li>
<li> Six</li>
<li id="whatevs"> Seven</li>
</ul>
Important to note, if the <li>s have the classes applied on page load, display is as expected: http://codepen.io/fontophilic/pen/XmRqqJ
Any ideas on how to get Chrome to re-render the li color? Is this a known bug?
I still believe this to be a chromium/webkit bug, but for now I've found an acceptable solution. I force Chrome to re-render the element by modifying the box by adding and removing a 1px transparent border.
setTimeout(function(){
document.getElementById("bar").classList.add("bad");
document.getElementById("test").classList.add("good");
document.getElementById("foo").classList.add("good");
document.getElementById("whatevs").classList.add("good");
}, 3000);
ul {
width: 150px;
}
ul li {
list-style: disc;
color: transparent;
}
ul li a {
color: black;
display: block;
border-top: 1px solid transparent;
}
ul li.good {
background-image: none;
color: green;
border-top: 1px solid transparent;
}
ul li.good a {
color: green;
border-top: 0px solid transparent;
}
ul li.bad {
color: red;
border-top: 1px solid transparent;
}
ul li.bad a {
color: red;
border-top: 0px solid transparent;
}
<ul>
<li> First</li>
<li id="test"> Two</li>
<li id="foo"> The Third</li>
<li> Quatro</li>
<li id="bar"> Fiver</li>
<li> Six</li>
<li id="whatevs"> Seven</li>
</ul>
Update
Based on this stackoverflow question, I've improved my solution and eliminated the crufty css. hiding and showing the parent element will force a redraw of its children. For whatever reason, using jQuery's show/hide worked, and vanilla js show/hide did not. This is confusing, but seemingly true.
setTimeout(function(){
document.getElementById("bar").classList.add("bad");
document.getElementById("test").classList.add("good");
document.getElementById("foo").classList.add("good");
document.getElementById("whatevs").classList.add("good");
$("#woot").hide().show(0);
}, 3000);
ul li {
color: black;
}
ul li a {
color: black;
}
ul li.good {
color: green;
}
ul li.good a {
color: green;
}
ul li.bad {
color: red;
}
ul li.bad a {
color: red;
}
<ul id="woot">
<li> First</li>
<li id="test"> Two</li>
<li id="foo"> The Third</li>
<li> Quatro</li>
<li id="bar"> Fiver</li>
<li> Six</li>
<li id="whatevs"> Seven</li>
</ul>

I've inherited a web page and I want to create a hover drop down menu but I'm having some trouble.

Basically I've started as webmaster for my society. I'm tryign to clean up the navigation bar and I'd like to include a drop down menu but I can't figure it out with what I have there now. The current menu looks as follows:
<nav>
<ul>
<li id="home"><a <?=nlink($page, "home")?> href="home">Home</a></li>
<li id="ourshows"><a <?=nlink($page, "shows")?> href="shows">Our Shows</a></li>
<li id="booking"><a <?=nlink($page, "booking")?> href="booking">Booking</a></li>
<li id="rehearsals"><a <?=nlink($page, "rehearsals")?> href="rehearsals">Rehearsals</a></li>
<li id="history"><a <?=nlink($page, "history")?> href="history">History</a></li>
<li id="contact"><a <?=nlink($page, "contact")?> href="contact">Committee & Contact</a></li>
<li id="involved"><a <?=nlink($page, "involved")?> href="involved">Get Involved</a></li>
<li id="calendar"><a <?=nlink($page, "calendar")?> href="calendar">Calendar</a></li>
</ul>
</nav>
This is what my CSS looks like for this section:
nav {
border-top: thin #ccc solid;
border-bottom: thin #ccc solid;
font-size: 1.2em;
}
nav > ul > li {
list-style-type: none;
display: inline-block;
color: black;
margin-right: 1.5rem;
font-variant: small-caps;
text-decoration: none;
}
nav a {
text-decoration: none;
color: #555;
}
nav a:active {
color: #555;
}
nav a:visited {
color: #555;
}
nav a:focus {
color: #555;
}
nav a:hover {
color: #000;
}
nav a.selected {
font-weight: bold;
}
p:first-letter {
font-size: 120%;
}
I think you are looking something like this:
nav {
border-top: thin #ccc solid;
border-bottom: thin #ccc solid;
font-size: 1.2em;
}
nav > ul > li {
list-style-type: none;
display: inline-block;
color: black;
margin-right: 1.5rem;
font-variant: small-caps;
text-decoration: none;
}
nav a {
text-decoration: none;
color: #555;
}
nav a:active {
color: #555;
}
nav a:visited {
color: #555;
}
nav a:focus {
color: #555;
}
nav a:hover {
color: #000;
}
nav a.selected {
font-weight: bold;
}
p:first-letter {
font-size: 120%;
}
nav > ul > li > ul {
display: none;/*hide nested ul*/
position: absolute;
padding: 0;
list-style-type: none;
}
nav > ul > li:hover ul {
display: block;/*show nested ul on hover*/
}
<nav>
<ul>
<li id="home"> Home</li>
<li id="ourshows">Our Shows
<ul>
<li> Home</li>
<li> Home</li>
<li> Home</li>
</ul>
</li>
<li id="booking">Booking
</li>
<li id="rehearsals">Rehearsals
</li>
<li id="history">History
</li>
<li id="contact">Committee & Contact
</li>
<li id="involved">Get Involved
</li>
<li id="calendar">Calendar
<ul>
<li> Home</li>
<li> Home</li>
<li> Home</li>
</ul>
</li>
</ul>
</nav>
Here's a very basic example of a navigation with dropdown menus:
JSFiddle
Basically, it uses strictly CSS to determine whether or not to show the submenus. Let me explain.
The hierarchy is as follows:
<ul> //Outer menu
<li> //Menu item
<ul> //Submenu
<li> //Submenu item
So to show a submenu, you add a child <ul> to any <li> in the parent menu.
The submenu <ul> is set with the following properties:
body > ul li ul
{
position: absolute; /*We are taking the submenu out of the flow of the doc.*/
top: 100%; /*Move it just below the parent <li>*/
left: 0; /*Align to the left of the parent*/
display: none; /*Hide it when not active*/
}
Note that these are just the important properties. I added some others for colors and such in the actual fiddle.
We then use the :hover property to show the submenu when necessary.
body > ul li:hover ul
{
display: block; /*Show the ul*/
}
BAM! You have a dropdown menu. Comment if you have any more questions.

Resources