Using SCSS to target a sibling class when hovering over an element with CSS

Is there a way to alter styles of a sibling element on hover using only CSS?

I attempted something similar but was unsuccessful.

HTML:

<ul>
   <li class="item active">name1</li>
   <li class="item">name2</li>
   <li class="item">name3</li>
   <li class="item">name4</li>
</ul>

SCSS

ul {
  padding: 0;
  margin: 0;

  li {
    cursor: pointer;
    list-style: none;
    padding: 12px 16px;

    &.active {
       background-color: $primary-blue;
       color: white;
    }

    &:hover {
       background-color: $primary-blue;
       color: white;

       ~ .active {
         background-color: white !important;
         color: black !important;
       }
    }
  }
}

I am attempting to change the style of elements on hover while simultaneously removing the style of the currently active element. The active element could be any position in the list, up to 10 elements. This example has been simplified for clarity.

EDIT! IMPORTANT! I have noticed some confusion regarding my request, I hope this plunker will help clarify things :)

https://plnkr.co/edit/RQy04Qv1zy0nukhnlN82

Answer №1

To achieve the desired layout using only CSS, utilize the order property in combination with Flexbox or Grid:

ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}

li {
  cursor: pointer;
  list-style: none;
  padding: 12px 16px;
}
 
li:last-child {
  order: -1; /* rearranged to maintain layout */
}
 
.active {
  background-color: blue;
  color: white;
}

li:hover {
  background-color: blue;
  color: white;
}

li:hover ~ .active {
  background-color: white;
  color: black;
}
<ul>
 <li class="item">name2</li>
 <li class="item">name3</li>
 <li class="item">name4</li>
 <li class="item active">name1</li> <!-- must be placed last for ~ selector functionality -->
</ul>

Answer №2

"My goal is to be able to hover over any element and apply specific styles, while also hiding the active element's style. The active element could be any of the elements in a list of up to 10 items."


Achieving this behavior with CSS alone is possible, however, it requires a layout change as complex interactions using pure CSS involve:

  1. Precise positioning of elements in relation to others, considering parent-child relationships and cascading rules that impact inheritance.

  2. The requirement for unique attributes and default behaviors for certain element groups, types, or tags. Simply applying CSS to a list won't suffice to achieve the desired behavior.

Layout

  1. <input id='chx0' type="checkbox" hidden='true'>
    act as invisible switches controlling the state (specific styles) of other elements. When a checkbox is :checked, all affected elements enter an active state.

  2. <label id='btn0' for='chx0'></label>
    are buttons triggering the associated checkbox via the attribute: for= "chx0"

  3. Due to cascading nature of CSS rules, only sibling elements following the checkboxes can be styled – which essentially includes any next sibling down the DOM tree along with its children/descendants. Think of it like a family hierarchy:

    Previous-Element-Sibling <section>Elder Brother</section>

    Reference Point 🢂

    <input id='chx0' type='checkbox'>

    Next-Element-Sibling <li>Younger Brother</li>

    You can target your younger brother but not your older brother.

  4. In Demo 2, there are two checkbox-label pairs:

    • ACTIVE / INACTIVE controls the behavior of the .active element.

    • ORDER / CHAOS changes the order of <dd> elements (optional and added for demonstration).


While I'm not familiar with SCSS, it appears that you aim to modify the style of sibling elements. However, the general sibling combinator ~ seems to work but lacks the desired effect: white background with black text. In this demo, the adjacent sibling combinator + is used with inverted colors for better visibility of changes.

Demo 1

ul {
  padding: 0;
  margin: 0;
}

li {
  cursor: pointer;
  list-style: none;
  padding: 12px 16px;
}

li.active {
  background-color: blue;
  color: white;
}

li:hover {
  background-color: blue;
  color: white;
}

li:hover+li {
  background-color: black !important;
  color: white !important;
}
<ul>
  <li class="item active">name1</li>
  <li class="item">name2</li>
  <li class="item">name3</li>
  <li class="item">name4</li>
</ul>

Demo 2

.dataList {
  display: flex;
  flex-flow: column nowrap;
}

