CSS styling precedence when using React and CSS modules - css

I have a css module which apply styling to an existing component. The css module works fine but the styling was always overwritten by the default style of component.
Supposed I have this markup.
<Header className={styles.header}>
<Row type="flex" justify="space-between">
<Col>
<Link to="/">
<Title className={styles.brand}>Shiritori</Title>
</Link>
</Col>
</Row>
</Header>
Then uses the styles declare in the css module:
.header {
background: rgb(75, 191, 107);
margin-bottom: 1rem;
> div {
align-items: center;
}
}
I expect that the background css property of the default style will be overwritten but instead the styles in my css module was canceled out.
Actual result:
.ant-layout-header {
height: 64px;
padding: 0 50px;
line-height: 64px;
background: #001529;
}
.ant-layout-header, .ant-layout-footer {
-ms-flex: 0 0 auto;
flex: 0 0 auto;
}
.ant-layout, .ant-layout * {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.App_header__37gyT {
background: #4bbf6b; <- this property was overwritten by the .ant-layout-header background property
margin-bottom: 1rem;
}
I also consider the order of css/scss import but same result.
import "../../../node_modules/antd/dist/antd.css";
import styles from "./App.module.scss";
Is there a way to overwrite existing style of a component. I use antd for the UI toolkit and components.

Unable to replicate your issue. Seems to be working fine:
That said, when dealing with CSS specificity, you can do one of several things:
Overwrite a child class style from a parent class style.
Use the id property: <Header id="header-id">Header</Header> (then use the # to refer to header: #header-id { ... })
Overwrite the .ant-layout class name within a separate CSS/SCSS file.
Add an !important declaration after the style property, for example: background: pink !important;
That said, I'd avoid importing the entire CSS library and instead use the babel plugin to import only what's needed.

Related

React Component SCSS available for all Components

I just started learning ReactJS and I made a Project with .scss
For some reason when I add a style in a .scss file that style also changes other components' styles as well.
example:
I add a li style in the Home.scss, but it will change the style of the Footer component's li too. I didn't import it into the Footer.js or anything.
Does anyone know what is the reason why does it do it, and what is the solution?
Adding a className per component won't solve your problem, it will work as expected until you have any nested component.
Because if you add
#component-name {
li {
...
}
}
The CSS will be applied to any component inside of that component too.
To limit your CSS to a component in react, you have a few options :
CSS Modules
Create React App supports CSS Modules out of the box (as of version 2)
It works with SCSS too (YourComponent.module.scss)
YourComponent.js:
import styles from './YourComponent.module.css'
export const YourComponent () => {
<ul>
<li className={styles.yourLi}>
</ul>
}
YourComponent.module.scss:
.yourLi {
color: blue;
}
CSS-in-JS
With this method, as the name suggests, you can declare your CSS within your JS.
There are multiple libraries to implement this.
Styled-Components
Here is an example with styled components which is the one that seems to be the most used as of today:
const YourLi = styled.li`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
`
render(
<div>
<ul>
<YourLi>
Your styled li
</YourLi>
</ul>
</div>
)
Add a class footer in the first div of footer component
sass allows nested defining of classes like
.footer{
li{
}
}
using that can help.
since it doesn't matter where you import scss in react. styles are imported globally by default.

Styling Material UI Button

Hi I just started using Material UI and am having a hard time styling the components. I am building a sign in page and would like my Submit button to be all the way to the bottom right. If someone can help me out that would be greatly appreciated because it seems to be inheriting styles from everywhere else but where I would like to!
I have tried adding
textAlign: 'right'
to buttonStyle and that does not work. I have also tried adding
text-align: right;
to my .form-button CSS.
The only thing that affects anything is removing the .App
Login.js
<div className='form-container'>
...
<Button
style={buttonStyle}
className='form-button'
variant='contained'>
Log-In
</Button>
</div>
...
const buttonStyle = {
backgroundColor: '#527354'
};
App.css
.App {
text-align: center;
}
.form-button {
width: 83px;
height: 36px;
box-shadow: 0px 1px 3px #00000033;
}
.MuiButton-label {
color: var(--primary-white);
font-family: 'Open Sans', sans-serif;
}
.form-container {
max-width: 400px;
margin: 2rem auto;
overflow: hidden;
padding: 0 2rem;
}
Another main goal would be to avoid inline styling because I do prefer keeping it within my style sheet. But if not possible or too overly difficult, I will inline style (as I did with the background-color).
As keikai has mentioned in the comment, you may check the Documentation in this link material-ui.com/styles/basics for overriding style.
For 'it seems to be inheriting styles from everywhere else'
I will suggest you to use styled-components instead of global css import, which mess up everywhere. Try this,
npm install --save styled-components
It creates a css class that only apply to the component.
Sample code:
import styled from 'styled-components'
const MyDiv = styled.div`// can be span, section, etc
// add your style here for the div
your div style(optional)
// your class css inside the div
.form-container {
max-width: 400px;
margin: 2rem auto;
overflow: hidden;
padding: 0 2rem;
}
// add more class if you have any
`
Then wrap your component with
// your newly created styled div
<MyDiv>
// component that needs your style
<MyComponent />
</MyDiv>
Your style will only be applied to MyDiv and MyComponent, and nothing else.
It may took awhile to get used to it, but it is extremely useful.

How to style a PrimeNG Chips?

I have a form in my application where I use the following code from Primafaces:
...other inputs...
<label for="workshopTags">Tags</label>
<p-chips
[(ngModel)]="values"
name="workshopTags"
id="workshopTags"
></p-chips>
I am able to display the Chip element correctly but I would like to style it putting its width to 100% and the height to 100px, but nothing seems to work to change those. This solution didn't work for me. I tried to set a styleClass or an inline style as the documentation suggest but they didn't work either. If I write inline:
style="width: 100%"
The following error is thrown:
Error: Cannot find a differ supporting object 'width: 100%;'
How can I make it work?
there are tow methos to style primeng component overwrite the original style or by create a custom style base on custome class
overwrite
add the style to global style.css or style.scss , this method for overwrite primeng component style without add extra class to the component.
.ui-chips {
display: inline-block
}
.ui-chips ul {
border:2px dashed green !important; /* 👈 I have use important */
}
.ui-chips > ul.ui-inputtext .ui-chips-token {
font-size: 14px;
background: green !important; /* 👈 I have use important */
border:1px solid #005555;
box-shadow: 0 0 25px #ccc;
}
stackblitz demo 🍏🍏
custome style
the method above will change the style of all p-chips component in the entier project , by this method you need to set styleClass property so you can create different style like the example here 👇 , but you need to set styleClass property for every component
<p-chips [(ngModel)]="values" styleClass="p-chips"></p-chips>
style.css
.p-chips.ui-chips {
/* border:1px solid #ff2200; */
display: inline-block
}
.p-chips.ui-chips ul {
border:2px dashed orange;
}
.p-chips.ui-chips > ul.ui-inputtext .ui-chips-token {
font-size: 14px;
background: orange;
border:1px solid #ff5555;
box-shadow: 0 0 25px #ccc;
}
stackblitz demo 🍊🍊
You can use ht /deep/ modifier ,add this inside your app.component.css and delete it from your style.css, and you don't need !important to force the style here, delete it. here is what you are looking for
p {
font-family: Lato;
}
/deep/ .p-chips > .ui-inputtext {
width: 100%;
height: 100px;
}
check it here https://stackblitz.com/edit/angular-primeng-startup-kmm7xw
You could try encapsulation: ViewEncapsulation.None in your override component decorator:
#Component({
selector: 'app-chip',
templateUrl: 'path-to-template where you use ui-chips',
styleUrls: ['path-to-styles where you could override ui-chips styles'],
encapsulation: ViewEncapsulation.None
})
export class AppChipComponent { }
To set the width to 100%, you have to use the style or styleClass attribute and set the css property display: block.
As an example using the styleClass attribute
<p-chips
[(ngModel)]="interests"
styleClass="block">
</p-chips>
Here I am using Prime Flex v3 with PrimeNg.

