SMACSS\BEM - how to correctly handle icon style? - css

I have two nested modules:
<div class="header">
.....
<i class="topIcon"></i>
......
</div>
I have two separate files (I would like to keep it separate because they are reusable parts and can be used separately throughout the application) acting as modules in SMACSS terminology:
Header:
.header {
/* header styles */
}
Icon:
.topIcon {
/* icon styles */
}
Now I want to apply some styles to my topIcon when header has :hover state.
I can put .header:hover .topIcon inside my icon module file and apply style, however from my POV it breaks SMACSS rules.
Do you have any better suggestions?

I use to do it by using Sass' & selector:
.topIcon {
/* icon styles */
.header & {
/* modified styles when it's in header */
}
.header:hover & {
/* modified styles when it's in header thats hovered */
}
}
The result would be
.topIcon {
/* icon styles */
}
.header .topIcon {
/* modified styles when it's in header */
}
.header:hover .topIcon {
/* modified styles when it's in header thats hovered */
}
That way, I keep the icon-related styles in the icon file, but avoid "foreign" classes at a root level.
A weak point of that way might be, that you might also have another rule for .header:hover in the header file, which might be confusing for others, where to place what.

Related

Spartacus custom styling - order of SCSS imports

I am working on custom styles for my Spartacus application and struggling with the order of the CSS rendered. Despite the order of imports in my styles.scss, my custom CSS rules are rendered in the middle of Spartacus default styling, forcing me to bump up the specificity of my rules to achieve desired results.
This is my styles.scss:
$styleVersion: 4.3;
#import '~#spartacus/styles';
#import './styles/custom/_index';
/* custom/_index.scss contains further imports of the actual styling */
and this is the snippet of the rendered CSS:
/* Spartacus defaults
...
*/
cx-wish-list-item .cx-return-button .btn-link:hover {
text-decoration: underline;
}
/* My custom code */
header .SiteLogo {
width: auto;
max-width: 150px;
}
/* Spartacus defaults continued */
cx-bulk-pricing-table table {
text-align: center;
}
/*
...
*/
Working with Spartacus 4.3 and Angular 12. My objective is to:
keep my custom code as simple and low-specificity as possible
be able to leverage Bootstrap and Spartacus variables and mixins in my SCSS
Is there a way to ensure my custom styles are rendered last, according to the imports order?
In the documentation they mention wrapping custom styles in the body tag in style.scss.
link here
Try wrapping your scss in the body tag. This worked for me.
body {
cx-wish-list-item .cx-return-button .btn-link:hover {
text-decoration: underline;
}
/* My custom code */
header .SiteLogo {
// width: auto;
width: 150px;
}
/* Spartacus defaults continued */
cx-bulk-pricing-table table {
text-align: center;
}
}
In order to control the order of styles, it is better to import the styles by yourself.
First, check the angular.json file (as there might be other Spartacus related style files) and keep only one styles file there:
"styles": [
"src/styles.scss"
],
Then, in styles file import all other styles in required order, e.g.:
#import '~#spartacus/styles/index';
#import './styles/custom/_index';

CSS of nested selector is not being applied to div

I utilised the BEM method and my <div> is showing the css from the Block and Modifier, but not the Element
i.e. the css for c-banner(block) and --warning(modifier) is appearing but not __icon(element).
I know that the color of the modifier is appearing because I tried changing it to another color and it appears on the UI.
Eg:
Currently:
&--warning {
color: #D9822B
}
Edited:
&--warning {
color: black
}
Once changed, the icon of --warning will show up with a black color on the UI.
However, the padding-right of __icon doesn't ever get applied.
c-banner {
/* Block CSS Properties */
&__icon {
padding-right: 12px;
&--warning { /* Used for warning purposes */
color: #D9822B;
}
&--primary { /* Used for general information */
color: #137CBD;
}
&--success { /* Used for verified access */
color: #0F9960;
}
&--danger { /* Used as a hard stop */
color: #DB3737;
}
}
}
I'm genuinely perplexed as to why the padding-right of __icon does not get applied but the color of --warning is
All you are missing is:
.c-banner ..... the dot before the classname
Also, for padding to work they have to be inside --warning because you are chaining to form the full selector and there is no selector that ends with __icon
You can style material-icons if you want to affect multiple:
.c-banner {
.material-icons { padding-right: 12px; }
/* can also do [class*="__icon"] but may be less predictable */
&__icon {
/* rest of the scss */
}
}

Is there a null or undefined or "falsy" value for css custom properties?