.btn {
  background: rgba(0, 0, 0, 0);
  padding: 3px 5px;
  margin: 20px 0 -15px 30px;
  border: 2px ridge grey;
  border-radius: 4px;
  cursor: pointer;
  display: inline-block;
  width: 12ch;
  text-align: center;
}

#btn0::before {
  content: 'ACTIVE';
  color: green;
}

#chx0:checked~#btn0::before {
  content: 'INACTIVE';
  color: tomato;
}

#btn1::before {
  content: 'ORDER';
  color: blue;
}

#chx1:checked~#btn1::before {
  content: 'CHAOS';
  color: orange;
}

#chx1:checked~.dataList dd:nth-of-type(1) {
  order: 8
}

#chx1:checked~.dataList dd:nth-of-type(2) {
  order: 5
}

#chx1:checked~.dataList dd:nth-of-type(3) {
  order: 6
}

#chx1:checked~.dataList dd:nth-of-type(4) {
  order: 10
}

#chx1:checked~.dataList dd:nth-of-type(5) {
  order: 3
}

#chx1:checked~.dataList dd:nth-of-type(6) {
  order: 2
}

#chx1:checked~.dataList dd:nth-of-type(7) {
  order: 4
}

#chx1:checked~.dataList dd:nth-of-type(8) {
  order: 1
}

#chx1:checked~.dataList dd:nth-of-type(9) {
  order: 7
}

#chx1:checked~.dataList dd:nth-of-type(10) {
  order: 9
}

.data {
  color: white;
  background: rgba(0, 0, 0, 0.8);
  border: 2px inset white;
  padding: 3px 5px
}

.active {
  color: gold;
  border: 2px ridge gold;
  background: rgba(0, 0, 0, 1);
}

.active::after {
  content: ' is ACTIVE';
  font-weight: 900;
}

#chx0:checked~.dataList:hover .data.active {
  border: 2px inset white;
  color: white;
  background: rgba(0, 0, 0, 0.8);
}

#chx0:checked~.dataList:hover .active::after {
  content: '';
  font-weight: normal;
}

.data:hover {
  color: #000;
  background: #fff;
}

.data.active:hover {
  color: lime;
  border-color: lime;
  background: #000;
}

#chx0:checked~.dataList .data.active:hover {
  color: #000;
  background: #fff;
}

.data.hovered {
  color: yellow;
}
<input id='chx0' type='checkbox' hidden='true'>
<input id='chx1' type='checkbox' hidden='true'>

<label id='btn0' class='btn' for='chx0'></label>
<label id='btn1' class='btn' for='chx1'></label>

<dl class='dataList'>
  <dt class='data term'>DATA LIST</dt>
  <dd class='data'>ITEM 0</dd>
  <dd class='data'>ITEM 1</dd>
  <dd class='data'>ITEM 2</dd>
  <dd class='data'>ITEM 3</dd>
  <dd class='data active'>ITEM 4</dd>
  <dd class='data'>ITEM 5</dd>
  <dd class='data'>ITEM 6</dd>
  <dd class='data'>ITEM 7</dd>
  <dd class='data'>ITEM 8</dd>
  <dd class='data'>ITEM 9</dd>
</dl>

Answer №3

It seems that including the ampersand in the active selector may be necessary, like this:

li {
    cursor: pointer;
    list-style: none;
    padding: 12px 16px;

    &.active {
       background-color: $primary-blue;
       color: white;
    }

    &:hover {
       background-color: $primary-blue;
       color: white;

       ~ &.active {
         background-color: white !important;
         color: black !important;
       }
    }
  }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Vertically and horizontally align an SVG within 2 divs without modifying the parent div of the SVG

Is there a way to center an SVG both vertically and horizontally inside a div? The issue is that the width and height of the SVG are determined using the vx-responsive library, resulting in the following DOM structure: Edit: code has been added below < ...

Ways to insert a hyperlink within a div element

Consider the following HTML structure: <article id="1919"> <div class="entry-content clearfix"> <div></div> <div></div> </div> </article> &l ...

Remove the "href" from Zend2 navigation functionality

When using Zend2 navigation from an array passed in Zend\Navigation\Navigation, everything works smoothly if child items are opened on parent item mouse hover. However, undesirable actions occur when they are opened on mouse click, as the user is ...

How to customize the color of the clock symbol in a MUI TextField set to type 'time'

