U. Watt
U. Watt

Reputation: 724

scss wrong selector being matched

I have two components called GroceryItem and BasketItem. Since these components share quite a few styles and I didn't want to write the same properties in different stylesheets, I set up a stylesheet called _item-layout.scss that has all the common styles and then imported this in both BasketItem.scss and GroceryItem.scss.

The core difference between these components is that the BasketItem icon is meant to switch from white to red when the enclosing div is hovered upon, whereas the GroceryItem icon is meant to switch to green. To enable this functionality, I set the hover property to change colour in the BasketItem and the GroceryItem stylesheets.

The thing is, both components change icon colour to red when hovered on. This is especially confusing for me because in my GroceryItem.js file, I've only imported GroceryItem.scss. So how can it match a selector that isn't even present in the stylesheet that has been imported?

item-layout.scss:

.root {
  background-color: rgba(230, 230, 230, 1);
  margin: 10px 0px;
  user-select: none; //standard syntax
  -webkit-user-select: none; //webkit (safari, chrome) browsers
  -moz-user-select: none; //mozilla browser
  -khtml-user-select: none; //webkit (konqueror) browser
  -ms-user-select: none; //IE10+

  .p {
    font-weight: 500;
  }
}

.icon {
  margin-right: 10px;
  color: whitesmoke;
}

.row-content {
  display: flex;
  padding: 15px;
}

GroceryItem.scss:

@import "./../../styles/_item-layout";

.root:hover .icon {
  color: green;
}

BasketItem.scss:

@import "./../../styles/item-layout";

.root:hover .icon {
  color: red;
}

GroceryItem.js:

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlusSquare } from "@fortawesome/free-solid-svg-icons";
import "./GroceryItem.scss";
import React from "react";

function GroceryItem(props) {
    return (
        <div className="root" onClick={props.onClick} >
            <div className="row-content">
                <FontAwesomeIcon icon={faPlusSquare} className="icon"/>
                <p>{props.title}</p>    
            </div>
        </div>
    )
}

export default GroceryItem;

Upvotes: 0

Views: 76

Answers (2)

Luckyfella
Luckyfella

Reputation: 662

Both declarations of icon styles are in the same scope so the last loaded scss file overwrites the first one.

You could add an additional classname in both components and use them as a kind of color flag. Lets say in first component you add the css classname green next to your icon classname and in the second one add red next to your icon classname. So you have: ... className="icon green" ... and ... className="icon red"

In you main scss file you do

.root {
    .icon {
        &:hover {
            &.green {
                color: green;
            }
            &.red {
                color: red;
            }
        }
    }
}

Of course add the other styles you have set for your root class

Upvotes: 1

bas
bas

Reputation: 15722

I think the problem is that you have hover styles for the root class and you're using this class in both components.

If you import BasketItem.js or GroceryItem.js, their respective scss files will also be imported. Each of these scss files sets the color of elements with class root on hover to either red or green. So whichever js file is imported last will indirectly decide the root class hover color.

Since you say both components have a red hover color BasketItem.js is probably imported after GroceryItem.js based on the code in your question. If you switch the import order around you will probably see both components turn green.

The simple solution here is to just use separate classes for GroceryItem and BasketItem so there is no collision / involuntary overwriting of styles.

Upvotes: 1

Related Questions