Skip to content

PostCSS plugin for creating fluid and responsive CSS values with granular breakpoint control using the flow() function

License

Notifications You must be signed in to change notification settings

soyleninjs/postcss-flow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PostCSS Flow

A PostCSS plugin for creating fluid and responsive CSS values with granular breakpoint control

npm version License: MIT PostCSS

FeaturesInstallationUsageExamplesContributing


What is PostCSS Flow?

PostCSS Flow is a powerful plugin that simplifies responsive design by transforming a simple flow() function into fluid CSS values with automatic media queries. Write responsive styles in a single line instead of managing multiple breakpoints manually.

Before (Traditional CSS)

.heading {
  font-size: clamp(20px, calc(20px + (30 - 20) * ((100vw - 834px) / 606)), 30px);
}
@media (width <= 834px) {
  .heading {
    font-size: clamp(10px, calc(10px + (20 - 10) * ((100vw - 360px) / 474)), 20px);
  }
}

After (With PostCSS Flow)

.heading {
  font-size: flow(10-360, 20-834, 30-1440);
}

Features

  • Fluid Values: Automatically generates clamp() functions with linear interpolation
  • Fixed Values: Define fixed breakpoints with the -0 suffix
  • Desktop First: Exclusive desktop-first approach with automatic breakpoint sorting
  • Auto-Sorting: Breakpoints are automatically ordered from largest to smallest viewport
  • Auto Media Queries: Generates necessary media queries using width <=
  • Simple Syntax: One line instead of multiple declarations and media queries
  • Zero Dependencies: Lightweight and efficient

Installation

Install via npm:

npm install @soyleninjs/postcss-flow --save-dev

Or using yarn:

yarn add @soyleninjs/postcss-flow --dev

Or using pnpm:

pnpm add @soyleninjs/postcss-flow --save-dev

Usage

1. Add to PostCSS Config

Add the plugin to your PostCSS configuration:

postcss.config.js (Array syntax)

module.exports = {
  plugins: [
    require('@soyleninjs/postcss-flow'),
    // other plugins...
  ]
}

postcss.config.js (Object syntax)

module.exports = {
  plugins: {
    '@soyleninjs/postcss-flow': {},
    // other plugins...
  }
}

2. Use in Your CSS

.element {
  property: flow(value1-viewport1, value2-viewport2, value3-viewport3);
}

3. Recommended: Combine with postcss-sort-media-queries

For optimal results, we recommend using PostCSS Flow together with postcss-sort-media-queries. This plugin will organize and merge all generated media queries, resulting in cleaner and more optimized CSS output.

Installation:

npm install postcss-sort-media-queries --save-dev

Configuration:

module.exports = {
  plugins: [
    require('@soyleninjs/postcss-flow'),
    require('postcss-sort-media-queries')({
      sort: 'desktop-first' // Matches PostCSS Flow's approach
    }),
    // other plugins...
  ]
}

Note: While not required, this combination significantly improves your final CSS structure by consolidating media queries and reducing duplication.


Syntax

Basic Syntax

flow(value-viewport[, value-viewport-isFluid]*)

Parameters

Each breakpoint is defined with the format:

Format Description
value-viewport Creates a fluid value between breakpoints
value-viewport-0 Creates a fixed (non-fluid) value at that breakpoint

Parameter details:

  • value: Numeric value (unitless, automatically converted to px)
  • viewport: Viewport width in pixels
  • isFluid (optional): Omit or use any value except 0 for fluid. Use 0 for fixed.

Desktop First Approach

The plugin works exclusively with a Desktop First approach, starting from the largest viewport and going down to smaller ones. Breakpoints are automatically sorted to ensure this behavior.

Important: The order you write breakpoints doesn't matter - they're automatically sorted from largest to smallest viewport!


Examples

Example 1: Basic Fluid Values

Transform a single line into fluid typography:

Input:

.heading {
  font-size: flow(10-360, 20-834, 30-1440);
}

Output:

.heading {
  font-size: clamp(20px, calc(20px + (30 - 20) * ((100vw - 834px) / 606)), 30px);
}
@media (width <= 834px) {
  .heading {
    font-size: clamp(10px, calc(10px + (20 - 10) * ((100vw - 360px) / 474)), 20px);
  }
}

What happens:

  • From 1440px and up: Fluid scaling from 20px to 30px
  • At 834px and below: Fluid scaling from 10px to 20px

Example 2: Combining Fluid and Fixed Values