md-menu override default max-width in Angular 2

I'm using Angular 2 , Angular Material and I am willing to display more data in a md-menu and, therefore, I need to set the max-width of the md-menu to a higher value. Its default value is of 280px.
<img src="/assets/images/ic-notifications.png" [mdMenuTriggerFor]="appMenu"/>
<md-menu #appMenu="mdMenu" [overlapTrigger]="false" yPosition="below" xPosition="before" class="notifications-dropdown">
<button md-menu-item >
<div class="row notification-row">
<div>
<span class="image-container"> Option 1 </span>
</div>
</div>
</button>
</md-menu>
In CSS file, I do this:
.mat-menu-panel.notifications-dropdown {
max-width:none;
width: 100vw;
margin-left: -8px;
margin-top: 24px;
overflow: visible;
}
.notification-row{
width: 424px;
}
In console, I can identify the class where the default value is set: max-width:280px; , and when I edit it in my console, it works perfectly, but even though I try to override it in my CSS code, I am not able to do that. I tried this, also:
.mat-menu-panel{
max-width: 600px;
}
And this:
.cdk-overlay-container .mat-menu-panel{
max-width:600px;
width: 100vw;
margin-left: -8px;
margin-top: 24px;
}
How can I override this default value?
Set the View Encapsulation to None on your component:
#Component({
templateUrl: './my.component.html' ,
styleUrls: ['./my.component.css'],
encapsulation: ViewEncapsulation.None,
})
Then in your component css you can do exactly what you tried:
.mat-menu-panel.notifications-dropdown {
max-width:none;
width: 100vw;
margin-left: -8px;
margin-top: 24px;
overflow: visible;
}
.notification-row{
width: 424px;
}
View Encapsulation = None means that Angular does no view
encapsulation. Angular adds the CSS to the global styles. The scoping
rules, isolations, and protections discussed earlier don't apply. This
is essentially the same as pasting the component's styles into the
HTML.
In some cases the wrapper over .mat-menu-panel can be .cdk-overlay-pane, in that case css should be something like this.
.cdk-overlay-pane.mat-menu-panel {
max-width: your_custom_value
}
Due to the css specificity rules, 2 classes of specificity are required in order to override the defaults.
The same crazy problem for me... how I solved:
::ng-deep .cdk-overlay-pane .mat-menu-panel {
max-width: 436px;
}
At component SASS file
See: Angular Component Styles - View Encapsulation
and issue comment by #gaiki https://github.com/angular/material2/issues/4462

