Why is tailwind css having no effect? - tailwind-css

No errors, but Tailwind doesn't apply any style:
package.json
"dependencies": {
"tailwindcss": "npm:#tailwindcss/postcss7-compat#^2.0.2",
"vue": "^3.0.5"
},
"devDependencies": {
"autoprefixer": "^9.8.6",
"parcel-bundler": "^1.12.4",
"postcss": "^7.0.35",
"#vue/cli": "^5.0.0-alpha.2"
},
postcss.config.js
module.exports =
{
plugins:
{
tailwindcss: {},
autoprefixer: {}
}
}
tailwind.config.js
module.exports =
{
purge: [],
darkMode: 'class', // or 'media' or 'class'
theme:
{
extend: {},
},
variants:
{
extend: {},
},
plugins: [],
}
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="css/main.css">
</head>
<body class="dark bg-gray-100">
<div class='app' id='app' class="bg-red-500">
<div class="text-gray-50">hello world</div>
</div>
</body>
</html>
main.css
#import "../../node_modules/tailwindcss/base.css";
#import "../../node_modules/tailwindcss/components.css";
#import "../../node_modules/tailwindcss/utilities.css";
Built using: node ./node_modules/.bin/parcel src/index.html

Instead of importing Tailwind's CSS files from the node_modules directory, use the #tailwind directives as instructed in the Include Tailwind in your CSS section in the Tailwind docs:
#tailwind base;
#tailwind components;
#tailwind utilities;
Then it should work – I just confirmed it on my machine. (Though your build command didn't work for me, so I used npx parcel src/index.html instead.)
If you take a look at the CSS files that you were importing, you'll see that they contain the same #tailwind directives that I mentioned above. I'm not sure, but I think that PostCSS first runs the Tailwind plugin, and after that processes the #imports. This would explain why PostCSS didn't process the #tailwind directives from the imported CSS files (because it had already run the Tailwind plugin).

Related

tailwind is not working with javascript and vite

I'm building a javascript app with vite.
I want to use tailwind for quick styling but setting it up in my project is something I struggle with all the time.
From the experience I've set it up but it's not working and I don't know why..
I suspect it is because of my change of root directory in the vite project.
My homepage:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link href="/src/style/output.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hermes</title>
</head>
<body>
<h1>My homepage</h1>
Test
<div id="app" class="h-14 bg-gradient-to-r from-purple-500 to-pink-500">h</div>
<script type="module" src="../main.ts"></script>
</body>
</html>
My tailwind config:
/** #type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/views/*.html"],
theme: {
extend: {},
},
plugins: [],
}
My main.css (input file by tailwind)
#tailwind base;
#tailwind components;
#tailwind utilities;
The output file which is linked in the html, is full of the basic style rest by taildwind
This is my folder structure:
I believe you need to create the postcss.config.cjs file manually with this content:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
The tailwind docs make it sound as though npx tailwindcss init -p will automatically create postcss.config.cjs but that didn't happen for me.
Install tailwindcss and its peer dependencies via npm, and then run the init command to generate both tailwind.config.cjs and postcss.config.cjs.
Once I added postcss.config.cjs and restarted the dev server the styles were applied.

Why Tailwind Height doesn't work (breakpoints)?

I installed Tailwind CSS and Elements on my Laravel project.
I'm doing the responsive part, but the "height" is not working when I use breakpoints (i.e "md:xxx").
I tried with other things like background color, width or flex, it's working.
<div class="bg-pink-500 md:bg-black h-16 md:h-64"></div>
The only change I made on Tailwind is to set my application color palette.
I see someone having the same issue and talking about a file missing (postcss.config.js).
I have postcss installed (v8.4.6) in my package.
I tried to manually create the file and fill with this (doesn't work) :
postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
]
}
Here is my code :
HTML CSS links
<!-- Styles -->
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
{{-- Tailwind Components --}}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght#300;400;500;600;700&display=swap" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tw-elements/dist/css/index.min.css" />
webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
]);
mix.sass('resources/scss/style.scss', 'public/css');
tailwind.config.js
const defaultTheme = require('tailwindcss/defaultTheme');
module.exports = {
purge: [
'./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
'./storage/framework/views/*.php',
'./resources/views/**/*.blade.php',
'./resources/**/*js'
],
theme: {
extend: {
fontFamily: {
'montserrat': ['Montserrat'],
sans: ['Montserrat'],
serif: ['Montserrat'],
mono: ['Montserrat'],
display: ['Montserrat'],
body: ['Montserrat']
// sans: ['Nunito', ...defaultTheme.fontFamily.sans],
},
colors: {
'black1': '#181818',
'black2': '#323232',
'white0': '#F9F9F9',
'white1': '#F1F1F1',
'white2': '#E4E4E4',
'red1': '#8E0000',
'red2': '#BA0000',
'red3': '#D62323'
},
},
},
variants: {
extend: {
opacity: ['disabled']
},
},
plugins: [
require('#tailwindcss/forms')
]
};
Thank you
UPDATE:
The css keeps default settings instead of using my breakpoint settings.
Screenshot of CSS in dev tool
Has you can see on the post's screenshot, the CSS file (index.min.css) coming from Tailwind CDN overwritte app.css, just call Tailwind CDN first:
{{-- Tailwind Components --}}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght#300;400;500;600;700&display=swap" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tw-elements/dist/css/index.min.css" />
<!-- Styles -->
<link rel="stylesheet" href="{{ asset('css/style.css') }}">
<link rel="stylesheet" href="{{ asset('css/app.css') }}">

