CSS Module with ClassNames Emotion migration - css

An example react file
const classNames = {
...defaultClassNames,
disabled: 'MyComponent--disabled',
selected: 'MyComponent--selected',
container: classnames('MyComponent', 'MyComponent-v2'),
};
return (
<MyComponent
classNames={classNames}
/>
An example CSS module file
.MyComponent-v2 {
.MyComponent-wrapper {
padding-bottom: 0;
}
.MyComponent:not(.MyComponent--disabled){
&:hover {
background: none !important;
.MyComponent-v2 {
background-color: red;
border-radius: 50%;
}
}
}
.MyComponent:focus,
}
How do I migrate this css module to emotion 10, all the examples I can find are using inline emotion with just a single css property like,
css={css`
background-color: hotpink;
&:hover {
color: ${color};
}
`}

Related

Nested onHover selector not working with styled-components

I'm trying to change the style of a styled-components element when another element is hovered over, however it doesn't seem to apply those changes.
The piece of relevant code is,
const Logo = styled.div`
. . .
&:hover {
color: red;
${TextStyled} {
display: flex;
}
}
`;
The color of the Logo component successfully changes to red on hover, however the display property of the TextStyled component doesn't seem to be affected.
What am I doing wrong here? I've tried adding a tilde before ${TextStyled}, but that selector didn't work either.
I've also tried applying the style through the parent Main component, but that didn't work either:
const Main = styled.div`
height: 100vh;
width: 100vw;
background: #000;
${Logo} {
&:hover {
color: red;
${TextStyled} {
display: flex;
}
}
}
`;
I think it doesn't work because it's not a child of the hovered element, so you could solve like this:
&:hover + ${TextStyled} {
color: red;
display: block;
}
Another way is put TextStyled into Logo like:
<Logo>Logo<TextStyled /></Logo>
And in logo const:
&:hover {
color: red;
${TextStyled} {
display: flex;
}
edit after comment:
For resolve your problem create another div then put logo and textstyled into that.
<Cont>
<Logo>Logo</Logo>
<TextStyled />
</Cont>
Then create rule:
const Cont = styled.div`
width: 100%; // just example
&:hover {
${TextStyled} {
display: block;
}
}
`;
and Logo:
const Logo = styled.div`
font-weight: 700;
color: #ffffff;
font-size: 4em;
letter-spacing: 5px;
transition: 0.25s;
z-index: 200;
&:hover {
color: red;
filter: blur(10px);
}
`;

I'm creating a reusable alert box in Angular 9. When I'm changing the alert type, the proper class is not applied

I'm trying to create a reusable alert component in angular 9. But I'm getting an issue. In the alert-box selector when I'm trying to give the alert type, it's not at all changing the alert type.
Only I'm getting the plain text. Styles are also not being applied.
Can someone please help me to fix this issue.
Usage:
<app-alert-box alertType="warning">
Hi this is alert
</app-alert-box>
My Code:
alert-box.component.html
<ng-container>
<div
[ngClass]="{
'alert-danger': alertType == 'danger',
'alert-info': alertType == 'info',
'alert-success': alertType == 'success',
'alert-warning': alertType == 'warning'
}"
class="alert"
role="alert"
>
<span class="alert-content" #alertContent>
<ng-content></ng-content>
</span>
<button (click)="alertClose()" *ngIf="closeButton" aria-label="Close">
X
</button>
</div>
</ng-container>
alert-box.component.scss
.alert {
padding: 20px;
color: white;
opacity: 1;
transition: opacity 0.6s;
margin-bottom: 15px;
.danger {
background-color: #f44336;
}
.success {
background-color: #4caf50;
}
.info {
background-color: #2196f3;
}
.warning {
background-color: #ff9800;
}
}
.closebtn {
margin-left: 15px;
color: white;
font-weight: bold;
float: right;
font-size: 22px;
line-height: 20px;
cursor: pointer;
transition: 0.3s;
}
.closebtn:hover {
color: black;
}
alert-box.component.ts
import { Component, OnInit, Input } from "#angular/core";
#Component({
selector: "app-alert-box",
templateUrl: "./alert-box.component.html",
styleUrls: ["./alert-box.component.scss"]
})
export class AlertBoxComponent implements OnInit {
#Input() alertType = "info";
#Input() closeButton = false;
#Input() autoClose = false;
#Input() autoCloseAfter = 5000;
alertOpen = true;
constructor() {}
ngOnInit(): void {
if (this.autoClose) {
const timer = setTimeout(() => {
this.alertClose();
clearTimeout(timer);
}, this.autoCloseAfter);
}
}
alertClose(): void {
this.alertOpen = false;
}
}
You classes are called alert-danger, alert-success,... but your css is just referring to alert, success
Change to css to
.alert {
padding: 20px;
color: white;
opacity: 1;
transition: opacity 0.6s;
margin-bottom: 15px;
&.alert-danger {
background-color: #f44336;
}
&.alert-success {
background-color: #4caf50;
}
&.alert-info {
background-color: #2196f3;
}
&.alert-warning {
background-color: #ff9800;
}
}
Stackblitz example

