materializecss in messes with existing classes. How can I add a prefix? - css

I want to use materializecss in my chrome extension.
The extension adds some functionality to gmail. Unfortunately the materializecss seems to interfere with the gmail stylings. Is it possible to isolate the scope of the materialize css or to add a custom prefix to the classes?
I currently import the css in my manifest.json
"content_scripts": [
{
"matches": ["*://mail.google.com/*"],
"css": [
"vendor/materializecss/materialize.min.css"
],
...

Not without rewriting the whole framework (the scss files) or using scoped stlyes.

There is gulp-class-prefix plugin to prefix CSS classes. Here is the configuration file
var gulp = require('gulp'),
classPrefix = require('gulp-class-prefix');
gulp.task('prefix', function () {
return gulp.src('SOURCE_OF_CSS_FILE')
.pipe(classPrefix('YOUR_PREFIX'))
.pipe(gulp.dest('DESTINASTION_FOLDER'));
});
gulp.task('default', ['prefix']);
but this will only prefix only CSS file and will work only for the components that do not need JS inclusion. For dynamic components, you need to make changes in materiazecss.js file.
Update
I got this python script. This script is designed for bootstrap. But anyhow this works(70%-80%) for materializecss too. You just need to change the file name in the main function of it ie replace bootstrap with materializecss.

Related

How to get multiple CSS output from tailwind

I'm using TailwindCSS, I want a separate stylesheet CSS file for each of my web pages. like
about.html - about.min.css
portfolio.html - portfolio.css
First you should ask yourself why do you want to do this? Creating a separate style-sheet for each individual page (home, about, etc) is not really common. The focus is on re-usability and possibly only adding additional styles.
If you are concerned about the file size, then do not integrate Tailwind via CDN but build your own style. Then you have access to the purge function. Purge kicks out all unused styles and the result is a very small CSS file.
You can use:
const mix = require('laravel-mix')
mix.postCss('input.css', 'output.css', [
require('tailwindcss')`enter code here`('./tailwind.config.js'),
require('autoprefixer')
])
.postCss('input.css', 'output-pdf.css', [
require('tailwindcss')('./tailwind-custom.config.js'),
require('autoprefixer')
])
You'll need to install TailwindCSS as PostCSS plugin as well as postcss-import and autoprefixer. Then create postcss.config.js in root directory and add:
module.exports = {
plugins: {
'postcss-import': {},
tailwindcss: {},
autoprefixer: {},
}
}
then you can add as many css files as needed in your css directory, albeit with some concerns following this documentation
Keep in mind, you should only use one css for all pages in your web unless you have multiple projects with different styling required.
If you want multiple CSS output , then you should not be using Tailwind for your project.

Prevent vuetify from polluting global style scope

I am trying to essentially embed a Vue component into another one from a remote source (npm), without using a Vue Plugin. The components are mounting as expected, however, because the embedded component uses Vuetify, it's style is polluting the style of the "parent" application Here's some images that hopefully illustrate what i mean:
Note the primary colors of the root application before mounting the embedded component
Upon mounting of the Login (embedded) component:
I tried the strategy mentioned here, using less in the embedded component to import the vuetify css at a block level, but it doesn't seem to be working for me.
I realize that, in the end, I could ultimately solve this by ensuring the embedded theme matches the root applications theme, but I'd rather not have to rely on that. If my component is being built with webpack, why am I unable to apply Vuetify's css to just that component? Any suggestions?
happy to include code if necessary
To use with vue.js install postcss-parent-selector
npm i postcss-parent-selector -D
then create a postcss.config.js file in root and add following code
module.exports = {
plugins: [
require("postcss-parent-selector")({
selector: ".mywrapperclass",
}),
],
};
Then in public/index.html add a wrapper element around the app:
<div class="mywrapperclass">
<div id="app"></div>
</div>
Some links:
https://vue-loader-v14.vuejs.org/en/features/postcss.html
https://www.npmjs.com/package/postcss-parent-selector
https://github.com/postcss/postcss
I am currently having the same issue with my application. The possible solutions I've came up with are:
-Embedding the child Vue application via iframe and using a library like vuex-iframe-sync to pass props between Vuetify root app and the child app.
-Disabling Vuetify theme alltogether and perhaps customize components on my own:
// src/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
const vuetify = new Vuetify({
theme: { disable: true },
})
-Another option was using webpack config to run a PostCSS plugin and possibly add prefixes to Vuetify's global styles while bundling the app, but I couldn't figure out how.
Please let me know if you make any progress on this topic!

How to change tailwind-config.js dynamically based on user settings in rails

I have a Rails 6 app set up to use Tailwind CSS with Webpacker similarly to how it's done in this GoRails tutorial.
I want to be able to change the Tailwind defaults dynamically based on the controller and action so that it's very easy for users to "skin" sections of the site by selecting a few options that then dynamically adjust a few of the Tailwind config options. (An example of how this could be used would be users logged into the admin area of the site changing their font family and background color to match their brand.)
I can't just add a stylesheet to the layout based on a conditional because I'd have to override all of the instances where a Tailwind css variable I want to change (like "sans-serif"). That would be a lot of work and brittle to maintain as Tailwind evolves.
It would be ideal if there was a way to dynamically insert choices selected by the user into the Tailwind config file (/javascript/stylesheets/tailwindcss-config.js), but I'm not sure how to do this.
Also is there a better way to do this in Rails when using Tailwind? It seems like there should be some way to use Javascript from the controller to dynamically change the settings in my tailwindcss-config.js (The Tailwind config file is explained here). So, something in that file like this:
theme: {
fontFamily: {
display: ['Gilroy', 'sans-serif'],
body: ['Graphik', 'sans-serif'],
},
What was a font stack hard-coded as a configuration in Tailwind would become this:
theme: {
fontFamily: {
display: DYNAMICALLY INSERTED FONT STACK,
body: ANOTHER DYNAMICALLY INSERTED FONT STACK,
},
How would you do this in Rails? I have that Tailwind config file living at /javascript/stylesheets/tailwindcss-config.js. Is this possible to do with Webpack in rails? Is this even the correct approach to take with Rails 6 using Webpacker + Tailwind?
I have the feeling that we'd be trying to use a 'buildtime' tool for a 'runtime' operation
To directly inject the variable into tailwindcss config file would imply a rebuild of the actual css served to the user, applying the instructions in tailwind config file to the actual content put in app/javascript/css (assuming the setup used in the mentioned video tutorial).
The operation is carried on by webpack, integrated through the webpacker gem.
IMHO, neither webpack nor tailwind were designed with the purpose of rebuilding the assets at runtime, and, even if I'm definitely aware that a universal machine can do anything ;) I wonder where taking this route would take one, mainly in terms of maintainability.
From this link it seems that triggering a rebuild of webpack on a config change is not straightforward.
Here's a somewhat different path to try:
In the <head> section of the application define css variables (more precisely 'css custom properties') for the settings you want your user to access, which can be set and changed dynamically (from js too)
<style>
:root{
--display-font: "<%= display_font_families %>";
--body-font: "<%= body_font_families %>";
--link-color: "<%= link_color %>";
}
</style>
Alternatively you could create app/assets/stylesheets/root.css.erb (the extension is important) and include it in your template before tailwind
Then you should be able to change your tailwindcss config to something like the following:
theme: {
fontFamily: {
display: "var(--display-font)",
body: "var(--body-font)",
},
extend: {
colors: {
link: "var(--link-color)",
},
}
This way we define a dynamic css layout that responds to the value of css variables. The variables and the structure they act on reside on the same logical level, which corresponds to the actual webpage served to the user.
css variables are easily accessible from js, this is one way to have a clean access from rails too
Now let's imagine that the user wants to change the link color (applied to all the links).
In our imaginary settings form, she chooses an arbitrary color (in any css-valid format - the only constraint here is that it must be a valid css value, something you'll need to address with some form of input validation).
We'd likely want
a preview feature (client side/js): without reloading the page the user should be able to apply the new settings temporarily to the page. This can be done with a js call that sets the new value for the variable --link-color
// userSelectedColor is the result of a user's choice,
// say it's "#00FF00"
document.documentElement.style
.setProperty('--link-color', userSelectedColor);
as soon as this value is changed, all the classes previously created by tailwind, and any rule that make use of the variable, will reflect the change, no need to rebuild the css at all.
Please note that our user is not constrained to an arbitrary subset of the possible values, anything that can be accepted by css is fair game. By assigning to the config parameter a css variable, we actually have instructed tailwindcss to specify it in all its classes as a variable value, which now is under our control through css/js ...
We definitely DON'T NEED (nor want) webpack to rebuild the styles
To try to make it clearer, with our color example, in the generated css there will be classes like these - have a look at this link for an explanation of how customizing tailwind theme works
/* GENERATED BY TAILWIND - well, this or something very similar :) */
.text-link {
color: var(--link-color);
}
.bg-link{
background-color: var(--link-color);
}
/* .border-link { ... */
clearly the browser needs to know the value of --link-color (we've defined it in the :root section) and the value itself can be any valid css, but what interests us is that it can be changed anytime, automagically propagating the change to every rule using it, it's a css variable ...
and we'll want a save feature (server side/rails): when the user clicks on 'save', the new settings should be made persistent (saved in db)
this is plainly accomplished (for example) handling the form submit, saving the new value, which will then be pulled from the db to valorize the css variables on the next render of the page
just my 2 cents :) have fun !
As tailwind config file is "js" you can call ajax data then can add it in the config file data to make it dynamic. As we import the theme file in taiwlind config
I was having the same issue today. This worked for me.
# tailwind.config.js
theme: {
fontFamily: {
custom: ['Gilroy', 'sans-serif']
},
and use it like
#sample.html.erb
<span class="font-custom"> Hello Tailwind! </span>

Using css-loader without React

I'm building a small web app with Webpack-enabled CSS modules (via css-loader) and without React. My goal is to get the benefits of short, obfuscated CSS class names (as I'm currently using lengthy BEM class names) in my HTML by using the localIdentName: '[hash:base64:8]' option on css-loader. Since I'm not using React, I'm working with raw HTML that is not being programmatically generated through JSX file or document.write.
I've used css-loader with React plenty before, and it ultimately works because you're able to import the style class names in the React file and refer to them using the human-readable names, regardless of whatever the class name gets changed to by Webpack.
However, I'm confused how to deal with this when using raw HTML; I can't just import the styles in since it's not a JS file. If I have a class called photo__caption--large referenced in my HTML, and webpack converts the class name to d87sj, the CSS file will say d87sj but the HTML will still say photo__caption--large.
Is there some kind of loader for HTML files that's able to edit class names in the file to their Webpackified equivalents? Or should I really just be using React with CSS modules?
This github code might help you.
https://github.com/moorthy-g/css-module-for-raw-html
A bit of complicated setup needed. We need to wire the following packages together.
- postcss-loader
- postcss-modules
- posthtml-css-modules
- posthtml-loader
The following postcss configuration creates modules dump file (./tmp/module-data.json).
// postcss.config.js
module.exports = {
plugins: {
'postcss-modules': {
getJSON: function(cssFileName, json) {
const path = require('path'), fs = require('fs');
const moduleFile = path.resolve('./tmp/module-data.json');
const cssName = path.basename(cssFileName, '.css');
const moduleData = fs.existsSync(moduleFile) ? require(moduleFile) : {};
moduleData[cssName] = json;
fs.existsSync('./tmp') || fs.mkdirSync('./tmp');
fs.writeFileSync(moduleFile, JSON.stringify(moduleData));
},
generateScopedName: '[local]_[hash:base64:5]'
}
}
}
And the following webpack rule links html file to modules dump file.
{
test: /\.html$/,
use: [
{ loader: 'html-loader' },
{
loader: 'posthtml-loader',
options: {
plugins: [
require('posthtml-css-modules')('./tmp/module-data.json')
]
}
}
]
}
Finally, HTML uses css-module attribute instead of class
<div css-module="main.container">
<h2 css-module="main.title">Title for the page</h2>
</div>
Let me know if you have any issues
My understanding of Webpack, CSS Modules, & CSS-Loader is that the entire point is to use javascript to generate the files.
This enables all the name translation and what not. What's your goal with Webpack if you're writing static HTML?
There are several static site generators for Webpack that will allow you to get the result you want, BUT they're still building the HTML files.
Alternately you could look at tools similar to React (Vue or Angular) that allow you to write all your "templates" in straight HTML. In Vue for example, you can write only HTML (to be compiled from javascript) without needing to use any of its data binding or routing.

How could I make Aurelia include my styles as external styles via <link>?

I am trying to set up the conjunction of Atom editor, Sass, Typescript and Aurelia. This question is about Aurelia (installed via aurelia-cli) and its building system, I guess.
Well, I wrote style.sass for my component, then I required it in the component's view (app.html, for instance) as style.css. Fine, it works. But the content of compiled style.css gets included in index.html as internal styles, I mean everything goes inside <style>-tag, not through <link>. Also it seems that the corresponding .css file is never created at all. The stream just includes its content right in <style>-tag inside index.html.
How could I make Aurelia include my styles as external styles via <link>? In building task the last action is a build-plugin coming from aurelia-cli which is kinda black-box for me. Also aurelia.json is imported, so there should be a way to configure the needed behavior. A quick search didn't give me the answer, so here I am.
This is probably not the best solution, and not completely what you want, but perhaps it helps. You can do the following (I took a new TypeScript project):
First remove the css includes from your views.
Then, adjust the ./aurelia_project/tasks/process-css.ts task as follows:
import * as gulp from 'gulp';
import * as sourcemaps from 'gulp-sourcemaps';
import * as sass from 'gulp-sass';
import * as project from '../aurelia.json';
import {build} from 'aurelia-cli';
export default function processCSS() {
return gulp.src(project.cssProcessor.source)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest(project.platform.output));
};
This will output CSS files in the ./scripts folder. Then, adjust the aurelia_project/aurelia.json file as follows (remove css):
{
"name": "app-bundle.js",
"source": [
"[**/*.js]",
"**/*.{html}"
]
},
In your index.html you can now include the generated styles (or even in your components views).

Resources