Vue component not showing

I followed the series codetube "youtube clone" and I did everything like the Alex but the Vue component not working. I am not working on localhost but on server. I would be very glad for any suggestions.
My app.js
require('./bootstrap');
Vue.component('videoup', require('./components/VideoUpload.vue'));
const app = new Vue({
el: '#app'
});
My VideoUpload.vue file:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Upload</div>
<div class="panel-body">
...
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
My blade file:
#extends('layouts.app')
#section('content')
<videoup></videoup>
#endsection
My app.blade file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Styles -->
<!-- <link href="/css/app.css" rel="stylesheet">-->
<link rel="stylesheet" href="/css/app.css">
<!-- Scripts -->
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
</head>
<body>
<div id="app">
#include('layouts.partials._navigation')
#yield('content')
</div>
<script src="/js/app.js"></script>
</body>
</html>
My gulfpile.js:
const elixir = require('laravel-elixir');
require('laravel-elixir-vue-2');
require('laravel-elixir-webpack-official');
elixir((mix) => {
mix.sass('app.scss')
.webpack('app.js');
});
My webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
// vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.common.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
devtool: '#eval-source-map'
};
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map',
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
};
It's difficult to debug your setup because I have no idea what tutorial you followed, how you are bundling your code (webpack or browserify) or what build tools you are using (gulp, elixir etc), but I think the most important thing is to understand how Vue works, and then you will be able to better understand how to solve this yourself.
Firstly, vue has two builds - a standalone build and a runtime-only build. The difference between these is that the standalone build includes a template compiler and the runtime-only build does not.
Render Functions
Vue compiles templates in to render functions to work (which are just javascript functions), it doesn't use HTML at all, so if you haven't written a render function or you haven't pre-compiled your components (using .vue files and a bundler like browserify or webpack) then you must use the standalone build; and this includes the base component itself, so the important thing to know is:
If you are trying to use a component inside anything other than a .vue file you need to use the standalone build.
because you need the compiler to turn the HTML into a render function.
So, looking at your code, you are trying to use your component inside a .blade.php file, which isn't a single file component so you will need the standalone build in your project.
When using npm, vue imports the runtime-only build by default:
// ES6
import `Vue` from `vue` // this imports the runtime-only build
// ES5
var Vue = require('vue'); // this requires the runtime-only build
But you need to make sure you are using the standalone build, and how you do this depends on whether you use webpack or browserify. If you are using webpack, you need to add the following to your webpack config:
resolve: {
alias: {
'vue$': 'vue/dist/vue.common.js'
}
}
If you are using browserify you will need to add the following to your package.json:
"browser": {
"vue": "vue/dist/vue.common"
},
And also make sure that resources/assets/views/layouts/app.blade.php wraps everything in a div with the id app:
...
<body>
<div id="app">
...
</div>
</body>
...
Update
Based on your webpack config it looks like your issue is here:
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
This says you are compiling main.js in the src folder and outputting it to the dist folder as build.js.
Laravel uses a different structure, so you will need to change this to:
entry: './resources/assets/js/app.js',
output: {
path: path.resolve(__dirname, './public/js'),
publicPath: '/public/',
filename: 'app.js'
},
This now says, compile resources/assets/js/app.js and output the file to public/js/app.js. I don't use webpack myself so that may need a little tweaking, but that should get your project up and running.
I had the same issue. the following solved it for me..
I changed:
require('./components/mycomponent.vue')
to:
import MyComponent from "./components/mycomponent.vue";

How to stop FOUC when using css loaded by webpack

