PowerUp your CSS Mixins by writing them with Javascript

Scenario 1 — a basic button @mixin

@define-mixin button $bg, $color, $bgHover {
background: $bg;
border-color: $color;
color: $color;
&:hover, &:focus {
background: $bgHover;
}
}
.button {
/* all those boring common styles */
&-default {
@mixin button teal , white, tomato;
}
&-mono {
@mixin button white, gray, darkGray, white;
}
/* &-bring-the-gang {
you already lost count
} */
}
button(bg, color, bgHover) {
return {
background: bg,
color: color,
'&:hover, &:focus' {
background: bgHover,
}
};
}

Scenario 2— access an object

// ----- index.js ----- //const paddingSizes = {
sm: '0.2rem 0.5rem',
md: '0.5rem 1rem',
lg: '1rem 2rem',
}
padding(size) {
return {
padding: paddingSizes[size],
}
}
/* ----- index.css ----- */.item {
@mixin padding md; /* output -> padding: 0.5rem 1rem; */
}

Scenario 3— math

// ----- index.js ----- //fontSize(px) {
return {
'font-size': (px / 16) + 'rem',
}
}
/* ----- index.css ----- */.item {
@mixin fontSize 20; /* output -> font-size: 1.25rem; */
}

Extra Scenario 4 — media queries

// ----- index.js ----- //function fontSize(mixin, px) {
const pxNumb = px * 1 // Convert String to Number

return {
'font-size': (pxNumb / 16) + 'rem',
'@media (min-width: 60em)': {
// Increase font-size in 2px
'font-size': ((pxNumb + 2) / 16) + 'rem',
},
};
}
/* ----- index.css ----- */.item {
@mixin fontSize 16;
}
/* output:font-size: 1rem;@media (min-width: 60em) {
font-size: 1.125rem;
}
*/

Unit Testing

test('font-size render with 20px - 1.25rem', () => {
expect(mixins.fontSize(mock, '20')).toMatchSnapshot();
});
exports[`test font-size render with 20px - 1.25rem 1`] = `
Object {
"font-size": "1.25rem",
}
`;

Integration

const paddingSizes = {
sm: '0.2rem 0.5rem',
md: '0.5rem 1rem',
lg: '1rem 2rem',
}
const mixins = { // The first argument, mixin, is used to connect postCSS-mixins
button(mixin, bg, color, bgHover) {
return {
background: bg,
color: color,
'&:hover, &:focus': {
background: bgHover,
}
};
},
padding(mixin, size) {
return {
padding: paddingSizes[size],
}
},
fontSize(mixin, px) {
return {
'font-size': (px / 16) + 'rem',
}
}
};
module.exports = mixins;
const mixins = require('./src/styles/mixins/');module.exports = {
plugins: [
/* ... */
require('postcss-mixins')({
mixins: mixins,
}),
/* ... */
]
};
const mixins = require('./../src/styles/mixins');const mock = {
replaceWith: jest.fn(),
};
test('button default generates with correct styles', () => {
expect(mixins.button(mock, 'teal', 'white', 'tomato')).toMatchSnapshot();
});
test('padding generates with small size', () => {
expect(mixins.padding(mock, 'sm')).toMatchSnapshot();
});
test('font-size render with 20px - 1.25rem', () => {
expect(mixins.fontSize(mock, '20')).toMatchSnapshot();
});

--

--

--

I’m a Senior UX Frontend Engineer who helps to turn ideas into accessible experiences. I’m into React, Accessibility, and Design Systems.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Java Vs JavaScript

How to setup Webpack +2.0 from scratch in 2017 — Part III

Facebook Login IOS for React Native using Facebook SDK

What’s new in React Router V6

Numeric Separator in Javascript

Steps to create NPM Package and upload on NPM Server.

React Hooks tutorials for beginners-1

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Sandrina Pereira

Sandrina Pereira

I’m a Senior UX Frontend Engineer who helps to turn ideas into accessible experiences. I’m into React, Accessibility, and Design Systems.

More from Medium

What does a Front End developer do?

What does a Front End developer do

What is a Component in React JS?

Hoisting in javascript | Codementor

How to use Swiper.js in your project (for absolute beginners guide)