UNPKG

grid-rows-masonry

Version:

A ponyfill for CSS Grid masonry layout in plain JavaScript and React.

187 lines (126 loc) 8.19 kB
# Grid Rows Masonry _Use `grid-template-rows: masonry` today._ [![npm version](https://img.shields.io/npm/v/grid-rows-masonry)](https://www.npmjs.com/package/grid-rows-masonry) [![npm downloads](https://img.shields.io/npm/dw/grid-rows-masonry)](https://www.npmjs.com/package/grid-rows-masonry) [![License: ISC](https://img.shields.io/badge/license-ISC-informational)](./LICENSE) ![Tests](https://img.shields.io/github/actions/workflow/status/bartram/grid-rows-masonry/pr-check.yml) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![GitHub stars](https://img.shields.io/github/stars/bartram/grid-rows-masonry?style=social)](https://github.com/bartram/grid-rows-masonry/stargazers) `Grid Rows Masonry` is a **ponyfill** for the [CSS masonry layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Masonry_layout), to bring the feature to [browsers that don’t yet support it](https://caniuse.com/mdn-css_properties_grid-template-rows_masonry). It reflows items using a lightweight algorithm that respects your CSS Grid columns and gaps without absolute positioning and without changing the order of elements in the DOM. --- ## Why this over legacy “masonry” libs? - **Future-forward:** mirrors the emerging CSS masonry model; easy to retire when native support lands. - **Tiny & dependency-free:** zero deps, fast to initialize. - **Works anywhere:** vanilla JS or React. --- ## Quick start ### 1) Install #### npm ```bash npm install grid-rows-masonry ``` #### pnpm ```bash pnpm add grid-rows-masonry ``` #### yarn ```bash yarn add grid-rows-masonry ``` ### 2) Usage #### Vanilla JS ```html <div id="my-grid" style="display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: masonry; gap: 20px" > <!-- your variable-height items --> </div> <script type="module"> import { Masonry } from "grid-rows-masonry"; const el = document.getElementById("my-grid"); const masonry = new Masonry(el); // later, if you need to remove all modifications: // masonry.destroy(); </script> ``` #### React ```tsx import { Masonry } from "grid-rows-masonry/react"; export default function Gallery() { return ( <Masonry style={{ display: "grid", gap: 20, gridTemplateColumns: "repeat(3, 1fr)", gridTemplateRows: "masonry", }} > {/* children with variable heights */} </Masonry> ); } ``` --- ## Comparison | Package | Type | Key Features | Differentiators | | --------------------------------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | **Grid Rows Masonry** | Ponyfill (vanilla + React) | Simulates `grid-template-rows: masonry`; zero dependencies; lightweight; works with CSS Grid. | Future-forward CSS Grid approach; minimal overhead; no reliance on virtualization or CSS flexbox. | | **masonry-layout** | Vanilla JS library (Desandro) | Classic masonry layout; long-established; works with containers, item selectors. ([npm][1], [GitHub][2]) | Mature and popular, but heavyweight and reliance on manual initializations. | | **react-layout-masonry** | React component | Flexible & customizable; no dependencies; modern React-friendly API. ([npm][3]) | Built for React, but less focus on CSS Grid polyfill approach. | | **masonic** | React virtualized component | Virtualized rendering; high performance with large lists; hooks/utils exposed; supports TypeScript. ([npm][4], [GitHub][5]) | Best for massive item sets—adds complexity, dependencies, and virtualization. | | **react-responsive-masonry** | React, CSS Flexbox | Responsive columns and gutter breakpoints; lightweight and CSS-driven. ([npm][6]) | Pure flexbox; good for responsiveness but deviates from Grid spec and lacks ponyfill behavior. | | **react-masonry** | React component | Simple layout stacking by measuring and positioning elements; minimal React dependency. ([npm][7]) | Straightforward but lacks modern CSS features or Grid integration. | | **CSS Grid masonry polyfill** (`@prof-dev/masonry`) | Vanilla JS polyfill | Detects browser support for `grid-template-rows: masonry`, falls back to simulation; CSS Grid-based. ([GitHub][8]) | Similar concept, but does not reorder items. | | **react-plock** | React component | Ultra tiny (<1 kB gzipped), balanced layout, responsive, tree-shakeable. ([GitHub][9]) | Extremely lightweight and performance-oriented, but focuses on React only. | [1]: https://www.npmjs.com/package/masonry-layout "masonry-layout" [2]: https://github.com/desandro/masonry "desandro/masonry: :love_hotel: Cascading grid layout plugin" [3]: https://www.npmjs.com/package/react-layout-masonry "react-layout-masonry" [4]: https://www.npmjs.com/package/masonic "masonic" [5]: https://github.com/jaredLunde/masonic "jaredLunde/masonic: 🧱 High-performance masonry layouts ..." [6]: https://www.npmjs.com/package/react-responsive-masonry "react-responsive-masonry" [7]: https://www.npmjs.com/package/react-masonry "react-masonry" [8]: https://github.com/Profesor08/masonry "Profesor08/masonry: This library helps to make masonry grid layout using css grid" [9]: https://github.com/askides/react-plock "askides/react-plock: The 1kB Masonry Grid for React." --- ## Live demos - [**Vanilla CodeSandbox**](https://codesandbox.io/p/sandbox/grid-rows-masonry-vanilla-js-example-6kz8nw) - [**React CodeSandbox**](https://codesandbox.io/p/sandbox/grid-rows-masonry-react-example-r3sjf8) --- ## API ### `new Masonry(root: HTMLElement)` Initializes the ponyfill on a Grid container (`display: grid`) with 2+ columns. **Methods** - `destroy(): void` restores original DOM order / margins. --- ## Best practices - Define **columns & gaps in CSS**; the ponyfill only computes vertical placement. - No need to reinitialize when content changes–the library responds to mutations of the grid element, and updates the layout. --- ## Used by Are you using `grid-rows-masonry`? Open a PR to add your logo/link here! > Dependents list: <https://github.com/bartram/grid-rows-masonry/network/dependents> --- ## FAQ **Does this change DOM order?** No. It uses `grid-column-start` to change the column placement of elements to ensure the best fit, but DOM elements are never added or removed. **Will it conflict with native masonry later?** No. When native `grid-template-rows: masonry` is supported by the user's browser, it will feature-detect and skip initialization. --- ## Contributing Issues and PRs welcome! ### Visual regression tests Install the Chromium browser once: ```bash npx playwright install chromium ``` Then use the Storybook-backed visual regression commands: ```bash npm run test:visual npm run update:visual ``` `test:visual` rebuilds `storybook-static`, serves it locally, and compares each story snapshot against the checked-in Playwright baselines. `update:visual` refreshes those baselines when the visual change is intentional. --- ## License ISC © Bartram Nason