I want to create a component and expose certain properties that could be overridden by parent elements.
Here's an example. Let's say I'm creating a button which has its own colors, but allows to change its background color if there's a --button-bg-color defined:
.my-button {
--bg-color: blue;
/* lots of other css... */
/**
* here I assume that there might be a --button-bg-color defined,
* but I have a fallback to my own --bg-color variable
*/
background-color: var(--button-bg-color, var(--bg-color));
}
The problem with the code above is that the --button-bg-color variable is referenced somewhere deep down the styling.
What I wish I could do is the declare somewhere up top that I might want to use this variable. This would tell me that this component expects to be overridden.
Maybe something like this?
.my-button {
--button-bg-color: undefined; /* is there something like undefined? */
--bg-color: blue;
/* the rest of the code is the same */
}
Oh well, I just realized that we can do this:
.my-button {
--bg-color: var(--button-bg-color, blue); /* inherit with fallback */
/* lots of other css... */
background-color: var(--bg-color);
}
This way there's also less repetition.

How to change Polymer(1.0) paper-toolbar background colour?

Yesterday I decided to try Polymer 1.0 and I'm already facing difficulties when trying to styling the paper-toolbar.
The documentation says that the background colour can be changed by using:
--paper-toolbar-background
But how can I use it on CSS?
I tried the following:
paper-toolbar {
--paper-toolbar-background: #e5e5e5;
}
Also this:
paper-toolbar {
--paper-toolbar {
background: #e5e5e5;
}
}
But neither worked. What is the correct way to do it?
Thanks.
If you are styling it on your main page, then you have to apply styles using <style is='custom-style'>. This is to make Custom CSS Properties work.
Applying is relatively easy. paper-toolbar provides 2 custom properties and one mixin. --paper-toolbar-background is a property that changes the background color of the toolbar while --paper-toolbar-color changes its foreground color. --paper-toolbar is a mixin applied to the toolbar.
To use these properties is just the same as applying styles in your elements. As an example
<style is="custom-style">
paper-toolbar {
--paper-toolbar-background: #00f; /* changes the background to blue*/
--paper-toolbar-color: #0f0; /* changes the foreground color to green */
--paper-toolbar: {
font-size: 40px; /* Change default font size */
}; /* Notice the semicolon here */
}
</style>
I couldn't find a solution to this problem either until recently. I have two toolbars and I didn't want to change the CSS for all toolbars just the header toolbar.
To change the CSS for every toolbar, in your external css file add the following:
paper-toolbar.paper-toolbar-0 {
background: orange;
color: red;
}
However, that doesn't address the problem. To change a single paper toolbar based on a class like the following:
<paper-toolbar class="header">
...
</paper-toolbar>
The above uses the class called "header" so in my CSS I added:
paper-toolbar.header {
background: orange;
color: red;
}
... and it worked! Yay! That means with this you should be able to override any CSS of any of the other elements doing the same thing. This is completely untested but I think it should work like:
<elementName>.<classname> {
...
}
Hope this all helps!

Style webkit scrollbar on certain state

I'd like my WebKit scrollbars to have a different color when its container is hovered over. I want the entire scrollbar to light up.
I was thinking something like this would do the trick (but it doesn't):
.scroller:hover::-webkit-scrollbar {
background: green;
}
I've styled the scrollbars the same way: on .scroller, not globally. (That works: .scroller::-webkit-scrollbar) I want the overflowed divs special, not the document.
Another (related) problem: light up the thumb when hovering over the scrollbar. This doesn't work:
.scroller::-webkit-scrollbar:hover ::-webkit-scrollbar-thumb
This is possible using pure CSS, at least with Chrome version 29.
http://jsfiddle.net/eR9SP/
To style the scrollbar when its container (in this case .scroller) is hovered over, use:
.scroller:hover::-webkit-scrollbar { /* styles for scrollbar */ }
.scroller:hover::-webkit-scrollbar-thumb { /* styles for scrollbar thumb */ }
.scroller:hover::-webkit-scrollbar-track { /* styles for scrollbar track */ }
Additionally, you can style the scrollbar thumb itself when it's hovered over or active (being clicked) using the following:
.scroller::-webkit-scrollbar-thumb:horizontal:hover,
.scroller::-webkit-scrollbar-thumb:vertical:hover { /* hover thumb styles */ }
.scroller::-webkit-scrollbar-thumb:horizontal:active,
.scroller::-webkit-scrollbar-thumb:vertical:active { /* active thumb styles */ }
Changing the background color works just fine for me.
http://jsfiddle.net/QcqBM/1
div#container:hover::-webkit-scrollbar {
background: lightyellow;
}
Are you sure there isn't something else wrong with your CSS call?
There's a very easy way to do it -- just add the webkit scrollbar in the CSS using class, then remove it from your element using classList.remove on your element.
A few more details here

Resources