Tailwind CSS how to code pixel perfect design - css

Just started to use https://tailwindcss.com
And can't figure out how to code pixel perfect design only with tailwind classes. Simple example, I need padding-left 22px but closest tailwind class is pl-6 and pl-8 which is 24px and 32px respectively. So at the end of the day, I have a bunch of tailwind classes + 1 custom where I make arrangements this defeats the purpose of this framework "utilities first".

Ok got it, I need to edit tailwind.config.js and set custom sizes there. For example:
height: [
...
'278px': '278px',
...
]
So now this size can be set with <div clas="h-278px">...</div>
Update:
After completed many projects on top of TailwindCSS I learned that it's not very optimal to set spacing/w/h... in tailwind config if it's used only once. It's better to go with the custom class you can always use #apply in that class anyway.
Update 2021:
As of tailwind version 2.1 we can enable JIT and use arbitrary styles like this:
mb-[278px]

You can try this for px and % styling -
w-[100px] or w-[50%]

Has mention by Mladen Janjetovic, you can also add new utilities to you tailwind setup.
The easiest way to add your own utilities to Tailwind is to simply add them to your CSS.
#tailwind base;
#tailwind components;
#tailwind utilities;
#layer utilities {
.h-278 {
height: 278px;
}
}
So now this height can be set with
<div clas="h-278">...</div>
By using the #layer directive, Tailwind will automatically move those styles to the same place as #tailwind utilities to avoid unintended specificity issues.
Using the #layer directive will also instruct Tailwind to consider those styles for purging when purging the utilities layer.

Related

What is base in tailwind config used for?

I was wondering what could be configured in tailwind config file, I just can not grasp what could be configured in this file, specially the base part.
#tailwind base;
#tailwind components;
#tailwind utilities;
Could anybody elaborate this?
Using the #tailwind means to insert Tailwind’s directive. Tailwind supports these four directives base, components, utilities, and screens styles into your CSS.
Base injects Tailwind's base styles like inserting any layout
theme etc. Details use of the base
#layer base {
h1 {
#apply text-2xl;
}
h2 {
#apply text-xl;
}
}
Similarly, components work for extracting some classes like buttons.
You can go through all this for getting hints

Controlling the specificity of CSS Modules in a Next.js App

