I am following the tutorial below on react material web components (RMWC) and got confused with the styling and theming chapters.
https://jamesmfriedman.github.io/rmwc/styling-theming
In this chapter, the author tries to explain differences between using standard CSS and CSS Modules, but I am unable to understand this. What are the differences between the two and why do we use CSS modules and how is it different from standard CSS?
I am also trying to apply CSS using CSS modules, but CSS is not getting applied over the elements. Am I doing something wrong here?
I am using Create-React-App.
My code (style is not getting applied):
index.js
import React from 'react'
import ReactDom from 'react-dom'
import styles from './index.css'
import Button from '#material-ui/core/Button'
class App extends React.Component {
render() {
return (
<div>
<Button className={styles.button}>
CSS Modules
</Button>
</div>
)
}
}
ReactDom.render(<App />, document.getElementById('root'))
index.css
.button {
background: linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%);
border-radius: 3px;
border: 0;
color: white;
height: 48px;
padding: 0 30px;
box-shadow: 0 3px 5px 2px rgba(255, 105, 135, .3);
}
Even though by doing it in below way , it is working fine.
import React from 'react'
import ReactDom from 'react-dom'
import styles from './index.css'
import Button from '#material-ui/core/Button'
class App extends React.Component {
render() {
return (
<div>
<Button className="button">
CSS Modules
</Button>
</div>
)
}
}
ReactDom.render(<App />, document.getElementById('root'))
Your code is fine except for one small detail you might have missed. Using create-react-app allows you to use css modules if you follow their guidelines. Your file name needs to be index.module.css for it to work as a css module.
Reference:
This project supports CSS Modules alongside regular stylesheets using the [name].module.css file naming convention.
If you think about programming best practice, using global variable is bad.
Because you will run to collision of variable eventually. For worst case, there's no any warn and you're just confused when the value of variable is changed.
In css, sharing class or any selector might help you save time to write css. but eventually you will get some problem (especially in medium-large code base) finding that element is styled by unintentionally class or selector or you want to change style of some element but it affect other element that you don't want.
I suggest you reading this link for further detail.
https://css-tricks.com/css-modules-part-1-need/
for you case, you need to setup babel plugin to use css modules in react
https://github.com/gajus/babel-plugin-react-css-modules
if you create project by create-react-app, you should look at #Keno Clayton 's answer
You can get the answer what different among standart css with css module, when you make more than one page. You will use some css to different page and sometimes you will use same css class name. Same class name will make css overwrite your style. CSS Module comes to fix that problem.
Related
I'm trying to import a component-level CSS module (xx.module.css), but it is not being applied. I am using Nextjs and using a custom server.js, _app.js, and _document.js. I am suspicious that I need to do something in one of those files to make the CSS load, but I do not know what it is. Is anyone able to guide me?
Styled code:
import styles from "./NavigationButtons.module.css";
...
<div className={styles.test}>
<>Some text here I want colored</>
</div>
NavigationButtons.module.css:
.test {
color: "red";
}
I am angular user and i got a new project in my hands that i need to learn react. I am in very beggining, and my doubt is very very simple i think.
So, in angular you can add your css in the file angular.json (styles) right? And that css are available for all components that you will create.
So, in react i am looking and looking and i can't find an answer. The only way is import the file in all components?
I have a css file that i need for all components and i don't want import that file in all components.
Is there other way on react?
Thank you for the answers.
Suppose this is the code in your styles.css file.
.container{
background: goldenrod;
height: 80vh;
}
Then you can link this file in any React Component like this:
import React from 'react';
import classes from './styles.css';
class Cont extends Container{
render(){
return (
<div className={classes.container}>
<p>Hi</p>
</div>
)
}
}
Up until now, I've always used a single CSS file when creating multiple page applications which would store all my CSS rules.
Now that I'm using Vue.js and components, I am not sure where to write my CSS.
I could write the CSS in the <style></style> tags of a component but to me this only makes sense if the CSS is only used for this specific component. This leaves me wondering where should I write CSS which I would like to be applied globally to everything.
Imagine I have some CSS which I want to be applied to everything like this snippet:
*, *:after, *:before {
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
text-decoration: none;
}
Where would I write it?
Until a better solution I can offer two suggestions:
1. In App.vue file
If it's just a small amount of code, put it in your App.vue file
As you said:
"I could write the CSS in the tags of a component but to me this only makes sense if the CSS is only used for this specific component."
If you put CSS in the in the <style></style>in any .vue files that's part of your project it's going to be global.
<style></style> get's applied to the whole project unless you add scoped to the tag.
<style scoped>
body {
background: green; /* This won't effected your main <body> tag unless you actually have a `<body>` inside the `<template>` of that file */
}
</style>
2. Import a separate file containing only CSS (updated and easier)
From #Fabjan in the comments.
Just import the .css file in your main.js file:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './assets/lib/css/reset.css' // my own reset file
import './assets/lib/css/myMain.css' // global stylesheet
Make sure to put it before your run your app. new Vue({})
(3. My previous answer:)
You can create a styles.vue and add all your global styles there inside <styles></styles> without scoped. (this worked for me)
Then inside your main.js file you write:
import GlobalStyles from "./assets/lib/css/styles.vue"
Vue.use(GlobalStyles)
Make sure your styles.vue contains at least on tag inside for it to import properly.
<template>
<div class="empty">
</div>
</template>
<style>
body {
background: red;
/* The rest of your Global CSS code */
}
</style>
This feels really tacky but it worked for me now.
Hope it helps and I'd love some feedback or comments if people have better solutions.
Here is my solution to configure global scss with my project that using Nuxt.
Assume that you already have node sass and sass-loader installed.
In nuxt.config.js file add your SCSS path from static or assets folder
css: [
'#/assets/scss/main.scss'
]
Bonus: if you don't like this way maybe you can get a try nuxt-sass-resources-loader
Basically, I'm trying to build a microservice that uses a standard UI library we built internally to generate HTML templates for use in email and we want to automatically inline all our CSS into each tag.
Both our standard UI library and the email templates I've created import CSS like so:
// someComponent.jsx
import React from 'react';
import Button from '#shared-ui/Button';
import 'app/modules/someComponent.scss';
class someComponent extends React.Component {
render() {
return (
<div className="someComponent">
<Button>
Click here to learn more.
</Button>
</div>
)
}
}
export default someComponent;
And the SCSS file:
// someComponent.scss
.someComponent {
font-size: 42px;
}
We import the Button component from our UI library (which already has its own CSS).
For building our web app, this sort of approach works out fine. But when it comes to building out HTML that is suitable for email, it's lacking, since we need to provide inline tags.
Ultimately, when I call renderToStaticMarkup() in our entry file, I want the rendered HTML to come out looking something like this (including the components we imported from our shared UI library):
<div style="font-size:42px">
<button style="background-color: #fff; border: 1px">
Click here to learn more.
</button>
</div>
I'm having a tough time with this. Short of writing out the inline styles by hand, I can't figure out a way to get this to work (and that doesn't even include how I would go about getting inline styles for our shared UI library).
I'm currently building out a large React app. Css, has never been my strong point. But now CSS has sass / cssNext / inline styles with React. I've been using BEM with sass, but as my other applications have grown huge even that starts to break down. Especially when you had on the ability to "re-skin" or "theme" the pages outside of the primary color schemes etc..
so -- can someone point me to a proven way to create css with react that can scale very well, and allows for custome theme'ing when people want to borrow my components. For instance,
<MyComponent />
// this component has its styles but lets say Joe Schmoe wants be import
// it? But, Joe wants to overlay his custom styles?
// Is there a new paradigm that allows for an overlay or reskin within the component?
Or even the idea of the whole application being skinnable some time down the line. I know this is sorta a very base question, but whenever I build out projects my pain points also seem to be the CSS - so I want to know what really works.
This was, until recently, not a solved problem in the React world.
I'm one of the maintainers of ElementalUI, a React component library, and we've been trying out all the different ways of styling for the past 6-12 months. (!) You name it, we've tried it. (I talked about my experiences with some of the most popular libraries during my ReactNL keynote and where they break down)
The issue is that none of the current styling libraries have built-in support for theming at all. You can do it with most of them in a very hacky, non user-friendly way, but that's not what you want when you distribute a component, right?
That's why we built styled-components. styled-components has a bunch of interesting properties, and one of them is that theming is directly built into the library, making it the perfect choice for building distributable components!
Here is the short explanation, though I encourage you to go through our documentation which explains everything!
This is what the basic usage of styled-components looks like:
import React from 'react';
import styled from 'styled-components';
// Create a <Wrapper> react component that renders a <section> with
// some padding and a papayawhip background
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
This variable, Wrapper, is now React components you can render:
// Use them like any other React component – except they're styled!
<Wrapper>
<Title>Hello World, this is my first styled component!</Title>
</Wrapper>
(if you click on the image you'll get a live playground)
When you pass an interpolated function into the tagged template literal, we pass you the properties passed to the component. This means you can adapt to the props:
import styled from 'styled-components';
const Button = styled.button`
/* Adapt the colors based on primary prop */
background: ${props => props.primary ? 'palevioletred' : 'white'};
color: ${props => props.primary ? 'white' : 'palevioletred'};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
Here, we've created a Button component that you can make primary like any other React component:
<Button>Normal</Button>
<Button primary>Primary</Button>
Now comes the theming aspect. We export a component called ThemeProvider that you can pass a theme to and wrap your app (or parts of the app) in:
import { ThemeProvider } from 'styled-components';
const theme = {
main: 'mediumseagreen',
};
ReactDOM.render(
<ThemeProvider theme={theme}>
<MyApp />
</ThemeProvider>,
myElem
);
Now any styled component within that ThemeProvider, no matter how deep thanks to context, will get this theme injected into the props.
This is what a themable Button would look like:
import styled from 'styled-components';
const Button = styled.button`
/* Color the background and border with theme.main */
background: ${props => props.theme.main};
border: 2px solid ${props => props.theme.main};
/* …more styles here… */
`;
Now your Button will take the theme it gets passed and change it's styling based on that! (you can also provide defaults via defaultProps)
That's the gist of styled-components and how it helps to build distributable components!
We have a currently WIP doc about writing third-party component libraries which I'd encourage you to check out, and of course the normal documentation is a good read too. We've tried to cover all the bases, so if you see anything you dislike or that you think is missing please immediately let us know and we'll discuss!
If you have any other questions about styled-components feel free to reply here or reach out on Twitter. (#mxstbr)
I don't know what is the best way. I think it's more like a personal preference. I will just share the tools that I'm using. What I'm using is css-modules with postcss.
css-modules gives you the power to create a local-scoped identifier with a global unique name for each of your CSS classes and also enable a modular and reusable CSS! You can also use postcss-modules-values to create a global settings file which contains all the settings variables. So that you can change the theme for your website.
Here's how I structure the components. Each of my component will have one css file which is very easy to maintain or make changes.
Here's the code for the Button component.
function Button(props) {
const className = props.className ? `${styles.button} ${props.className}` : styles.button;
return (
<button disabled={props.disabled} className={`${className}`} type="button" onClick={props.onClick}>
{Children.toArray(props.children)}
</button>
);
}
Notice that I have a className for the component which allows other component to pass in the class for the button component. So that when someone borrow your component they can extend or override your button styles.
If you need to create a customisable website, I will also recommend to use Less.js which provides the live preview of the customised website.