My CSS subclass isn't rendering, but the parent does - css

I have a component <WarningOutlined className="verify-icon__warning"/>.
When I use the className verify-icon it displays the default, but none of the styles preceded by __ render.
I've also tried importing an object from another file that's used to render a list of these icons and returning the component that way, but it also doesn't render.
I wondered if it's because I'm using two stylesheets in this file, but I commented out references to the other one and it still doesn't render.
The class is defined as such
.verify-icon {
font-size: 18px;
&__default {
color: $color-dark-gray;
}
&__warning {
color: $color-ant-gold;
}
&__info {
color: $color-blue;
}
&__success {
color: $color-primary-green;
}
}

Related

CSS: Store font icon code in css variables

I have a custom icon font (generated with Icomoon).
body {
--pseudo-element-content: '\e900';
div::before {
font-family: 'CustomFont';
content: var(--pseudo-element-content);
}
}
However, when doing this, my pseudo element doesn't appear in my browser (as if it didn't have any content). It looks like my css variable has the icon value interpreted and not its code.
If I change it to
div::before {
font-family: 'CustomFont';
content: '\e900';
}
it works like a charm. I tried a few tricks (string concat, adding ' and escaping them) but it didn't work.
I've tried it and it work with another character (see the snippet).
It seems that you don't have that font on your OS and the browser can't render it.
body {
--pseudo-element-content: "\016E";
}
div::before {
font-family: "CustomFont";
content: var(--pseudo-element-content);
}
<div><-- </div>
CSS variables are placed in the rules, not at the top level:
selector {
padding: 100px;
--some-var: 'abcdef'
}
Variables are inherited like the ordinary CSS rules.
If you want the variable to be visible everywhere, add it to html (or :root):
html {
--pseudo-element-content: '\e900';
}
Answer to edited question:
You are trying to place the styles inside each over, which is not supported in CSS. Perhaps, originally code was for CSS preprocessor - SASS.
The fix:
body {
--pseudo-element-content: '\e900';
}
div::before {
font-family: 'CustomFont';
content: var(--pseudo-element-content);
}

How is it possible to adjust a component's CSS based on a global CSS class-name in Angular?

We are using a class on the html-element to determine whether the user is in dark or light mode of the app.
<html class="dark-mode"></html>
This class is added using Renderer2 in a service that detects the selected setting of the user. This works fine so far.
Now, we have to adjust all the components to look good in the dark mode as well. But the problem is Angular's ViewEncapsulation.
What we thought would come in handy, is to simply update the SCSS of the component:
.headline {
color: black;
.dark-mode & {
color: white;
}
}
Or in plain CSS:
.headline {
color: black;
}
.dark-mode .headline {
color: white;
}
Now this doesn't work, because the class .dark-mode seems to be encapsulated, as expected.
How can we solve this problem?
:host-context provides access to css classes above the :host. By using :host-context you are able to check if any of the parents of the host have a specific css class and apply styling:
:host-context(.dark-mode) h2 {
color: white;
}
Documentation: https://angular.io/guide/component-styles#host-context

CSS Modules: selecting child class through selectors

So,
I have appended a home class to body like so:
document.body.classList.add("home")
I want to select appContainer a child element of body class by doing
html body.home #appContainer { ..... }
This works without CSS Modules but was wondering how I can do it with CSS modules. Thanks
You need to use wrap the class that you want to be global into :global(). If your selector uses an element you must write it directly after the element with no space in between, like element:global(.class) which translates into element.class.
Therefore, in your case html body:global(.home) #appContainer is the answer.
For anyone else that comes across this issue, I am using postcss-preset-env and I had to do this:
Worked ✅
.toolTipTest :global .rc-tooltip-arrow {
color: blue;
}
This did not work ❌
.toolTipTest:global(.rc-tooltip-arrow) {
color: blue;
}
And neither did this ❌
.toolTipTest:global(.rc-tooltip-arrow) {
color: blue;
}
// Neither Did this
.toolTipTest {
&:global(.rc-tooltip-arrow) {
color: blue;
}
}

How to reference SCSS sibling?

Assuming that I have the following HTML:
<div class="navigation__item">
<span class="navigation__item__icon"></span>
</div>
I want to apply some rules to an icon, when hovering an item, which can be described with the following CSS:
.navigation__item__icon {
color: black;
}
.navigation__item:hover .navigation__item__icon {
color: white;
}
I can achieve this using the following SCSS:
.navigation__item {
&:hover {
.navigation__item__icon { <-- here
color: white;
}
}
&__icon {
color: black;
}
}
Here, is there any way to avoid writing navigation__item? Something like "parent rule \ element".
I like Sass for logical structure so that if I want to rename the whole navigation block with elements, I can simply change navigation class name in the root, and everything is renamed. This case breaks this advantage.
Update: Actually, I have found a way to do this without using {} braces. & can be repeated more than once:
.navigation__item {
&:hover &__icon {
color: white;
}
&__icon {
color: black;
}
}
It is great, but it doesn't make much sense if I have many rules and rules for &:hover itself. The question is still open - is this possible to access sibling element definition from within the {} block.
In Stylus there is a Partial reference but I don't know anything similar in SASS. One solution could be using a variable for the parent selector:
.navigation__item {
$selector: &;
&:hover {
#{$selector}__icon {
color: white;
}
}
&__icon {
color: black;
}
}
Is usefull is you change navigation__item class for another.
EDIT: I had used a wrong example, it's OK now.

