Nested scss rule not rendering in react project - css

I may be missing something blatantly obvious, but for some reason when I try to nest sass rules, nothing renders. However, every other aspect seems fine.
In this case, hover isn't working.
jsx:
const SidebarSection = (props) =>
<div className={styles.sidebarPane}>
<ul className={styles.navList}>
<li className={styles.navElement}>{props.element}</li>
</ul>
</div>;
scss example rule:
.navElement {
cursor: pointer;
margin: .5rem 0 0 0;
&:hover {
color:yellow;
}
}
Webpack css/sccs loaders:
test: /\.(css|scss)$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
options: {
modules: true,
},
}, {
loader: 'postcss-loader',
}

Related

CSS not getting imported in component

I have the following Test component:
Test.css
.SomeClass {
background-color: blue;
width: 100px;
height: 100px;
}
Test.tsx
import React from 'react';
import './Test.css';
export const Test = () => {
return (
<div className={'SomeClass'}>
hello
</div>
);
};
Relevant section of webpack config:
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: !isProduction,
modules: {
localIdentName: '[local]',
},
},
}],
},
The problem is that the styles are not applied. On inspection, the div looks like this:
<div class="SomeClass">hello</div>
but there is no "SomeClass" css.
I suspect it is to do with some webpack config. I tried this too: use: ['style-loader', 'css-loader'] instead of the above use array, but no luck.
Edit
This project uses react-jss.

Importing global css custom variables

I'm trying to use webpack with postcss to import a theme-variables.css file that contains my css custom variables.
//theme-variables.css
:root {
--babyBlue: blue;
}
Basically I want any css that imports theme-variable to be able to access these css custom properties and resolve to static values using postcss-css-variables.
//style.css
#import "./theme-variable.css";
div {
display: flex;
color: var(--babyBlue);
}
becomes
//main.css
div {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
color: blue;
}
However I keep getting webpack errors variable --babyBlue is undefined and used without a fallback
main.js ends up looking like this:
:root {
--babyBlue: blue;
}
div {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
color: undefined;
}
Here's my webpack (index.js requires styles.js):
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: { main: "./src/index.js" },
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader",
options: { importLoaders: 1 }
},
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: loader => [
require("postcss-css-variables")(),
require("postcss-cssnext")(),
require("autoprefixer")(),
require("postcss-import")()
]
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css"
})
]
};
Solution:
The postcss-import plugin has to come first HOWEVER the plugins for Postcss-loader does not go in reverse order like webpack loaders do.
This fixes it:
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: loader => [
require("postcss-import")()
require("postcss-css-variables")(),
require("postcss-cssnext")(),
require("autoprefixer")(),
]
}

CSS direct descendant not working properly on production build

I suspect this is an issue with webpack, but I cannot seem to get this to work. My only CSS file (main.css) contains the following code:
.numpad > input {
text-align: center;
border: 2px solid blue;
margin: auto;
}
However when I publish the application, the CSS file shows the following:
.numpad {
text-align: center;
border: 2px solid blue;
margin: auto;
}
.numpad > input {
text-align: center;
border: 2px solid blue;
margin: auto;
}
I have searched the entire solution for any sort of duplicate that could be causing the first. It doesn't exist.
My webpack config is as follows:
module.exports = (env) => {
const isDevBuild = !(env && env.prod);
return [{
stats: { modules: false },
entry: { 'main': './ClientApp/boot.tsx' },
resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
output: {
path: path.join(__dirname, bundleOutputDir),
filename: '[name].js',
publicPath: 'dist/'
},
devtool: 'inline-source-map',
module: {
rules: [
{ test: /\.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' },
{ test: /\.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader?minimize' }) },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' },
{ test: /\.js$/, include: /src/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ['env'] } } }
]
},
plugins: [
new CheckerPlugin(),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
}),
new CleanWebpackPlugin(['dist'])
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin('main.css')
])
}];
};
Any ideas for why there is a duplicate being created?

