Styles are not working in through styled components - reactjs

I am trying to add background-color through styled component.
If add the styles through style={} attribute it is working as expected but If I add the same style in my styled component file it is not working.
//this is working
<MyStyle style={{backgroundColor: '#fff' }}>
//some component here
</MyStyle>
//This is not working.
export const MyStyle = styled.div`
background-color: ‘#fff’;
`;
Can somebody point me here what I am missing here?

The first example is simply using the react style builtin, you don't need styled components to do this.
The code in the second example, you need to remove the quotes around the color, like this:
//This is not working.
export const MyStyle = styled.div`
background-color: #fff;
`;
Styled components takes css syntax, which unlike json syntax, does not have quotes around option names, color names, etc.

You don't have to put single quote around #fff
export const MyStyle = styled.div`
background-color: #fff;
`;
EDITED:
If there are overriding CSS styles that make your div's background not white just yet, and you can't find them, just add !important to this style
export const MyStyle = styled.div`
background-color: #fff !important;
`;
Regarding the issue about finding existing CSS styles that might be overriding your preferred style, take a look at this: https://www.styled-components.com/docs/advanced#existing-css

Related

Restyling Bootstrap Components with React/Typescript styled components

I hava menu bar from bootstrap, but I would like to change some colors, e.g.button styles.
import Button from 'react-bootstrap/Button';
<Header__Button>
Something
</Header__Button>
const Header__Button = styled(Button)`
color: '#003D58';
background: 'transparent';
`;
This was my approach to do it, but it does not work. What is the correct and working way to handle this ?
The styled-components package uses the same syntax that use would use in a CSS stylesheet rather than in a Javascript object. So you don't want to use quotes around the values. Removing them will fix it:
import Button from "react-bootstrap/Button";
import styled from "styled-components";
const Header__Button = styled(Button)`
color: #003D58;
background: transparent;
`;
You can do like this,
const styles = css `
.custom-button {
color: '#003D58';
background: 'transparent';
}`;
<div css={styles}>
<Button className='custom-button'>Hello</Button>
</div>

Reusing existing CSS in styled-component

