Tailwind Gradients
Generate CSS Background Gradients and SVG Fill&Stroke Gradients
After reading a post about svg-gradient-fill i wrote this plugin, its not usually a tailwind concern to write extra files. This might be more suited for webpack plugin or loader, but since i am already using tailwind to generate gradients...
Usage
// tailwind.config.js
const { tailwindGradients } = require('@therobot/tw-gradients')
const { writeFileSync } = require('fs')
const config = {
plugins: [
tailwindGradients({
/*
* Adds base style .fill-inherit svg { fill: inherit }
*/
addSvgInherit: true,
/*
* svgUrlPrefix: '~/gradients.svg'
*
* Makes resulting style looks like this:
* fill: url(~/gradients.svg#gradient-name)
*
* Its not supported by most browsers
*
* Just in case you got some webpack plugins for this
*/
classPrefix: 'bg-gradient',
onResult: svg => writeFileSync('./public/gradients.svg', svg),
}),
],
theme: {
gradients: theme => ({
red: {
// .bg-gradient-red .stroke-red .fill-red
fallback: 'currentColor',
colors: [theme('colors.red.700'), theme('colors.orange.600')],
},
var: {
// .bg-gradient-var
// you need to define --my-color in hidden svg
// :root { --my-color: red }
colors: ['var(--my-color)', theme('colors.yellow.700')],
angles: 135,
},
// .bg-gradient-gray
gray: {
fallback: 'last',
angles: [90],
colors: [theme('colors.gray.700'), theme('colors.gray.800')],
},
// .bg-gradient-teal-180 .bg-gradient-teal-90
teal: {
fallback: 'first',
colors: [
theme('colors.teal.700'),
'ease-in-out', // it will not be used in svg, but `postcss-easing-gradients` will see it in css
theme('colors.blue.500'),
],
angles: [180, 90],
},
}),
},
}
Hot Reload Loop
If something causes infinite hot reload loop, add more regexp to webpack watchOptions
// vue.config.js
module.exports = {
configureWebpack: {
devServer: {
watchOptions: {
ignored: [/node_modules/, /public/, /SvgGradients/],
},
},
},
}
const { tailwindGradients } = require('@therobot/tailwindcss-gradients')
const { writeFileSync } = require('fs')
const vueTemplate = svg =>
[
`<template functional>\n${svg}\n</template>`,
`<style lang="postcss">`,
` .v-icon { stroke: none; fill: none; }`,
` .v-icon svg { stroke: inherit; fill: inherit; }`,
`</style>`,
`<script lang="ts">`,
`import Vue from 'vue'`,
`export default Vue.extend<{}>({ functional: true, name: 'CssGradients' })`,
`</script>`,
].join('\n')
const config = {
plugins: [
transitionsConfig,
tailwindGradients({
addSvgInherit: true,
classPrefix: '',
svgIdPrefix: '',
suffix: 'gradient',
onResult: (svg, gradients) => {
writeFileSync('./src/assets/gradients.svg', svg)
writeFileSync(
'./src/components/atoms/SvgGradients.vue',
vueTemplate(svg)
)
writeFileSync(
'./src/assets/gradients.inner.svg',
gradients
.join('')
// remove line breaks
.replace(/\n/g, '')
// remove two or more spaces
.replace(/[\s]{2,}/g, '')
)
},
}),
],
}
// vue.config.js
process.env.VUE_APP_BODY_PREFIX = fs.readFileSync(
'./src/assets/gradients.svg',
'utf8'
)
module.exports = {}
<!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.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title></title>
</head>
<body>
<%= VUE_APP_BODY_PREFIX %>
<div id="app"></div>
</body>
</html>