Name clash between Less mixin and CSS selector

I have this simplified Less script
.placeholder(#color: #333333) {
&::-webkit-input-placeholder { color: #color; }
}
input {
.placeholder();
}
.placeholder {
margin-top: 20px;
}
The output when I run this through my local compiler or winless online less compiler is
input {
margin-top: 20px;
}
input::-webkit-input-placeholder {
color: #333333;
}
.placeholder {
margin-top: 20px;
}
Insted of the desired output
input::-webkit-input-placeholder {
color: #333333;
}
.placeholder {
margin-top: 20px;
}
Is this a bug or am I missing something here?
By the result it looks to me like I can't have CSS-selectors with the same name as mixins with default values.
I'm running into this problem when compiling Bootstrap with my site specific code. In this particular case I can work around it, but as the project grows and I include other projects I can't imaging I have to keep track of any mixins with default values?
Edit: I see now that I should have read the manual and pretty much seen on the first page of the docs that everything can be treated as a mixin.
In Less, everything is technically a mixin irrespective of whether we write it with parantheses (as in with parameters) or without parantheses (as in like a CSS class selector). The only difference between the two is that when the parantheses are present, the properties present within it are not output unless called from within a selector block.
Quoting the Less Website:
It is legal to define multiple mixins with the same name and number of parameters. Less will use properties of all that can apply.
In this case, since the other mixin has a default value for its only parameter, both the properties can apply when called without any parameter and hence there is no way to avoid it from happening.
Workaround Solution: One possible solution to work-around this problem is to enclose all such conflicting rules within a parent selector (like body).
.placeholder(#color: #333333) {
&::-webkit-input-placeholder { color: #color; }
}
input {
.placeholder();
}
body{
.placeholder{
margin-top: 20px;
}
}
Compiled CSS:
input::-webkit-input-placeholder {
color: #333333;
}
body .placeholder {
margin-top: 20px;
}
Option 2: Extracted from the solution posted by seven-phases-max in the Less GitHub Issue thread.
For the particular use-case one of possible workarounds is to isolate conflicting classes in unnamed scope so they won't interfere with external names:
.placeholder(#color: #333333) {
&::-webkit-input-placeholder { color: #color; }
}
input {
.placeholder();
}
& { // unnamed namespace
.placeholder {
background: #ffffff;
}
} // ~ end of unnamed namespace
Note: The above is a straight copy/paste from the GitHub thread without any modifications so as to not tamper with the information.
#mixin placeholder(#color: #333333) {
&::-webkit-input-placeholder { color: #color; }
}
input {
#include placeholder();
}
.placeholder {
margin-top: 20px;
}
that should work.
So if i understood right, you just want to add 20px on top of the placeholder ? Add padding-top to input instead.
input {
padding-top: 20px;
}

Resources