We've a large project that exist of multiple styled components.
But for a next release and design update of that component we'll working together with a new partner that will deliver the styleguide and a CSS file that they are created for our client.
So I'm looking how I can re-use the styles of our partner in a styled component.
Do you think it's a good idea to do something like:
const PrimaryButton = styled(".btn-primary)``.
Instead of:
const PrimaryButton = styled.button``;
Actually, I can not find any working example, thus I think it's not possible... So, does someone know how I can do something like this?
Ehm, and for some reason I want to avoid to have something like this...
<PrimaryButton className="btn-primary"></PrimaryButton>
You can reuse styled components by extending the styles.
const Button = styled.button`
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// A new component based on Button, but with some override styles
const PrimaryButton = styled(Button)`
color: blue;
border-color: blue;
`;

Question about mixing styled-components with material-ui

Hello I am a react newbie and new to styling as well :)
I am trying to style the material-ui Button component with styled components
I am doing this by overriding global class names, I know material-ui introduced global class names like MuiButton-root etc
I am not clear on the use of "&" in parent selector, for example:
const StyledButton = styled(Button)`
&.MuiButton-root {
width: 500px;
}
.MuiButton-label {
color: ${props => props.labelColor};
justify-content: center;
}
`;
The above code works and can achieve the following:
The Button has a width of 500px
The label has a color of red (labelColor is passed in as a prop)
Please see sandbox below for full code
Question:
Why do I need "&" selector for the MuiButton-root, whereas for the MuiButton-label I don't?
Also is this the best way to style material-ui with styled components?
Please see the following sandbox: https://codesandbox.io/embed/practical-field-sfxcu
The '&' selector is used to target the classes and neighbouring elements/classes. Take a look at cssinjs. Its the underlying system behind MUI's styling.
But in short to answer your question;
const StyledButton = styled(Button)`
&.MuiButton-root { //this targets any class that is added to the main component [1]
width: 500px;
}
.MuiButton-label { //in css-in-js this is effectively '& .MuiButton-label [2]
color: ${props => props.labelColor};
justify-content: center;
}
[1] Targets main classes on component
<StyledButton className='test bob'> << this element is targeted
</StyledButton>
[2] Targets child elements either through class or element type. Note the space between & and the actual class.
<StyledButton className='test bob'>
<span className='MuiButton-label'>test</span> << this element is targeted instead
</StyledButton>
You can also use the element tag directly
span {
color: ${props => props.labelColor};
justify-content: center;
}

Add styling to child element using Styled Components?

Say I want to create a styled component called <NoPrint /> that adds the following CSS to any element passed as child:
#media print
{
display: none !important;
}
How can I do that?
I want to be able to write a styled component like this:
<NoPrint><p>Some paragraph</p></NoPrint>
<NoPrint><Some>Some React component</Some></NoPrint>
I know that I can write:
const NoPrint = styled.div`
#media print
{
display: none !important;
}
`
render(
<NoPrint>
<Something />
</NoPrint>
)
But this component creates a wrapping div, which I do not want.
This is because you have to pass in the component you want to style, IE:
Style a component without wrapper
const NoPrint = styled(myComponent)`
#media print
{
display: none !important;
}
`
this will apply a custom style directly to an element without a wrapper.
Polymorphic prop
Another way is to use a "as" polymorphic prop
const Component = styled.div`
#media print
{
display: none !important;
}
`;
render(
<Component
as="button"
onClick={() => alert('It works!')}
>
Hello World!
</Component>
)
The only way I can see to figure something without having a div would be to have your media query in a css stylesheet with a classname, and pass that classname to your elements.
something like
#media print
.noPrint{
display: none !important;
}
<p class="noPrint" >Some paragraph</p>
To make an element without a div, there is React.Fragment available, but you can't style those...
I don't know if
Realistically you cant escape the wrapping div. You will have to either wrap it somewhere or, create a static styled component that can be included inside other styled components by referencing it.
Example
You can put this in like a style helper file
export const NoPrint = styled.div`
#media print
{
display: none !important;
}
then you can include it in other styled components. But it will not be wrappable around other components without an associated element like a span or div.

How to use material-ui (alpha) with styeld-components properly?

I've been trying to use styled-components with the alpha version of material-ui
According to the documentation, this should work out of the box.
This code:
const StyledButton = styled(Button)`
color: red;
text-transform: uppercase;
`;
return <StyledButton>Button</StyledButton>;
will generate something like this:
<button tabindex="0" class="MuiButtonBase-root-3177716317 sc-bdVaJa sxRGN" type="button" role="button">
...
</button>
It looks good.
However, the only problem I have is the order of the injected CSS styles (pic). Styles from styled-components are injected before MUI's styles which make their priority lower.
Is there any way to solve this without using !important?
In the current release (i.e. non-alpha) version, what you've asked would indeed require !important basis:
"Note that CSS properties defined inline are given priority over those defined in a CSS class. You need to use !important to take precedence over the inline style."
Ref: http://www.material-ui.com/#/customization/styles
Perhaps the alpha hasn't quite moved away from this inline requirement yet or it is still a work-in-progress.
What I've done to overcome this sort of thing myself is to (unfortunately) recreate the entire CSS on a standard <button> element when I need such a solution. Here's an example of how I'm doing that with a react-photonkit "theme"
// #flow
import styled from 'styled-components';
const PhotonStyledButton = styled.button`
font-family: Arial, Roboto, Helvetica, sans-serif;
height: 30px;
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 12px !important;
line-height: 1.4;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: default;
background-image: none;
border: 1px solid transparent;
border-radius: $default-border-radius;
box-shadow: 0 1px 1px rgba(0,0,0,.06);
-webkit-app-region: no-drag;
&:focus {
outline: none;
box-shadow: none;
}
color: #333;
border-top-color: #c2c0c2;
border-right-color: #c2c0c2;
border-bottom-color: #a19fa1;
border-left-color: #c2c0c2;
background-color: #fcfcfc;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fcfcfc), color-stop(100%,#f1f1f1));
background-image: -webkit-linear-gradient(top, #fcfcfc 0%, #f1f1f1 100%);
background-image: linear-gradient(to bottom, #fcfcfc 0%, #f1f1f1 100%);
&:active {
background-color: #ddd;
background-image: none;
}
`;
export default PhotonStyledButton;
styled-components in general is compatible with any component library. When you write styled(AnotherComponent) we take that component and inject an automatically generated class name. This means essentially it's the same thing as writing <AnotherComponent className="sc-asdf123" />!
The current version of material-ui specifically is a bit difficult to custom style because it uses inline styles. From the MaterialUI documentation:
Note that CSS properties defined inline are given priority over those defined in a CSS class. You need to use !important to take precedence over the inline style.
This means simply using styled(MaterialButton) won't work as the passed-in styles will mostly just be ignored. You need to bump the specificity of your styles to override the inline styles that material-ui ships with. (this article is a great primer on specificity if you're not familiar with the details)
Answer for the alpha version of material-ui
The current alpha version of material-ui has switched to using JSS under the hood. (which is CSS in JS not inline styles, like styled-components) This means the issue is likely to be that the styled-components styles are injected after the default material-ui styles. (which are injected by JSS)
JSS supports custom injection points so you might be able to add a <!-- jss --> comment to the HEAD of your HTML to make sure JSS injects its CSS before the styled-components injected CSS?
Answer for the current version of material-ui
There are two ways to bump the specificity of the styled-components injected styles, one more tedious and one a bit more "hacky". The first one is adding !important at the end of all of your styles:
const Button = styled(MaterialButton)`
color: blue!important;
`
While this works in most cases it gets tedious very fast when you have lots of custom styling in a component. The better way is to use the class name hack:
const Button = styled(MaterialButton)`
&&& {
color: blue;
}
`
These ampersands get replaced with the automatically generated class name meaning the outputted CSS looks something like this:
.sc-asdf123.sc-asdf123.sc-asdf123 {
color: blue;
}
This bumps specificity by a big margin, thusly overriding the defined inline styles, and is less annoying than having to put !important after each rule.
Now we can use <!-- material-ui --> to make sure the styles are injected after it.
By default, Material-UI will look for a html comment named to inject styles after. By adjusting the placement of this comment within your HTML body you can control the order that CSS rules are applied to your components. (ref)

Resources