I have a component with a button. It has a default class and a class passed to its from the props. But sometimes the default class overwrites the class from the props. Is it possible to increase the specificity of the class from the props or lower the specificity of the default class?
Do not suggest using !important
Do not suggest to prescribe default styles for the button tag, I do not want to apply them to all buttons in the project
Assigning an id for each button is also not an option
In the props, it is the class name that needs to be passed, not the style
import React from 'react'
import styles from './Button.module.scss'
import classNames from 'classnames'
const Button = ({ children, className, ...props }) => {
return (
<button {...props} className={classNames(styles.btn, className)}>
{children}
</button>
)
}
I can't find a beautiful and convenient solution. Now I'm adding !imortant in a class of props.
I just hope there's some css or js trick I'm not aware of.
Any additional selector will be increase priority of passed classname
component.module.scss:
button.passed-class-name {
color: red;
}
button.module.scss:
.btn {
color: green
}
Component.js
import styles from './component.module.scss'
import { Button } from 'components/Button'
const Component = () => {
<Button className={styles.passedClassName} />
}
The ideal solution could not be found. I decided not to reinvent the wheel and write a UI kit for the project, like everyone else.
UI kit styles are connected earlier, so styles from parents will rewrite them without !important and without increasing specificity.
Related
I wanted to add an "i" element as a child element to HTMLDivElement
but styles are not applied to the newly inserted "i" element.
How can I make sure to apply the same styles to newly added "i" element?
I want to apply the the styles that I have set in the scss file for the new element.
(when I am inserting the new element in the .ts file, I can set the same styles using JS(TS), but I intend to use the scss/css styles, is there any way to use the scss/css styles for the newly added elements?)
accommodation-view-data.html
<div class="star-rating" #starRating>
<i class="bi bi-star-fill"></i> <!-- styles are applied to this element successfully -->
</div>
accommodation-view-data.component.scss
i{
font-size: 1.6rem;
padding: 0 0.25rem ;
color: #ffbe0f;
}
accommodation-view-data.component.ts
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '#angular/core';
#Component({
selector: 'app-accommodation-view-data',
templateUrl: './accommodation-view-data.component.html',
styleUrls: ['./accommodation-view-data.component.scss']
})
export class AccommodationViewDataComponent implements OnInit, AfterViewInit {
#ViewChild('starRating')
starRatingElem!: ElementRef;
constructor() { }
ngOnInit(): void {
}
ngAfterViewInit(): void {
/* When I append the the new element to the DOM,
* the styles that I have set in the scss file, are not applied for the new element */
const starIconElement = document.createElement('i');
starIconElement.classList.add('bi');
starIconElement.classList.add('bi-star-fill');
(this.starRatingElem.nativeElement as HTMLDivElement).append(starIconElement);
}
}
This is a normal behavior, When you write style that is integrated in the styleUrls, every single class is reworked to be specific to the component, it's the style scope (note the i[ng-content-lep-c52]in the screenshot below).
So adding an element in the dom like you do is not recommended, instead prefer toggling it thanks to a ngIf or here for stars with a ngFor or else you'll have hard times trying to make it dynamic and bind values with the component model.
Like you can see in this screenshot, the first element is properly matched with the scoped style while the new element isn't.
NOT RECOMMENDED AND DEPRECATED: To bypass this you can use the ::ng-deep pseudo class to make a style global, and therefor getting overrided by scoped style as you can see in this screenshot comming from this stackblitz.
You can find more information about styles in angular here
Ok, so, i have a component that takes a className as a prop, but the component itself comes with an default style.
className={`${
props.classNameStyle ? `${styles.defaultButtonStyle} ${props.classNameStyle}` : styles.defaultButtonStyle
}
If className prop exists, it should put as classes both the default class and the class passed as prop, and otherwise, to put just the default class. It works, but, i want the class passed as prop to have a bigger CSS specifity than the default button, because, let's say that we have :
.defaultButtonStyle { background-color:red }
and
.classNameStyle { background-color:blue } (this is the class from props)
it should make the background color blue, but in the browser's console, the classNameStyle it's cut, and the background-color is set to the default button style. I don't want to use !important, because that's gonna be annoying for the user. Any ideas?
I want to use CSS Modules, but it seems as if vue lacks a mechanism to provide the generated class names to child component.
Suppose I have two components:
Table.vue
TableRow.vue
And styles like this:
.table {
table-layout: auto;
&.hover .row:hover .cell {
background-color: red;
}
}
The generated styles for .row:hover do not apply to TableRow anymore, and I haven't found a nice way to pass it to the child. The only thing I tried that works, but which is very ugly is passing the $style object down to the child. Once the component tree gets bigger, this is very annoying because every Component needs a prop and has to pass the $style-object on to the next children...
You can assign class to a component using v-bind if they are coming from a variable
<div :class="list_view === 'list' ? 'at-listview' : 'at-groupview'"></div>
In above example list_view is a variable
If you want to send these classes to any component, again the concept is same but this time sending classes in a prop
<child-component classes_to_send="class1 class2 class" />
OR (using colon : to bind a variable )
<child-component :classes_to_send="class_from_variable" />
Now you can get these classes in <child-component/> props as shown below:
<script>
...
export default:{
props:['classes_to_send'],
}
...
</script>
<template>
<div :class="classes_to_send"></div>
</template>
I am trying to apply styling to a child of a custom component.
Selector:
<custom-component-example></custom-component-example>
Inside custom-component-example.html:
<button>
<ng-content></ng-content>
</button>
If I were to use style like this:
<custom-component-example style="color: green">some text</custom-component-example>
Or like this:
<custom-component-example [ngStyle]="{'color': green}">some text</custom-component-example>
The button text will not get green. The styling could be anything (for example font-weight or size or anything really).
I have also tried the solution to this topic:
Best way to pass styling to a component
But that also does not apply to the child element (button in the example above).
How do I pass any given styling and apply it to the child element, in the case of the example, how would I pass styling (through the custom-component-example selector) and apply it to the button and the button's text?
Thanks in advance.
You should never alter the child style from the parent, instead here is what you should do :
Apply a class to the parent (let's say green-button).
In the child's css you need to check that does my parent has a class green-button, if yes then it should change it's color.
In the child's css file ->
:host-context(.green-button) button{
color : green
}
You should not transfer styles from parent to child essentialy because it spoils the ViewEncapsulation goodness that Angular is proud of.
Here is some refrence . : Link
Also, the child component should be responsible for how does it button looks. The parent should be concerned about itself. In the future, if you will have two children to your parent, it will be difficult to manage what style to pass to what child.
Using this method, altering style is not only easy but also manageable.
Upvote and mark as solved if I was able to help.Cheers.
You need to pass the style property to the child component using the #Input() like
Your child component HTML code should look like
<div [className]="tableCss">
</div>
Your child component ts file code shoule look like
#Input() tableCss: string;
Your Parent component should look like
<app-list [tableCss]="'table-responsive table-borderless table-grid mt-4 border-top border-primary'"></app-list>
Try to change styles into [styles]
custom-component-example.html
<button [ngStyle]="styles">
<ng-content></ng-content>
</button>
custom-component-example.ts
#Input() styles: any = {};
Use,
<custom-component-example [styles]="{color: green}">some text</custom-component-example>
If you would like to use input and styles without deep selectecting of css like that:
a > b > c {
color: green;
}
Change this class to this:
class CustomComponentExample {
#Input() styles;
}
Set styles for this input:
<custom-component-example [styles]="{'color': green}">some text</custom-component-example>
Use this property in your component:
<button [ngStyle]="styles">
<ng-content></ng-content>
</button>
Try this:
Add a class on that component into your template file like this example bellow. (class='toggle-button').
<custom-component-example class="toggle-button"> Button name </custom-component-example>
Use ::ng-deep to your scss file for styling this class and add !important to that parameter.
::ng-deep .toggle-button { .switch-btn {
width: 80px !important;
height: 40px !important;}}
*"switch-btn" class is a class into the parent component.
I'm trying to append an active state in a React JS component when it is clicked.
Lets say I have a function
onMenuClick(e)
And my css class is called
.hamburger
I want to check the condition:
onMenuClick(e) {
if (this.state.menuOpen){
//append 'is-active' to the hamburger class
}
}
What is the most React-friendly/correct way to do this?
Use classnames as the official docs suggest.