Mix fluid and fixed breakpoints for precise control. Using -0 makes a breakpoint fixed (non-fluid) from that viewport down to the next breakpoint:

Input:

.container {
  padding: flow(10-360, 20-834-0, 30-1440);
}

Output:

.container {
  padding: clamp(20px, calc(20px + (30 - 20) * ((100vw - 834px) / 606)), 30px);
}
@media (width <= 360px) {
  .container {
    padding: 10px;
  }
}

What happens:

  • From 1440px down to 834px: Fluid scaling from 30px to 20px
  • At 834px (marked with -0): The value becomes fixed at 20px
  • From 834px down to 360px: Stays fixed at 20px (no fluid interpolation)
  • At 360px and below: Fixed 10px

The -0 suffix prevents fluid interpolation from that breakpoint downwards, creating a fixed value zone.


Example 3: Automatic Breakpoint Sorting

Don't worry about the order - write breakpoints in any order you want:

Input:

.text {
  font-size: flow(20-834, 10-360, 30-1440);
}

Output:

.text {
  font-size: clamp(20px, calc(20px + (30 - 20) * ((100vw - 834px) / 606)), 30px);
}
@media (width <= 834px) {
  .text {
    font-size: clamp(10px, calc(10px + (20 - 10) * ((100vw - 360px) / 474)), 20px);
  }
}

The plugin automatically sorts: 30-144020-83410-360


Example 4: Fluid Margins

Input:

.section {
  margin-bottom: flow(20-375, 40-768, 80-1920);
}

Output:

.section {
  margin-bottom: clamp(40px, calc(40px + (80 - 40) * ((100vw - 768px) / 1152)), 80px);
}
@media (width <= 768px) {
  .section {
    margin-bottom: clamp(20px, calc(20px + (40 - 20) * ((100vw - 375px) / 393)), 40px);
  }
}

Example 5: Multiple Properties

Use flow() on any CSS property that accepts pixel values:

Input:

.card {
  padding: flow(16-360, 24-768, 32-1440);
  gap: flow(8-360, 16-768, 24-1440);
  border-radius: flow(4-360, 8-768, 12-1440);
}

Each property gets its own fluid calculations and media queries!


Use Cases

Perfect for:

  • Fluid Typography: Scale font sizes smoothly across devices
  • Responsive Spacing: Padding, margins, and gaps that adapt naturally
  • Adaptive Layouts: Grid gaps, container widths, and more
  • Design Systems: Maintain consistent scaling across breakpoints
  • Performance: Uses native CSS clamp() for optimal rendering

Browser Compatibility

  • PostCSS: 8.0.0 or higher
  • Browsers: All modern browsers with clamp() support
    • Chrome 79+
    • Firefox 75+
    • Safari 13.1+
    • Edge 79+

For older browser support, consider using a CSS clamp() polyfill.


How It Works

  1. Parse: The plugin detects flow() functions in your CSS
  2. Sort: Breakpoints are automatically sorted from largest to smallest viewport
  3. Calculate: Linear interpolation formulas are generated for fluid values
  4. Generate: CSS clamp() functions and media queries are created
  5. Output: Clean, production-ready CSS

Contributing

Contributions are welcome! Here's how you can help:

Reporting Issues

Found a bug or have a feature request?

  1. Check existing issues
  2. Create a new issue with:
    • Clear description
    • Steps to reproduce (for bugs)
    • Expected vs actual behavior
    • Code examples

Pull Requests

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes
  4. Test thoroughly
  5. Commit: git commit -m 'Add amazing feature'
  6. Push: git push origin feature/amazing-feature
  7. Open a Pull Request

FAQ

Q: Can I use rem or em units? A: Currently, the plugin works with px values only. Unit conversion may be added in future versions.

Q: Does it work with CSS variables? A: The flow() function requires numeric values. CSS variables are not supported within the function.

Q: Can I use negative values? A: Yes! Negative values work perfectly for margins and transforms.

Q: Is there a maximum number of breakpoints? A: No hard limit, but 3-4 breakpoints is recommended for maintainability.


License

MIT License - see LICENSE file for details.


Author

Lenin


Acknowledgments

Inspired by the need for simpler responsive design workflows and the power of modern CSS functions.

If this plugin helps you, consider giving it a star on GitHub!


About

PostCSS plugin for creating fluid and responsive CSS values with granular breakpoint control using the flow() function

Resources

License

Stars

Watchers

Forks