WordPress meets Tailwind – plugins interfaces  without extra CSS files
Tags: tailwindcss, wordpress, css, php
Published: 2020-11-19 08:33:18

Modern web-development possesses numerous CSS-frameworks, the majority of which strictly dictate their own styles and rules for project creation. The most popular CSS-framework Bootstrap offers a ready-made grid and component styles from the majority of UI elements, such as buttons, tables, tabs or inputs. As a result, customization on the go becomes a challenge. We must rewrite Bootstrap styles time after time in order to achieve the necessary effect in our project. 
Tailwind offers a totally new approach to stylization. It doesn’t create components but uses small-sized utility classes instead. A good example of differences between these frameworks is buying a ready-to-use brand computer compared to assembling a system unit yourself using the prepared tools.
Of course, Bootstrap may be customized in a centralized manner, however the stylization will once again be applied to all the components at once. There is no quick way to change the style of a separate button or search element without writing an additional CSS-class. That is when **Tailwind** comes in handy. In a standard configuration, it includes a flexboxes and grids, containers and various utilities, which cover almost all the standard CSS-properties. 
For example, in order to create a standard button as in Bootstrap:
```html
<button type="button" class="btn btn-primary">Primary</button>
```
the set of styles may look something like this:
```html
<button type="button" class="inline text-center bg-blue-500 hover:bg-blue-600 text-white rounded px-4 py-2">Primary</button>
```
Looks bulky. And what happens when you face the need to quickly change the indents inside the Bootstrap button? You will have to open the file with styles, create a new class-modifier and write new values into it. This process will take quite some time. When it comes to Tailwind, it is enough to change the indent settings in HTML:
```html
<button type="button" class="inline text-center bg-blue-500 hover:bg-blue-600 text-white rounded px-8 py-4">Primary</button>
```
Utilities save us from constant shifts from HTML to CSS and back, that allows writing the styles as we go.
And what should we do once we have confirmed the appearance of the button and it can already be used as a component? It is not a problem either. We simply need to create a style of our component and copy all styles of the button into the special directory inside of it **@apply**:
```css
.button {
    @apply inline text-center bg-blue-500 hover:bg-blue-600 text-white rounded px-8 py-4;
}
```
We will not discuss all characteristics and utilities of the framework Tailwing in detail. It can be studies more in depth on the [official website](https://tailwindcss.com), and practice writing styles at [Tailwind Play](https://play.tailwindcss.com).
In our article we will try to apply it in development of a plugin for CMS WordPress by using Tailwind styles in admin-panel.
Let’s create the simplest plugin consisting of one file:
```php
<?php
/*
 * Plugin Name: Talwindcss
 */

function admin_style_tailwindcss() {
    wp_enqueue_style('admin-style-tailwindcss', plugins_url( 'tailwindcss.css', __FILE__ ));
}
add_action('admin_enqueue_scripts', 'admin_style_tailwindcss');


function tailwindcss_admin_menu() {
    add_menu_page('Tailwindcss', 'Tailwindcss', 'edit_others_posts', 'tailwindcss', 'tailwindcss_print_page');
}
add_action('admin_menu', 'tailwindcss_admin_menu');

function tailwindcss_print_page() {
    echo '<div class="wrap tailwindcss"><h2>Tailwindcss</h2><button type="button" class="inline text-center bg-blue-500 hover:bg-blue-600 text-white rounded px-8 py-4">Primary</button></div>';
}
```
Here we connect a style from a plugin folder and create a plugin page in admin-panel to demonstrate how Tailwind works. 
Tailwind in a ready format cannot be used in WordPress plugins, because it will clash with the existing styles of the core. It contains its own style reset, which we turn off, as well as classes without prefixes, which we add the prefixes to. We will assemble the style on the basis of Symfony Encore. In order to do that we will setup needed packages from the root of the plugin:
```yarn add --dev @symfony/webpack-encore tailwindcss postcss-import postcss-loader autoprefixer```
To packages.json we will add a section with assembly commands to scripts:
```js
{
  "private": true,
  "scripts": {
    "dev-server": "encore dev-server",
    "dev": "encore dev",
    "watch": "encore dev --watch",
    "build": "encore production"
  },
  "devDependencies": {
    "@symfony/webpack-encore": "^0.31.0",
    "autoprefixer": "^9.0.0",
    "postcss-import": "^12.0.0",
    "postcss-loader": "^3.0.0",
    "tailwindcss": "^1.9.6"
  }
}
```
Attention! At the time of publication of this article, Encore required autoprefixer version 9, postcss-import version 12 and postcss-loader version 3 to work correctly.
The next step is to initialize config Tailwind:
```npx tailwindcss init```
This command will create a file tailwind.config.js, inside of which we will configure the framework. We will also create the initial styles file: tailwind.css inside a subfolder src with the following contents:
```css
@tailwind base;

@tailwind components;

@tailwind utilities;
```
We will then create a config file PostCSS postcss.config.js:
```js
let tailwindcss = require('tailwindcss');

module.exports = {
    plugins: [
        tailwindcss('./tailwind.config.js'), // your tailwind.js configuration file path
        require('autoprefixer'),
        require('postcss-import')
    ]
}
```
And, of course, create the file for config Webpack-encore webpack.config.js:
```js
const Encore = require('@symfony/webpack-encore')
Encore
    .setOutputPath('build')
    .setPublicPath('build')
    .addStyleEntry('tailwindcss', './src/tailwindcss.css')
    // enable post css loader
    .enablePostCssLoader((options) => {
        options.config = {
            // directory where the postcss.config.js file is stored
            path: './postcss.config.js'
        };
    })
module.exports = Encore.getWebpackConfig()
```
Now that all is ready, we launch the assembling of Tailwind:
```yarn run dev```
We go to the page of plugin options and see that the styles have been applied. Although, at this moment the styles aren’t applied globally and we didn’t turn off style reset that is embedded in Tailwind. Let’s change the file tailwind.config.js as follows:
```js
module.exports = {
  important: '.tailwindcss',
  corePlugins: {
    preflight: false,
  },
  future: {
    // removeDeprecatedGapUtilities: true,
    // purgeLayersByDefault: true,
  },
  purge: [],
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
}
```
The option that we created ```important: '.tailwindcss'``` adds an extra nesting to all the framework utilities. Now all of them will be used only inside the elements with class talwindcss. The second option ```preflight: false``` turns off the embedded style reset.
Now all is well, and the styles will not clash with the styles of the core and other plugins. The only thing that is left to do is to launch the assembly command for production:
```yarn run build```
The full code of the plugin lays in [repository](https://github.com/zorca/tailwindcss-plugin).