Flex Gap Polyfill
This is a pure CSS polyfill using PostCSS to emulate flex gap using margins.
Known limitations
- Must use a wrapper div when using
margin: auto
orbackground
. - Percentage gaps aren't reliable if the container is not full width of parent container
- Width of flex items with percentages vary slightly from spec because of negative margin on container.
View the demo page for various test cases of the polyfill in action.
Example
.container {
display: flex;
gap: 40px;
}
Becomes:
/* Output simplified for purpose of example */
.container > * {
--fgp-parent-gap-row: 40px;
--fgp-parent-gap-column: 40px;
--fgp-margin-top: calc(var(--fgp-gap-row) + var(--orig-margin-top, 0px));
--fgp-margin-left: calc(var(--fgp-gap-column) + var(--orig-margin-left, 0px));
margin-top: var(--fgp-margin-top);
margin-left: var(--fgp-margin-left);
}
.container {
--fgp-gap: var(--has-fgp, 40px);
--fgp-gap-row: 40px;
--fgp-gap-column: 40px;
--fgp-margin-top: calc(var(--fgp-parent-gap-row, 0px) - var(--fgp-gap-row) + var(--orig-margin-top, 0px));
--fgp-margin-left: calc(var(--fgp-parent-gap-column, 0px) - var(--fgp-gap-column) + var(--orig-margin-left, 0px));
display: flex;
gap: var(--fgp-gap, 0px);
margin-top: var(--fgp-margin-top, var(--orig-margin-top));
margin-left: var(--fgp-margin-left, var(--orig-margin-left));
}
The polyfill emulates flex gap by adding margins to each child element and applying a negative margin to the container.
- NEW Now works regardless of whether
display: flex
andgap
are used in the same rule (see Options for ways to optimise) - Works with unlimited nested elements with any combination of units, px > px, px > %, % > %, etc
- No additional class names or divs needed (except when using
margin: auto
orbackground
) - Works even when margin already exists on element (inline styles not supported)
- Style margin, borders and padding as normal
- Supports
gap
,row-gap
andcolumn-gap
Browser support
Supports all current modern browsers, Edge, Firefox, Chrome, Safari, Opera (any browser that supports calc()
and var()
).
Usage
Add Flex Gap Polyfill to your project:
npm install flex-gap-polyfill postcss --save-dev
Use Flex Gap Polyfill to process your CSS:
const flexGapPolyfill = require('flex-gap-polyfill');
flexGapPolyfill.process(YOUR_CSS /*, processOptions, pluginOptions */);
Or use it as a PostCSS plugin:
const postcss = require('postcss');
const flexGapPolyfill = require('flex-gap-polyfill');
postcss([
flexGapPolyfill(/* pluginOptions */)
]).process(YOUR_CSS /*, processOptions */);
Options
-
only
Type: Array Default: undefined
When
true
polyfill will only apply whendisplay: flex | inline-flex
andgap
are used in the same rule. Provide an array of selectors to match additional rules. Can bestrings
orregexes
. Inlcude/* apply fgp */
within a rule to manually apply the polyfill. -
flexGapNotSupported
Type: String Default: false
Manually specify a selector to use when flex gap is not supported by detection via JavaScript, eg
flexGapNotSupported: '.flex-gap-not-supported'
.
-
webComponents
Type: Boolean Default: false
When
true
polyfill will also target slotted elements