Why css hover is affecting only bookmarks?

I have 5 links on site, they are styled with css, and they should turn black after mouse hovers on them. Links to extrenal pages doesn't turn black, only links to bookmarks on page are turning black.
I tried diffrent styling and nothing works. It works normally without React and without the server.
css styling:
.menu_link {
border: none;
text-decoration: none;
color: darkgreen;
height: 100%;
width: 20%;
text-align: center;
font-size: calc(1em + 1vw);
font-family: pokemon-hollow;
}
.menu_link:hover {
color: black;
background-color: beige;
}
.menu_link:visited, .menu_link:link {
color: darkgreen;
}
MenuLink class:
import React from 'react';
import './MenuLink.css'
class MenuLink extends React.Component {
render() {
return (
<a href={this.props.href} target={this.props.target} className="menu_link" >{this.props.name}</a>
)
}
}
export default MenuLink;
Menu class:
import React from 'react';
import './Menu.css';
import '../MenuLink/MenuLink'
import MenuLink from '../MenuLink/MenuLink';
class Menu extends React.Component {
render() {
return (
<div id='menu'>
<MenuLink id="main_container" name="Home"/>
<MenuLink href="https://bulbapedia.bulbagarden.net/wiki/Fennekin_(Pok%C3%A9mon)" name='Fennekin' target='_blank' />
<MenuLink href="https://bulbapedia.bulbagarden.net/wiki/Braixen_(Pok%C3%A9mon)" name='Braixen' target='_blank' />
<MenuLink href="https://bulbapedia.bulbagarden.net/wiki/Delphox_(Pok%C3%A9mon)" name='Delphox' target='_blank' />
<MenuLink id="main_container" name="Galery"/>
</div>
)
}
}
export default Menu;
No errors, but when I force on hover on link in chrome developer tools i get this:
color: black;
You are overriding .menu_link hover styles with these
.menu_link:visited, .menu_link:link {
color: darkgreen; /*this will override .menu_link:hover styles*/
}
If css specificity is exactly the same, order does matter. Styles declared later will be applied.
So change your css to the below:
.menu_link:visited, .menu_link:link,.menu_link {
border: none;
text-decoration: none;
color: darkgreen;
height: 100%;
width: 20%;
text-align: center;
font-size: calc(1em + 1vw);
font-family: pokemon-hollow;
}
.menu_link:hover {
color: black;
background-color: beige;
}
The problem was the order of lines.
.menu_link:visited, .menu_link:link {
color: darkgreen;
}
were after
.menu_link:hover {
color: black;
background-color: beige;
}
and they were overwriting hover selector. Changing the order to:
.menu_link:visited, .menu_link:link {
color: darkgreen;
}
.menu_link:hover {
color: black;
background-color: beige;
}
was what fixed the problem.
Bookmarks links weren't affected, probably because they can't have state :visited or :link.