I'm trying to figure out a good workflow of how to use Tailwind together with CSS Modules in Next.js, but I'm running into some tricky problems regarding specificity and the order in which styles are inserted by Webpack.
Consider the following use case: I want to create a reusable Button component whose styles can be overridden with utility classes. Option 1 is to extract the component, as mentioned in the Tailwind Docs:
/* button.jsx */
export const Button = props => <button {...props} className={`btn {props.className}`} />
and in my tailwind.css file I'd add the classname in the #layer directive:
#tailwind base;
#tailwind components;
#tailwind utilities;
#layer components {
.btn { #apply ... }
}
This is nice because I can override any of the buttons styles with utility classes, since they have higher specificity. However, I see a few minor problems here:
the class is now global, so it's included in every page even if I don't use the component
the style and component are no longer colocated - this might get messy if I create many such classes
Option 2 would be to use a CSS Module and apply the classes like this:
/* button.module.css */
.btn { #apply ...}
/* button.jsx */
import styles from "./button.module.css";
export const Button = props => <button {...props} className={`${styles.btn} {props.className}`} />
This way the CSS only gets loaded when the component is used, and the styles are colocated. Problem here is that in Next.js CSS Modules are inserted after global CSS, so they have higher specificity. Which totally makes sense, usually I'd want my CSS Modules to be able to override global styles. However, in this case I'd like them to be inserted before my global styles so that I can override them with utility classes.
I assume this should be possible by adjusting the Webpack config? Does anyone proficient with Webpack know how to achieve this?
I actually found a nice solution in tailwind v3.0, which is using the new important option. In your tailwind.config.js you can now add this line:
module.exports = {
// ...
important: '#__next'
}
This way, all your utilities are getting prefixed with #__next (the root element in Next.js), which increases their specificity above that of CSS Modules.
Go for the second option and simply add ! to the property to make that important.
/* button.module.css */
.btn { #apply !mb-0 }

TailwindCSS and Wordpress – Styling plugin output

I'm trying to figure out the best way of using TailwindCSS for WordPress theme development. I'm confused about the best way to style html output that you don't have easy control over like a plugin. Or for example a menu, how to style item states that WP provides useful classes to style like .current_page_item.
Previously I would typically dequeue plugin css and then add my own css rules applied using the css classes that the plugin outputs.
I was thinking I could do something similar using tailwinds #apply feature to apply a bunch of tailwind classes to an element using the plugins class name.
e.g.
.plugin-btn { #apply bg-blue-500 text-white font-bold py-2 px-4 rounded; }
or in the case of a menu:
.current_page_item { #apply text-red-500 hover:text-blue-500 }
This method seems a bit awkward with Tailwind v1.x as #apply didn't work with responsive class variants or pseudo class variants but v2 it seems #apply does work with these now.
Is this a good solution. What do other people do?
So if I understand you correctly, you tend to remove the styling of plugins & redo it your self? And the problem you have now is to create the responsive styling (using Tailwind CSS)?
If that's the case you could do something like:
// This would be the default style from a mobile-first perspective
.plugin-name {
#apply w-full;
}
// This would be the style from a MD perspective (I think iPad devices and up?)
#screen md {
.plugin-name {
#apply w-1/2;
}
}
When I need to add hover, focus etc I do it like:
When using SCSS:
.item-class-name {
#apply text-black ...;
&:hover {
#apply text-white bg-black;
}
}
When using CSS:
.item-class-name {
#apply text-black ...;
}
.item-class-name::hover {
#apply text-white bg-black;
}
I'm currently creating a (personal for now) starter theme which is built on TailWind CSS & AlpinejS, and using the laravel-mix setup.
This makes it easier to achieve something like:
// app.scss file in which I add the tailwind components
#tailwind base;
#tailwind components;
#tailwind utilities;
// Additional scss files are divided in components folder
#import './components';
// You could add a 'plugins' file like
#import './plugins';
// In the plugins file you would import all the plugin related styling files...if that makes sense.

How to scope Tailwind Css

I cannot find a good way to scope tailwind CSS when including it in a system where I don't want it to apply globally that works with custom build options.
Essentially I want to do this:
.tailwind{
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
}
But PostCSS importer doesn't like this due to the fact it imports before the tailwind placeholders are replaced. So the only way to make it work is to break the build into 2 stages then import the compiled css like:
.tailwind{
#import "tailwindcss.css";
}
It works but it breaks some of the css rules which show up in dev tools.
Is there a better way to scope tailwind to stop it interfering with other systems?
I've found that you can use postcss-nested for this. Install the plugin, add it as the first plugin to your PostCSS config file and this should work:
.tailwind {
#tailwind base;
#tailwind components;
#tailwind utilities;
#tailwind screens;
}
From the docs...
The prefix option allows you to add a custom prefix to all of Tailwind's generated utility classes. This can be really useful when layering Tailwind on top of existing CSS where there might be naming conflicts.
For example, you could add a tw- prefix by setting the prefix option like so:
// tailwind.config.js
module.exports = {
prefix: 'tw-',
}
You will achieve this by setting important in the tailwind config to your parent class or id. See docs.
// tailwind.config.js
module.exports = {
important: '.tailwind',
}
Unfortunately, this seems to only be affecting the components and utilities styles... the base styles will remain unaffected.
As requested leaving my answer here:
I used the prefix as suggested by Lanny
// tailwind.config.js
module.exports = {
prefix: 'tw-',
}
And then made my tailwind css file like this:
#import "tailwindcss/components";
#import "tailwindcss/utilities";
Then I just manually copied any base styles that I wanted manually into my main css file and manually changed anything that conflicted.
I think the tricky part here is actually about the preflight/reset.css. You want to fend off external styling from coming to your scope but also don't want to pollute the external system with your tailwind style.
My current set up include following steps:
In tailwind.config.js we disable the prefight, defining a prefix tw-, and adding an extra selector #app via option important. The last change will add an extra css selector to output, e.g. #app .tw-mb-4.
module.exports = {
important: '#app',
prefix: "tw-",
corePlugins: {
preflight: false,
},
Find and copy the content of base.css from node_modules folder before pasting it into a scss file with a parent selector #app. You can compile this using any online SCSS compiler. This will help you only reset styling within your scope.
#app {
/*content from base.css*/
}
Copy compiled the styling from #2 and paste to the beginning of your tailwind css file.
Structure the html so you contents are wrapped within a div with the id of #app.
Tailwind's important option doesn't seem to add selector to #layer component so you will have to include that in your component styling.
#layer components {
#app .page-h1 {
#apply tw-mt-0 tw-mb-2 tw-text-center tw-leading-8 tw-text-4xl md:tw-text-5xl;
}
}
According to the docs:
If you’d like to completely disable Preflight — perhaps because you’re integrating Tailwind into an existing project or because you’d like to provide your own base styles — all you need to do is set preflight to false in the corePlugins section of your tailwind.config.js file.
This seems to work with Wordpress in the admin but it does remove the normalization, like cursor: pointer on button hover, for example.
What I have done is this
module.exports = {
prefix: 'tw-',
content: [
"./src/**/*.{html,ts}",
],
theme: {
extend: {},
},
purge: {
enabled: true,
content: ['./src/**/*.{html,ts}']
},
plugins: [],
corePlugins: {
preflight: false,
}
}
It will reduce build size as ,I have purged CSS, disable global CSS,as I have used preflight, and now If u want to apply tailwind class use as
<div class="tw-m-4"></div>
As we have used tw in prefix

TailwindCSS use #apply with placeholder color

I am trying to use #apply together with placeholder color in TailwindCSS, but for some reason, it does not seem to work although I am able to use #apply together with other properties. I am also able to use the placeholder color options as a CSS class. It just doesn't work with #apply.
#tailwind base;
input {
#apply placeholder-gray-900;
}
#tailwind components;
#tailwind utilities;
By trying this I end up with this error:
`#apply` cannot be used with `.placeholder-gray-900` because `.placeholder-gray-900` either cannot be found, or its actual definition includes a pseudo-selector like :hover, :active, etc. If you're sure that `.placeholder-gray-900` exists, make sure that any `#import` statements are being properly processed *before* Tailwind CSS sees your CSS, as `#apply` can only be used for classes in the same CSS tree.
This is because the placeholder text is changed with a pseudo-selector, ::placeholder. If you look at the placeholder docs it's shown in light gray after each class definition.
As you can't #apply classes with a pseudo-selector, you'll need to add the pseudo-selector to your code, something like this (note you'll need to use the text color utilities here):
input::placeholder {
#apply text-gray-900;
}
For v2.1.4 ...
By default, the active variant is not enabled for any core plugins. Maybe its actual definition includes a pseudo-selector like :hover, :active, etc. You can control whether active variants are enabled for a plugin in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
backgroundColor: ['active'],
}
},
}
Read here for Tailwind - Hover, Focus, & Other States

Resources