Getting: Unexpected token { expected ; while parsing pure CSS file

The application builds successfully. But when I load it in the browser, it produces the error 'Unexpected token, expected ;' with a marker at the first { character in the css file. I believed I followed the docs but this error will not go away. Any idea what could be causing this error?
webpack.config.js
module.exports = {
...
module: {
rules: [{
test: /\.jsx?$/,
use: 'eslint-loader',
exclude: /node_modules/,
include: Dir.src
}, {
test: /\.jsx?$/,
use: 'babel-loader',
exclude: /node_modules/
}, {
test: /\.json$/,
use: 'json-loader'
}, {
test: /\.woff2(\?[a-z0-9]+)?$/,
use: [{
loader: 'url-loader',
query: {
limit: 10000,
mimetype: 'application/font-woff2'
}
}]
}, {
test: /\.(eot|gif|jpe?g|mp+|png|svg|tff|wav|woff*)$/,
use: [{
loader: 'file-loader',
query: {
limit: 10000
}
}]
}, {
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: 'file-loader'
}, {
test: /favicon\.ico$/,
use: [{
loader: 'url-loader',
query: {
limit: 1,
name: '[name].[ext]',
}
}]
}, {
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
test: /\.s[a,c]ss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
...
}
index.jsx
import React from 'react';
import './index.css';
...
index.css
div { text-overflow: ellipsis; }
button {
border-radius: 0 !important;
cursor: pointer;
padding: 0.6vh 1.2vw;
}
button, .btn, .form-control { border-width: 0.1vh 0.05vw; }
button, .btn, .btn > *, [class^='btn-'], [class^='btn'] > * { font-size: 1.8vmin; }
.btn-group-sm > .btn, .btn-sm {
font-size: 77%;
line-height: 1.5;
}
Produces:
+ 1446 hidden modules
webpack: bundle is now VALID.
{ SyntaxError: C:/simproduct/component/index.css: Unexpected token, expected ; (1:4)
> 1 | div { text-overflow: ellipsis; }
| ^
2 | button {
3 | border-radius: 0 !important;
4 | cursor: pointer;
at Parser.pp$5.raise (C:\simproduct\node_modules\babylon\lib\index.js:4454:13)
at Parser.pp.unexpected (C:\simproduct\node_modules\babylon\lib\index.js:1761:8)
at Parser.pp.semicolon (C:\simproduct\node_modules\babylon\lib\index.js:1742:38)
at Parser.pp$1.parseExpressionStatement (C:\simproduct\node_modules\babylon\lib\index.js:2236:8)
Try the following configuration for test: /.css$/. Make sure that you have postcss-loader in your configuration.
test: /\.css$/,
use: ['style-loader', {loader: 'css-loader', options: { importLoaders: 1 }},
'postcss-loader'
]
}
You will need to have postcss.config.js file; the same location you have your package.json. Add the following; or change is accordingly
module.exports = {
plugins: {
'postcss-import': {},
'postcss-cssnext': {
browsers: ['last 2 versions', '>5%']
}
}
};
Edit
Try to add the following query to your jsx loaders as follows:
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
query: {
presets: ['react', 'es2015','stage-1']
}
}

Media Query not working with CSS/Style loader and Webpack3

I am using css-loader and style-loader for my CSS but all media queries are not working. I am using "webpack": "^3.4.1", "css-loader": "^0.28.4" and "style-loader": "^0.18.2".
This is my Webpack configuration:
const ExtractTextPlugin = require('extract-text-webpack-plugin')
rules: [{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]-[local]-[hash:base64:6]',
camelCase: true
}
}]
}]
...
plugins: [
new ExtractTextPlugin({
filename: 'style.[chunkhash:6].css',
allChunks: true
})
]
My css file is something like this:
.container{
position: relative;
margin: 30px 15px;
padding: 50px 15px;
background: #fff;
}
#media (max-width: 768px) {
.container{
background: #fbfbfb;
}
}
and I am importing this CSS file in React code like this:
import styles from './Component.css'
try use this code
.container{
position: relative;
margin: 30px 15px;
padding: 50px 15px;
background: #fff;
}
#media only screen and (max-width:768px){
.container{
background: #c00;
}
}
<div class="container">
content her
</div>
I think that the problem is that you declared the ExtractTextPlugin, but you are using css and style loader instead.
Take a look at this setup for reference:
plugins
plugins: [
new ExtractTextPlugin({
filename: "css/bundle.css",
allChunks: true,
disable: process.env.NODE_ENV !== 'production'
}),
]
loader
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader?importLoaders=1'
})
}
This would use ExtractTextPlugin with production builds, and fallback to style-loader when using webpack-dev-server because ETP doesn't support hot reloading.
Feels so silly that I wasted as much time as I did, not getting why I was facing this same issue.
Just wanted to include it here for anyone else's reference as well...
Note, There could be other reasons for this issue as well.
My issue was that I hadn't added the meta tag w/ viewport.
FYR -
<meta name="viewport" content="width=device-width, initial-scale=1" />
Hope this helps.

Resources