PHPackages                             bugo/flexgrid - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. bugo/flexgrid

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

bugo/flexgrid
=============

Fluent PHP builder for CSS Grid and Flexbox layouts

0.1(3mo ago)01MITPHPPHP ^8.2CI passing

Since Mar 12Pushed 3mo agoCompare

[ Source](https://github.com/dragomano/flexgrid)[ Packagist](https://packagist.org/packages/bugo/flexgrid)[ RSS](/packages/bugo-flexgrid/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (1)Dependencies (5)Versions (2)Used By (0)

FlexGrid PHP Builder
====================

[](#flexgrid-php-builder)

[![PHP](https://camo.githubusercontent.com/7bffcab80be9e1d83d7ec1e72f01342ea9ea17a26347f9b34a8d4a5ae8b58c48/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545382e322d626c75652e7376673f7374796c653d666c6174)](https://camo.githubusercontent.com/7bffcab80be9e1d83d7ec1e72f01342ea9ea17a26347f9b34a8d4a5ae8b58c48/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545382e322d626c75652e7376673f7374796c653d666c6174)[![Coverage Status](https://camo.githubusercontent.com/58850212053f5cc904e980439fc140db9eddd553ed6eb325ba438f32775ada32/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f647261676f6d616e6f2f666c6578677269642f62616467652e7376673f6272616e63683d6d61696e)](https://coveralls.io/github/dragomano/flexgrid?branch=main)

Fluent PHP library for generating CSS Grid and Flexbox layouts. Supports named areas, line-based placement, responsive breakpoints, and ready-made presets for common patterns.

---

Installation
------------

[](#installation)

```
composer require bugo/flexgrid
```

---

Quick start
-----------

[](#quick-start)

```
use FlexGrid\Grid;

echo Grid::columns(3, '.grid', '1.5rem')->build();
```

```
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}
```

---

GridBuilder
-----------

[](#gridbuilder)

`GridBuilder` is the main class. All methods return `static`, so they chain freely.

### Columns and rows

[](#columns-and-rows)

```
use FlexGrid\GridBuilder;
use FlexGrid\Enums\GridValue;

GridBuilder::make('.layout')
    ->columns('200px', '1fr', '200px')   // fixed values
    ->rows('64px', '1fr', '48px')        // row tracks
    ->gap('1rem')
    ->build();
```

Use `GridValue` helpers to avoid writing CSS strings by hand:

```
GridBuilder::make('.layout')
    ->columns(
        GridValue::fr(1),                          // "1fr"
        GridValue::minmax('200px', '1fr'),         // "minmax(200px, 1fr)"
        GridValue::repeat(3, GridValue::fr(1)),    // "repeat(3, 1fr)"
    )
    ->autoRows(GridValue::minmax('100px', 'auto')) // grid-auto-rows
    ->build();
```

Shorthand methods for repeated tracks:

```
GridBuilder::make('.grid')
    ->repeatColumns(4, '1fr')         // repeat(4, 1fr)
    ->repeatRows(3, '200px')          // repeat(3, 200px)
    ->autoFillColumns('250px')        // repeat(auto-fill, minmax(250px, 1fr))
    ->autoFitColumns('250px', '1fr')  // repeat(auto-fit,  minmax(250px, 1fr))
    ->build();
```

### Gap

[](#gap)

```
->gap('1rem')           // gap: 1rem  (both axes)
->gap('1rem', '2rem')   // gap: 1rem 2rem  (row, column)
->rowGap('1rem')        // row-gap only
->columnGap('2rem')     // column-gap only
```

### Named template areas

[](#named-template-areas)

Use `GridTemplate` to define the visual layout as an ASCII-art grid:

```
use FlexGrid\GridTemplate;

GridBuilder::make('.page')
    ->columns('220px', '1fr')
    ->rows('60px', '1fr', '40px')
    ->areas(GridTemplate::create()
        ->row(['header', 'header'])
        ->row(['nav',    'main'])
        ->row(['nav',    'footer']))
    ->build();
```

```
.page {
  display: grid;
  grid-template-columns: 220px 1fr;
  grid-template-rows: 60px 1fr 40px;
  grid-template-areas:
    "header header"
    "nav main"
    "nav footer";
}
```

For a more compact syntax, pass the area names as strings directly:

```
GridBuilder::make('.page')
    ->areaRows(
        'header header',
        'nav    main',
        'nav    footer',
    )
    ->build();
```

### Grid items (child elements)

[](#grid-items-child-elements)

Attach `GridItem` objects to the builder to generate child selectors alongside the container:

```
use FlexGrid\GridItem;
use FlexGrid\Enums\ItemAlignment;

GridBuilder::make('.page')
    ->columns('220px', '1fr')
    ->rows('60px', '1fr', '40px')
    ->areaRows('header header', 'nav main', 'nav footer')
    ->item(GridItem::select('.page__header')->namedArea('header'))
    ->item(GridItem::select('.page__nav')->namedArea('nav'))
    ->item(GridItem::select('.page__main')->namedArea('main'))
    ->item(
        GridItem::select('.page__aside')
            ->justifySelf(ItemAlignment::End)
            ->alignSelf(ItemAlignment::Start)
    )
    ->build();
```

```
.page {
  display: grid;
  grid-template-columns: 220px 1fr;
  grid-template-rows: 60px 1fr 40px;
  grid-template-areas:
    "header header"
    "nav main"
    "nav footer";
}

.page__header { grid-area: header; }
.page__nav    { grid-area: nav; }
.page__main   { grid-area: main; }
.page__aside  { justify-self: end; align-self: start; }
```

### Line-based placement

[](#line-based-placement)

When named areas are not used, place items by grid line numbers:

```
use FlexGrid\GridArea;

GridBuilder::make('.gallery')
    ->repeatColumns(4, '1fr')
    ->gap('1rem')
    ->item(
        GridItem::select('.gallery__hero')
            ->area(GridArea::at(1, 1)->spanRows(2)->spanColumns(2))
    )
    ->item(
        GridItem::select('.gallery__wide')
            ->area(GridArea::at(3, 1)->spanColumns(3))
    )
    ->item(
        GridItem::select('.gallery__tall')
            ->area(GridArea::at(1, 4)->rowEnd(4))
    )
    ->build();
```

```
.gallery { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }
.gallery__hero  { grid-row: 1 / span 2; grid-column: 1 / span 2; }
.gallery__wide  { grid-row: 3 / auto;   grid-column: 1 / span 3; }
.gallery__tall  { grid-row: 1 / 4;      grid-column: 4 / auto;   }
```

### Alignment

[](#alignment)

Grid alignment is split into two enums:

- `ItemAlignment`: `align-items`, `justify-items`, `align-self`, `justify-self`
- `ContentAlignment`: `align-content`, `justify-content`

```
use FlexGrid\Enums\ContentAlignment;
use FlexGrid\Enums\ItemAlignment;

GridBuilder::make('.grid')
    ->columns(GridValue::repeat(3, '200px'))
    ->placeItems(ItemAlignment::Center)                  // align-items + justify-items
    ->placeContent(ContentAlignment::Center)             // align-content + justify-content
    ->build();

// Or set each axis individually:
GridBuilder::make('.grid')
    ->alignItems(ItemAlignment::Start)
    ->justifyItems(ItemAlignment::End)
    ->alignContent(ContentAlignment::SpaceBetween)
    ->justifyContent(ContentAlignment::SpaceAround)
    ->build();
```

`ItemAlignment` cases: `Start`, `End`, `Center`, `Stretch`, `Baseline`.

`ContentAlignment` cases: `Start`, `End`, `Center`, `Stretch`, `SpaceBetween`, `SpaceAround`, `SpaceEvenly`.

Self-alignment on items:

```
GridItem::select('.box')
    ->placeSelf(ItemAlignment::Center)       // align-self + justify-self
    ->build();

GridItem::select('.box')
    ->alignSelf(ItemAlignment::Start)
    ->justifySelf(ItemAlignment::End)
    ->build();
```

### Auto flow and implicit tracks

[](#auto-flow-and-implicit-tracks)

```
GridBuilder::make('.masonry')
    ->autoFillColumns('220px')
    ->autoRows('10px')           // fine-grained implicit rows for JS masonry
    ->autoFlow('row dense')      // fill gaps greedily
    ->build();
```

### Responsive breakpoints

[](#responsive-breakpoints)

`responsive(int $minWidth, callable)` wraps a variant in `@media (min-width: вЂ¦)`. `media(string $query, callable)` accepts any media query string.

```
GridBuilder::make('.layout')
    ->columns('1fr')
    ->gap('1rem')
    ->responsive(640, fn(GridBuilder $g) =>
        $g->columns('1fr', '1fr')
    )
    ->responsive(1024, fn(GridBuilder $g) =>
        $g->columns('1fr', '1fr', '1fr')
          ->gap('2rem')
    )
    ->media('(prefers-reduced-motion: reduce)', fn(GridBuilder $g) =>
        $g->autoFlow('row')
    )
    ->build();
```

```
.layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 640px) {
  .layout { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 1024px) {
  .layout { grid-template-columns: 1fr 1fr 1fr; gap: 2rem; }
}

@media (prefers-reduced-motion: reduce) {
  .layout { grid-auto-flow: row; }
}
```

### Inline styles

[](#inline-styles)

`toInlineStyle()` returns a string suitable for the HTML `style` attribute вЂ” no selector, no braces:

```
$style = GridBuilder::make()
    ->columns('1fr', '2fr')
    ->gap('1rem')
    ->toInlineStyle();

// "display: grid; grid-template-columns: 1fr 2fr; gap: 1rem"
```

```