Angular2 css :host applying but not visible in browser

I am having a bizarre issue whilst creating my first Angular2 app.
I am applying some CSS to a component host (example-component) yet it doesn't appear in the browser?
This is my first time posting for Angular in SO, so hopefully I include everything needed to attain some help.
example.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'crate',
templateUrl: './app/folderA/folderAB/crate.html',
styleUrls: ['./app/folderA/folderAB/crate.css']
})
export class MyComponent {}
index.html
crate.html
<div class="background">
<div class="content">
<p>Content</p>
</div>
</div>
crate.css
:host-context(.lg){
width: 100%;
background-color: #000;
border-radius: 25px;
}
What I don't understand, is that I open this in chrome & firefox, and I see the following CSS stated under rules for example.component.
.lg[_nghost-ims-2], .lg [_nghost-ims-2] {
width: 100%;
background-color: #000;
border-radius: 25px;
}
It is correctly applying the CSS to example-component, but it is not being displayed / rendered in browser. What am I doing wrong / missing?
EDIT
The exact same issue applies even if I change crate.css to:
crate{
width: 100%;
background-color: #000;
border-radius: 25px;
}
Any component with an unrecognized tagName like <crate></crate> is created as a HTMLUnknownElement and has empty values for all the style properties, if you want it to behave like a div then add display: block; to your stylesheet.
See Browsers' default CSS for HTML elements for additional resources on the default css for different browsers.

Resources