I am getting FOUC when loading css inside of my entry point when using webpack. If I remove my css from being loaded by webpack and just include it in my html file as a normal link then the problem with FOUC goes away.
Note: This not just with bootstrap framework, I have tested with
Foundation and Materialize with the same results
The code posted below is just a test example of my problem using Bootstrap.
Html code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="jumbotron">
<h1>Navbar example</h1>
</div>
</div> <!-- /container -->
<script src="build/bundle.js"></script>
</body>
</html>
bootstrap.js main entry point
import "../node_modules/bootstrap/dist/css/bootstrap.css";
import bootstrap from 'bootstrap'
$(document).ready(function () {
console.log('bootstrap loaded')
});
webpack.config.js
var path = require('path');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const webpack = require("webpack");
module.exports = {
entry: './src/bootstrap.js',
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js'
},
resolve: {
extensions: ['', '.js']
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
'window.jQuery': 'jquery'
})
],
devtool: 'inline-source-map',
module: {
resolve: {
modulesDirectories: ['node_modules']
},
loaders: [
{
test: path.join(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['es2015']
}
},
{ test: /\.css?$/, loader: 'style!css'},
{ test: /\.html$/, loader: 'html' },
{ test: /\.(png|gif|jpg)$/, loader: 'url', query: { limit: 8192 } },
{ test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url', query: { limit: 10000, mimetype: 'application/font-woff2' } },
{ test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url', query: { limit: 10000, mimetype: 'application/font-woff' } },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file' },
]
}
};
ExtractTextWebpackPlugin will allow you to output your CSS as a separate file rather than having it embedded in your JS bundle. You can then include this file in your HTML, which as you said, prevents the flash of unstyled content.
I'd recommend only using this in production environments, as it stops hot-loading from working and makes your compile take longer. I have my webpack.config.js set up to only apply the plugin when process.env.NODE_ENV === "production"; you still get the FOUC when you're doing a development build/running the dev server, but I feel like this is a fair trade off.
For more information on how to set this up, take a look at SurviveJS's guide.
Update: As noted in the comments, ExtractTextWebpackPlugin has now been superceded by mini-css-extract-plugin - you should use that instead.
A bit late to the party, but here's how I do it.
While I recognize the merits of extract-text-plugin, it's plagued by a rebuild bug that messes up css order, and is a pain to set up. And setting timeouts in js is not something anyone should be doing (it's ugly and is not guaranteed 100% to prevent fouc)...
So my index.html is:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style>
#app { display: none }
</style>
<title></title>
</head>
<body>
<div id="app"></div>
<script src="scripts/bundle.js"></script>
</body>
</html>
Then, in client.js at the very end I add:
include "./unhide.css";
...and unhide.css contains a single line:
#app { display: block }
Voila, you see nothing until the whole app is loaded.
It's janky, but I wrap ReactDom.render() in a setTimeout() in my root index.js file.
setTimeout(ReactDOM.render(...), 0)

Build to style tag using webpack

In my webpack project, I want to inject styles as a <style> tag into the page, using JavaScript, rather than referencing an external file via a <link> tag. I am using style-loader for styles currently, and it outputs a bunch of link tags in the head.
Rather than this:
<html>
<head>
<link rel="stylesheet" type="text/css" href="/things">
<link rel="stylesheet" type="text/css" href="/things">
<link rel="stylesheet" type="text/css" href="/things">
</head>
<body>
I want this:
<html>
<head>
</head>
<style>
/* things here */
</style>
<body>
Is there any way of doing this? I had a read of the documentation but it only mentions building CSS output files, not outputting to a style tag in this way.
Reasons:
I am publishing a module to be included via NPM/Bower, and I would rather keep the build as a single package, rather than having to revert to
It is faster. There is a lot of literature around minimising the number of requests, including from webpack: https://github.com/christianalfoni/react-webpack-cookbook/wiki/Inlining-images
It turns out that adding the loaders to the imports manually does the trick. Removing this loaders definition from the webpack config:
module: {
loaders: [{
test: /\.scss$/,
loaders: ['style!css!sass!']
}]
}
and adding manually to each style import:
import React from 'react';
import 'style!css!sass!./fieldList.scss'; // -> this line
class FieldList extends React.Component
This causes the styles to be injected in my preferred way.
Try to use second entry point for styles.
All styles will be loaded first and then added to <style> tags in <head> section.
webpack.config.js:
export default {
entry: {
app: ['./app'],
styles: ['./styles']
},
loaders: [{
test: /\.(scss|css)$/,
loaders: [
'style',
'css',
'autoprefixer?browsers=last 3 versions',
'sass'
]
}]
}
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="styles.js"/>
</head>
<body>
<script src="app.js"/>
</body>
</html>

Resources