How to style :root without !important using proper specificity

Inside a Custom Element because border-color is set on the parent page, I can not make border-color work without resorting to !important
:host([player="O"]) {
color: var(--color2);
border-color: var(--color2) !important;
}
The selector works fine, the color is set,
so it is a Specificity issue
Question: Is it possible without !important ?
Working snipppet:
window.customElements.define('game-toes', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({
mode: 'open'
});
shadowRoot.innerHTML = 'Toes';
shadowRoot.appendChild(document.querySelector('#Styles').content.cloneNode(true));
}
});
:root {
--boardsize: 40vh;
--color1: green;
--color2: red;
}
game-toes {
width: var(--boardsize);
height: var(--boardsize);
border: 10px solid grey;
background: lightgrey;
display: inline-block;
}
<TEMPLATE id="Styles">
<STYLE>
:host {
display: inline-block;
font-size:2em;
}
:host([player="X"]) {
color: var(--color1);
border-color: var(--color1);
}
:host([player="O"]) {
color: var(--color2);
border-color: var(--color2) !important;
}
</STYLE>
</TEMPLATE>
<game-toes player="X"></game-toes>
<game-toes player="O"></game-toes>
qomponents
You are using CSS variable so you can still rely on them like this:
window.customElements.define('game-toes', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({
mode: 'open'
});
shadowRoot.innerHTML = 'Toes';
shadowRoot.appendChild(document.querySelector('#Styles').content.cloneNode(true));
}
});
:root {
--boardsize: 40vh;
--color1: green;
--color2: red;
}
game-toes {
width: var(--boardsize);
height: var(--boardsize);
border: 10px solid var(--playercolor,grey);
color:var(--playercolor,#000);
background: lightgrey;
display: inline-block;
}
<TEMPLATE id="Styles">
<STYLE>
:host {
display: inline-block;
font-size:2em;
}
:host([player="X"]) {
--playercolor: var(--color1);
}
:host([player="O"]) {
--playercolor: var(--color2);
}
</STYLE>
</TEMPLATE>
<game-toes player="X"></game-toes>
<game-toes player="O"></game-toes>
<game-toes ></game-toes>
As a complement to #Temani excellent answer: it happened because the element CSS style for <games-toes> will supersede the shadow root :host style.
According to Google's presentation:
Outside styles always win over styles defined in shadow DOM. For example, if the user writes the selector fancy-tabs { width: 500px; }, it will trump the component's rule: :host { width: 650px;}

What is the meaning of & in css styling in react js

I have recently started learning to react js. I noticed that in some of the style.ts files & has been used before the class declaration.
export const agGrid = {
extend: [container],
'& .ag-theme-material': {
marginTop: '2rem'
}
};
Can someone please help what is & for? I think the framework used is jss that is visible from package.json file
& is used to reference selector of the parent rule.
const styles = {
container: {
padding: 20,
'&:hover': {
background: 'blue'
},
// Add a global .clear class to the container.
'&.clear': {
clear: 'both'
},
// Reference a global .button scoped to the container.
'& .button': {
background: 'red'
},
// Use multiple container refs in one selector
'&.selected, &.active': {
border: '1px solid red'
}
}
}
Compiles to:
.container-3775999496 {
padding: 20px;
}
.container-3775999496:hover {
background: blue;
}
.container-3775999496.clear {
clear: both;
}
.container-3775999496 .button {
background: red;
}
.container-3775999496.selected, .container-3775999496.active {
border: 1px solid red;
}
Find out more over here - http://cssinjs.org/jss-nested?v=v6.0.1
& is basically using to denote the parent in a nested sass/scss.
agGrid = {
'& .ag-theme-material': {
marginTop: '2rem'
}
Will be converted as
agGrid .ag-theme-material {
margin-top: 2rem
}
into CSS
Or in another example using SCSS
.wrapper {
&:before, &:after {
display: none;
}
}
will be converted into
.wrapper::before {
display: none;
}
.wrapper::after {
display: none;
}

Resources