Question:
I'd like to use a plugin (daisyUI) for TailwindCSS in one of my Svelte components. It looks like style information leaks from this component and affects the entire site. How can I avoid this?
I don't think this is related to daisyUI specifically.
Below I'm describing a minimal reproducible example based on sveltekit. But the problem is not related to sveltekit. I'm encountering this in the development of a webextension which doesn't use sveltekit. The sveltekit setup is only to make the smallest possible demonstration for this question.
To illustrate the problem, I've set up a sveltekit skeleton project, then added one single additional svelte component which uses Tailwind. When I add the plugin, the background color of my page turns from white to gray. I don't understand how this can happen, as far as I can see, I'm only using Tailwind within that component. But the style seems to leak.
Minimal example on github:
Fastest way to reproduce:
git clone git#github.com:lhk/minimum_example.git
cd minimum_example
npm install
npm run dev -- -- open
Now you can edit tailwind.config.cjs and add/remove the plugin:
plugins: [
//require("daisyui")
],
Step-by-step explanation
I'd like to use Svelte together with Tailwind and DaisyUI.
Here's a minimal project setup
# choose the skeleton project, typescript syntax and no to everything else
npm create svelte#latest minimum_example
cd minimum_example
npm install
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init tailwind.config.cjs -p
npm i --save-dev daisyui
Now edit tailwind.config.cjs:
/** #type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{html,js,svelte,ts}'], theme: {
extend: {},
},
plugins: [
//require("daisyui")
],
}
Add a new Svelte component under src/components/Problem.svelte:
<p class="bg-blue-700">Using Tailwind class</p>
<style lang="postcss">
#tailwind base;
#tailwind components;
#tailwind utilities;
</style>
And include it in src/routes/+page.svelte:
<script lang="ts">
import Problem from "./../components/Problem.svelte";
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit kit.svelte.dev to read the documentation</p>
<Problem></Problem>
You can run the project with
npm run dev -- -- open
If you open the website you'll see the sveltekit skeleton app, plus one paragraph with a blue background (this is my test that Tailwind is working). Now you can uncomment the plugin in tailwind.config.cjs. The background of the page will turn gray.
I think this is a theme that somehow leaks from the Tailwind plugin to the entire site.
The way you use tailwind with svelte is quite wrong. The tldr answer is remove #tailwind directives and use #apply instead.
<p class="my-element">Using Tailwind class</p>
<style lang="postcss">
.my-element {
#apply bg-blue-700;
}
</style>
The way how svelte scopes styles is by using a unique class name alongside your custom selector, e.g. .my-element becomes .my-element.svelte-x57u2q. This also means you must use a selector so that this scoping mechanism can kick in.
But with vanilla tailwind, those builtin class names have to be global in order to be useful, in other word “leaked”. This is by design, not bug.
So if you want to use tailwind but also leverage svelte’s scoped style, #apply is the only solution.
The official doc has a section titled Using #apply with per-component CSS that reveals more technical details, I think it’s worth reading.
Is There any difference to import to an Angular project a CSS lib (eg bootstrap) considering the options below:
Angular.json (npm)
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"styles.scss"
]
Angular.json (CSS file locally)
"styles": [
"assets/lib/bootstrap/dist/css/bootstrap.min.css",
"styles.scss"
]
styles.scss (CSS file locally)
#import "assets/lib/bootstrap/css/bootstrap.min.css";
I suggest the first solution, because:
All three will end up in main CSS bundle
But 2. and 3. will also have original bootstrap inside assets. Even though it's used in bundle, it won't be removed from assets - which are a part of a build as it is.
Also, if you update Bootstrap it's way easier doing so by NPM.
In my angular application only one component uses handsontable, so the css need not be application level.In the component I tried using syntax like this:
styleUrls: ['./../../../node_modules/handsontable-pro/dist/handsontable.full.min.css']
But it had no effect.Finally I had to copy handsontable.full.min.css in the same folder as that of my component refer the styleUrls like this:
styleUrls: ['./handsontable.full.min.css']
I do not like copying as that leads to same file being at 2 places.
[As per handsontable documentation][1] to declare css at application level you have to add this to style.css
[1]: https://handsontable.com/docs/7.4.2/frameworks-wrapper-for-angular-installation.html
#import '~handsontable/dist/handsontable.full.css';
I experimented putting this line in style.scss and style.css file in turn, that also had no effect.
My Angular is 7.1.1 & handsontable is :
"#handsontable-pro/angular": "3.0.0",
"#handsontable/angular": "^5.1.1",
How can I avoid making 2 copies of handsontable css?
Edit: As per angular.json
"styles": ["projects/survey-webapp/src/styles.css"]
As per suggestion of #spots I added handsontable css to it without success:
"styles": [
"projects/survey-webapp/src/styles.css",
"node_modules/handsontable-pro/dist/handsontable.full.min.css"
],
Have you tried adding the stylesheet in the styles array in angular.json? I have never used Handsontable, but this is how I typically reference 3rd party stylesheets, such as bootstrap or ag-grid.
You'll want something like this:
"styles": [
//other styles...
"node_modules/handsontable-pro/dist/handsontable.full.min.css",
],
I started learning Angular and I'm following a tutorial. I tried putting the code as in the tutorial for the navigation-bar:
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
Recipe book
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li> Recipe</li>
<li> Shopping list</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<ul class="dropdown-menu">
<li>Save data </li>
<li>Fetch data </li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
But all I get is this:
If I remove bootstrap, I do get the other items.
I used npm install bootstrap --save and #import "~bootstrap/dist/css/bootstrap.css"; in styles.css to use bootstrap.
EDIT:
I did not wanted to open a question with two problem, but after looking at the answers so far ill describe another problem I had:
I also installed Jquery using nmp install jquery --save and added to angular.json:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.css",
"src/styles.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/tether/dist/js/tether.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
In this case, after removing #import "~bootstrap/dist/css/bootstrap.css"; from styles.css`, bootstrap is not working at all.
The only way i got bootstrap to work is as i described in the question.
EDIT 2:
I started a new project and followed #HDJEMAI s answer instructions.
I now still get the same page as in the picture but its now working through the rows added to styles and scripts in angular.json and not through the #import "~bootstrap/dist/css/bootstrap.css" in the styles.css file . But the problem is still that is not the same as in the tutorial even though the code is the same.
This is what he gets in the tutorial:
You have to install both bootstrap and JQuery:
npm install bootstrap jquery --save
Then you will find these files in your node module folder:
node_modules/jquery/dist/jquery.min.js
node_modules/bootstrap/dist/css/bootstrap.min.css
node_modules/bootstrap/dist/js/bootstrap.min.js
Then you have to update your angular.json file:
In the architect, build section, or even test section if you want to see Bootstrap working as well when testing your application.
"styles": [
"styles.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
"./node_modules/bootstrap/dist/js/bootstrap.min.js"
],
If you do not add the jquery.min.js script Bootstrap will not work.
Another requirement is popper.js if you need Bootstrap dropdown then you will need to install it and add the script file as well
npm install popper.js
Then add this script as well
"styles": [
"styles.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
"./node_modules/popper.js/dist/popper.js",
"./node_modules/bootstrap/dist/js/bootstrap.min.js"
],
Bootstrap dropdown require Popper.js (https://popper.js.org)
If you are adding the bootstrap path into the angular.json file, make sure it is the styles within the project\architect\build. Not the one in the project\architect\test.
{
"projects": {
"architect": {
"build": {
"styles": [
"node_modules/bootstrap/dist/bootstrap.min.css",
"src/styles.css"
],
"test": {
"styles": [
"src/styles.css"
],
First uninstall bootstrap. The next step is to install bootstrap by following command
npm install --save bootstrap#3 A
next go to styles.css and paste
#import "node_modules/bootstrap/dist/css/bootstrap.css"
I had the same issue. Below helped for me.
Stop the server and recompile using
ng serve
As I see, if you are following "Maximilian Schwarzmüller" course in UDEMY, make sure you have installed Bootstrap 3, not anything else. Use these commands in your project folder (the uninstall only if other version are installed).
npm uninstall --save bootstrap
npm install --save bootstrap#3
This will install it locally to your project.
I had Bootstrap4 installed (thinking the course would still work with 4 instead of 3) and using Bootstrap3 instead worked in this same project as your in the course (without popper and jQuery).
I've had a similar issue after installing bootstrap popper.js jquery I've manually removed bootstrap popper.js jquery folders from node_modules then I've done the following:
npm i bootstrap#latest jquery popper.js --save
going back to angular.json I've made sure I've included the following scripts under projects > architect > build :
"styles": [
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"./src/styles.scss"
],
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
"./node_modules/bootstrap/dist/js/bootstrap.min.js",
"./node_modules/popper.js/dist/popper.min.js"
],
It solved the problem for me.
On my end, I've solved this issue by adding the following into "style.css" file and it worked.
#import "~bootstrap/dist/css/bootstrap.css"
Add your angular.json
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"xtreme-admin-angular": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/xtreme-admin-angular",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"node_modules/bootstrap/dist/bootstrap.min.css"
//Your root depend this path
]
And rerun your project
Add this 3 links in your index.html file. You don't have to install bootstrap or jquery or update your angular.json file. Works as a charm.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
install npm install bootstrap#latest jquery --save
install npm install popper.js;
then go to Angular.json file (line no 47) change lines with this:
"styles": [
"src/styles.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
"./node_modules/popper.js/dist/popper.js",
"./node_modules/bootstrap/dist/js/bootstrap.min.js"
],
After installation of bootstrap and adding it to angular.json file.
If bootstrap doesn't render, just change the port of development URL:
ng serve --port <your choice of port>
I think it is because of the problem with bootstrap, try this:
Step 1.
Inside .angular-cli.json file
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css"
]
Remove "../node_modules/bootstrap/dist/css/bootstrap.min.css"
Step 2.
Go to styles.css
Import bootstrap by adding this line
#import "~bootstrap/dist/css/bootstrap.css";
These steps solved the errors I got during the building process.
Had same issues with bootstrap items using VS code editor. I tried ng build before ng serve and bootstrap items worked fine.
I’d start by checking both “styles” and “scripts” under “build” and “test” sections
Add this line in style.css and its gonna work.
#import "~bootstrap/dist/css/bootstrap.css";
Thanks
For me I had to do both, copy the node_modules jquery and bootstrap js files in angular.json
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
And copy #import "~bootstrap/dist/css/bootstrap.css"; in styles.css
I have also created a project following the video. This works for me
npm uninstall --save bootstrap npm install --save bootstrap#3
then in style array added like this
"styles": [
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
Please check all your .component.ts files, especially recipe.component.ts. Maybe there is CSS encapsulation tuning like
#Component({
selector: 'app-recipes',
templateUrl: './recipes.component.html',
styleUrls: ['./recipes.component.css'],
encapsulation: ViewEncapsulation.ShadowDom
})
If it is so. You should remove encapsulation property.
I had the same problem when using bootstrap in an Angular project. I correctly installed it and updated the angular.json file, but I forgot to import it into the global style sheet (styles.css). As a result, I included it in the global stylesheet. So, if your installation is correct and your angular.json is up to date, please try importing it in the global style sheet (styles.css) as shown below:
#import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
I'm hoping it works because it did for me when I had the same problem.
I check many way
"../"...
or
"./"...
or /
also I don't want to use in "style.css" because maybe want add some "js" files or "css" files that depend on "js" file
to this reason
the best way was
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/popper.js/dist/umd/popper.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
BUT restart your PC not only browser or IDE