<TextField id="endTime" label="End Time" onChange={onEndTimeChange} type="time" defaultValue="16:00" className={classes.textField} /> By using the attribute 'type="time"', an ic ...

Contact form repair completed - Messages successfully delivered

I am facing an issue with the contact form on my HTML landing page. Currently, when you click the 'Submit' button, it redirects to a new PHP page displaying 'Success'. Is there a way to make it so that upon clicking 'Submit' a ...

How can I assign a value other than a string to a placeholder or vue property?

As I develop a content management system using Nuxt and Pug/Jade, I am looking for an efficient way to create a list of input fields for users to enter information. My idea is to use the v-for directive to render the list and dynamically set the value and ...

What's causing ng-show to malfunction in IE11 on AngularJS?

I am experiencing a strange issue with my code - ng-show works perfectly fine on Firefox, but not on IE 11. <div ng-show="isExist" class="panel panel-default"> Here is the relevant code snippet from the controller: $scope.isExist = false; if(user ...

Encircle a circle within the Progress Tracker

Is there a way to create a ring around the circle in this progress tracker, similar to the image shown here? The progress tracker is based on You can view an example here. The CSS approach used was: .progress-step.is-active .progress-marker { backgrou ...

Problem with traversing from parent to children elements using jQuery selectors

<form data-v-c4600f50="" novalidate="novalidate" class="v-form"> <div data-v-c4600f50="" class="pr-2" question="Top Secret4"> <div data-v-c4600f50="" f ...

Compatibility of Blackberry Webworks

As I prepare to build a Webworks app, the documentation indicates that it is designed to function only on devices equipped with OS 5.0 or later. However, I am curious if there exists a way to make the app compatible with devices running an OS version lower ...

Lean/Tilt just the lower portion of the division

I have been experimenting with adding a unique slant to the bottom of a div. Progress has been made, as shown in the example below where I successfully applied the slant to some elements on the page. Currently, the slant is visible on both the top and bot ...

At times, the Kendo UI Tooltip may linger on screen longer than expected, failing to disappear as

I've been experimenting with this issue for quite some time now, but I'm stumped. Whenever I quickly move my mouse cursor over a series of links, occasionally a tooltip will linger on the screen even after the cursor has moved away from the link. ...

Creating a dynamic shift in background color

Is it possible to use jQuery to slowly change the color of diagonal lines in a background styled with CSS, while also adding a fading effect? I have created a fiddle with the necessary CSS to display a static background. You can view it here: http://jsfid ...

JQuery method for altering currentTime's format

I am attempting to showcase the current time and duration of my videos on my website using the format 00:00, but I am having some difficulty... myVideo.on('timeupdate', function() { $('.current').text(myVideo[0].currentTime); $ ...

Implementing CSS styles to Iframe content

I have written the following code snippet to display an iframe: <iframe scrolling='no' frameborder='1' id='fblike' src='http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.XYZ.com%2F&amp;send=false& ...

Ways to prevent negative values from appearing in the text field

Check out this code snippet on Fiddle. I need help with a text field that should only display positive values. If the input is negative, I want it to be stored in ng-model but not shown in the textbox. function LoginController($scope) { $scope.number = ...

What is the best way to retrieve upload progress information with $_FILES?

HTML: <input type="file" value="choose file" name="file[]" multiple="multiple"/><br/> <input type="submit" class="submit" value="confirm" /> <input type="hid ...

Changing the sliding underline effect in a jQuery navigation bar

Recently, I implemented a sliding underline element in my navigation bar. The idea is that when a link is hovered over, the underline smoothly transitions to that element. You can take a look at the codepen example here: https://codepen.io/lucasengnz/pen/e ...

Incorporating and designing a side button using jQuery Mobile

I'm working on adding a button to the left side of the screen that is round (but not necessarily) and partially visible, with a visually appealing design. This button will allow users to open a side menu panel. Below is the HTML code for the button: ...

The <input> element is not functioning as expected when attempting to use it as a button. I am struggling to find the solution to

My HTML file contains: <!Doctype HTML> <html> <head> <title>Orange’s Game</title> <meta charset="utf-8"> <script src="game.js”></script> </head> <body> <input type="button ...