Responsive variants for custom configured classes - tailwind-css

I've added more padding sizes to my tailwind.config.js. I can access the new padding sizes from my React components, and I can use them in my CSS files. However I can't use the responsive variants in my CSS files like md:p-140 etc.
tailwind.config.js
module.exports = {
theme: {
extend: {
padding: {
'140': '35rem'
}
}
},
// ...
}
I am able to use #apply pb-140 inside my CSS files, but if I use #apply md:pb-140, the class does not exist. The variants work when I use it in a React component, just not in CSS files. The variants for the default classes work with #apply though, like #apply md:p-8.
How can I get variants to work with classes added by my tailwind config?

Related

adding dynamic class name in svelte

I am currently writing an app with svelte, sapper and tailwind. So to get tailwind working I have added this to my rollup config
svelte({
compilerOptions: {
dev,
hydratable: true,
},
preprocess: sveltePreprocess({
sourceMap: dev,
postcss: {
plugins: [
require("tailwindcss"),
require("autoprefixer"),
require("postcss-nesting"),
],
},
}),
emitCss: true,
})
All in all this works, but I am getting some issues with dynamic class names.
Writing something like this always seems to work
<div class={true ? 'class-a' : 'class-b'}>
both class-a and class-b will be included in the final emitted CSS and everything works as expected.
But when I try to add a variable class name it won't work. So imagine this:
<div class={`col-span-6`}>
It will work exactly as expected and it will get the proper styling from the css class col-span-6 in tailwind.
But if I change it to this:
<div class={`col-span-${6}`}>
Then the style won't be included.
If I on the other hand already have a DOM element with the class col-span-6 then the styling will be added to both elements.
So my guess here is that the compiler sees that the css is not used and it gets removed.
And I suppose that my question is then if there is any way to force in all the styling from tailwind? so that I can use more dynamic class names
and not sure if it is relevant but the component I have been testing this on, have this style block
<style>
#tailwind base;
#tailwind components;
#tailwind utilities;
</style>
edit: can add that I am getting a bunch of prints in the log saying that there are unused css selectors that seems to match all tailwind classes
I think it was purgeCSS (built-in in tailwind 2.0) that did not recognize the dynamic classes.
It is difficult to solve this problem for every tailwind classes, but if you don't have a lot of these you can manually safe list those classnames:
// tailwind.config.js
module.exports = {
purge: {
content: ['./src/**/*.html'],
// These options are passed through directly to PurgeCSS
options: {
// Generate col-span-1 -> 12
safelist: [...Array.from({ length: 12. }).fill('').map((_, i) => `col-span-${i + 1}`],
},
},
// ...
}
I think that when the class attribute is a variable or depends on a variable it will not used to extract style during compilation (class-${6} is not evaluated during compilation but during runtime), because svelte marks it as unused css selector because the value of that class attribute is not known when the code is compiled.
To force svelte to include your style you must mark it as global, and to do that we have two options:
<script>
// component logic goes here
</script>
div class={`class-${6}`}/>
option 1:
<style>
:global(.class-6){
// style goes here
}
</style>
option 2: this will mark all your style as global
<style global>
.class-6{
// style goes here
}
</style>
I encounter the same problem, <div class="pl-{indent*4}"> do not work in svelte.
My solution is to use inline style,
<div style="padding-left:{indent}rem">,
which is inferred from pl-1=padding-left: 0.25rem; /* 4px */.
I think it's convenient for simple class.

Target a css class in 'a component generated by library' in react

I have used a chart library. I want to target and modify the properties of the CSS class generated by that library using external CSS. Let's assume the code in inspector is like this-
<div id="apexcharts9xagqubx" class="apexcharts-canvas apexcharts9xagqubx apexcharts-theme-light" style="width: 319.5px; height: 200px;">
<svg id="SvgjsSvg1001" width="319.5" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" class="apexcharts-svg apexcharts-zoomable hovering-zoom">
<div>
the apex chart documentation says I can target .apexcharts-canvas and change the background color. I have done this:
import React from "react";
import ReactApexChart from 'react-apexcharts'
import './apex.module.css'
return (
<div id="chart">
<ReactApexChart options={data.options} series={data.series} type="area" height={200}/>
</div>
);
inside apex.module.css I did this:
.apexcharts-canvas{
background-color: black;
}
now what?
looks like it doesn't work.
It looks like a CSS specifity thing.
You could try including the parent in the selector:
#chart .apexcharts-canvas {
background-color: black;
}
Hey friend when you import a css file with module prefix you shouldn't import that way, that kind of file will be imported giving it a name for example in this image:
This works equally with css extension files, since I am doing it with scss, this rule is for all css file types.
When you declare with module it's not a global style anymore but a style for a component because there is another way to import it but without the prefix module, in the image I already showed you the name of the declared name and then the name of the class.
Luckily my friend, it is not so complicated, I am also learning this little by little.
IF you are using CSS modules (else let me know):
TL;DR
You can either target the HTML element (instead of its class) where .apexcharts-canvas class is used (option 1), or you can make sure the global CSS imports are compatible with the CSS modules (option 2), checking webpack configuration.
I had same issue, I wanted to edit a CSS class in Apexcharts.
I am assumming you are using CSS modules (.module.css).
Option 1
Use this option if:
you used cra or you do not want to edit webpack configuration
it is enough to target the HTML element instead of the class directly
Steps:
The ID of the div where the chart is should be namespaced (CSS modules): id={styles.chart}, with CSS modules file imported as import styles from 'path-to-file'
In code inspector find div with chart id
Drill down until you find HTML element with your class .apexcharts-canvas
In your CSS modules file, target the HTML element with .apexcharts-canvas, using CSS selectors (example below)
.chart > div > div > :last-child {
background-color: black;
}
Option 2
Use this option if:
you can access the webpack config file (not using cra), AND
you want to target class directly
In the webpack configuration, you need to create a rule not only for CSS modules (import styles from 'path-to-file'), but also for global (normal) CSS (import 'path-to-other-file').
(credit: link)
rules: [
{
test: /\.(css|scss)$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
}
}
],
include: /\.module\.css$/
},
{
test: /\.(css|scss)$/,
use: [
'style-loader',
'css-loader'
],
exclude: /\.module\.css$/
},
]
After that you can import a global CSS file (import 'path-to-other-file') with a class .apexcharts-canvas on it.
Important: the webpack rules are mutually exclusive. Files ending with ".module.css" are considered CSS modules, other CSS files not ending like that are global CSS imports.

React/Webpack applying styles to tags but not classes/ids

I have setup my own react project from some tutorials including my own webpack configuration. When I try to style elements it is able to apply style to generic html tags such as <body> or <p> but it fails when I try to style classes/ids.
I know my css file is being imported because it styles the generic tags.
Webpack Config
{
test: /\.css$/,
use: [
"style-loader",
{
loader:"css-loader",
options:{
modules:true
}
}
]
}
CSS
.oakResults {
font-size:20px;
}
#yoyoyo {
color:red;
}
p {
color:orange;
}
React
<div className='oakResults'>
<p id='yoyoyo'>Results</p>
</div>
In my example, the <p> is colored red, but .oakResults font does not change and when I comment out the <p> style it doesn't turn red.
I want it to be able to style to both generic tags and classes/ids.
I think the reason of this issue is you have enable the css modules in webpack but not referring the css correctly.
So if you don't need the css module, try to remove options:{ modules:true} from your webpack config. Then the css could be applied to the class name you set in ReactJS.
Or if you do need the css module, keep the Webpack config. But modify your ReactJS to something like this:
import React, { Component } from 'react';
import styles from 'path\to\file.css';
class foo extend Component {
render() {
return (<div classname={styles.oakResults}> This is the test component</div>)
}
}
Hope it helps.
You should try this,
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
From the docs,
The modules option enables/disables the CSS Modules specification and setup basic behaviour.
Using false value increase performance because we avoid parsing CSS Modules features, it will be useful for developers who use vanilla css or use other technologies.
Refer more about CSS Modules.

Using CSS attribute selector with styled components for icons

I'm using NextJS for React, SSR and styled-components (with hashing). So far I managed to build main CSS structure with Sass.
nextjs.config.js
const withSass = require('#zeit/next-sass')
module.exports = withSass({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: "[hash:base64:5]",
}
})
The problem is I cannot use an attribute CSS selector; for icons, usually I define font-family like below
[class^='icon-'] {
font-family: 'fonticon'
}
.icon-foo {
&:before {
content: '\someunicode';
}
}
when I run build and .icon-foo class successfully converts to some hash and match with the CSS. But I cannot use an attribute selector here.
I know it's impossible to convert this kind of selector, but is there any solution, like giving a exception rule for cssLoaderOptions for example,
excludeClasses: /^.icon-/
so I can keep my classes as they are just for the icons?
I know I can give font-family to <i> tag, but I want to avoid that if possible.

Using css-loader inline with Webpack + React

I'm building my React app with Webpack, and css-loader w/modules. I love it. Most of my stylesheets are very small, though, and I'd like to inline them within the same JSX file as my markup and JavaScript.
The CSS loader I'm using right now looks like this:
{ test: /\.(css)$/i,
loader: ExtractTextPlugin.extract("style-loader", "css-loader?modules") }
In my JSX, I import my separate CSS files like this:
import classNames from 'dashboard.css';
...
<div className={classNames.foo}></div>;
This is then compiled and translated into something like:
<div class="xs323dsw4sdsw_"></div>
But what I'd like to do is something more like below, while still preserving the localized modules that css-loader gives me:
var classNames = cssLoader`
.foo { color: blue; }
.bar { color: red; }
`;
...
<div className={classNames.foo}></div>;
Is this possible? How can I do this without having to actually require / import a separate file?
I believe your issue is that you your current webpack configuration uses CSS Modules. CSS Modules automatically rename your CSS Classes to avoid global class name collisions.
The fix:
// remove 'modules' from the end of your css-loader argument
{ test: /\.(css)$/i,
loader: ExtractTextPlugin.extract("style-loader", "css-loader?modules") }
// like so
{ test: /\.(css)$/i,
loader: ExtractTextPlugin.extract("style-loader", "css-loader") }
Now your class names will be preserved. Although, I'm not sure why you want to do this. Do you care to share why?

Resources