@financial-times/o-grid

中文文档
6.1.9发布于 2026/02/26MITES Module零依赖近 30 天下载 1.9万

A 12 column responsive, flexbox-based grid system for laying out documents, templates and components.

原始使用文档
文档目录23 节
  1. Usage
  2. Quick Start
  3. Grid dimensions
  4. General settings
  5. Layout sizes
  6. Handover notes
  7. Markup
  8. Utility classes
  9. Responsive columns
  10. Examples
  11. Sass
  12. Options
  13. Advanced usage
  14. Utilities
  15. JavaScript Helpers
  16. getCurrentLayout()
  17. getCurrentGutter()
  18. getGridBreakpoints()
  19. enableLayoutChangeEvents()
  20. Grid Bookmarklet
  21. Migration
  22. Contact
  23. Licence

o-grid

A 12 column responsive, flexbox-based grid system for laying out documents, templates and components.

This component is a collection of Sass styles to build a 12 column grid system, with a few JavaScript helpers.

Our grid consists of:

  • 12 columns, of equal size.
  • 5 layouts (breakpoints) to support devices of various sizes.
  • Gutters of variable width, that adjust according to the current layout.
  • A maximum page width of 1220px, by default.

Grid system

Usage

Check out how to include Origami components in your project to get started with o-grid.

Quick Start

// your-app/main.scss
@import '@financial-times/o-grid/main';
@include oGrid();
// your-app/main.js

// Return the current layout (e.g. default, S, M, L, XL)
import oGrid from '@financial-times/o-grid';
let currentLayout = oGrid.getCurrentLayout();
console.log(currentLayout);

// Return the current gutter (e.g. 10px, 20px)
import oGrid from '@financial-times/o-grid';
let currentGutter = oGrid.getCurrentGutter();
console.log(currentGutter);

Grid dimensions

General settings

  • Minimum width: 240px
  • Maximum width: 1220px
  • Gutter widths (space between columns):
    • 10px on small screens
    • 20px on larger screens
  • Number of columns: 12

Layout sizes

  • Default 240px - …
  • Small (S) 490px - 739px
  • Medium (M) 740px - 979px
  • Large (L) 980px to 1219px
  • Extra large (XL) 1220px

Handover notes

Engineers may choose to use the o-grid Origami component to build a web based project to our grid, and respond to layout changes, but this may not be technically appropriate in every scenario particularly where it is appropriate to fallback to a simpler layout for older browsers.

It is important not to make assumptions about the devices our users are using or the most common screen-size, as these change. It is better to focus on the content of your design and adapt as needed when the space available to the design changes, rather than waiting to hit a specific breakpoint.

Markup

Utility classes

<div class="o-grid-container">
    <div class="o-grid-row">
        <!-- two divs, spanning a total of 12 columns -->
        <div data-o-grid-colspan="8">A div, 8 columns wide</div>
        <div data-o-grid-colspan="4">Another div, 4 columns wide</div>
    </div>
</div>

Responsive columns

Set a number of columns per layout:

<div class="o-grid-container">
    <div class="o-grid-row">
        <div data-o-grid-colspan="6 L8" class="first-column">
            Half by default, then 8 columns wide on Large layout and up
        </div>
        <div data-o-grid-colspan="6 L4" class="second-column">
            Half by default, then 4 columns wide on Large layout and up
        </div>
    </div>
</div>
div {
    @include oGridContainer();

    > div {
        @include oGridRow();
    }
}

.first-column {
    // Half by default, then 8 columns wide on Large layout and up
    @include oGridColspan((default: 6, L: 8));
}
.second-column {
    // Half by default, then 4 columns wide on Large layout and up
    @include oGridColspan((default: 6, L: 4));
}

Using numbers

  • {0-12} - number of columns to span by default
  • S{0-12} - number of columns to span at the small layout and up
  • M{0-12} - number of columns to span at the medium layout and up
  • L{0-12} - number of columns to span at the large layout and up
  • XL{0-12} - number of columns to span at the extra large layout and up
<div data-o-grid-colspan="6 L8"></div>
div { @include oGridColspan((default: 6, L: 8)); }

Using keywords

  • hide
  • one-half
  • one-third, two-thirds
  • one-quarter, three-quarters
<div data-o-grid-colspan="one-half Ltwo-thirds"></div>
div { @include oGridColspan((default: one-half, L: two-thirds)); }

Examples

A full width column for all sizes except large screens and up, where it spans on 9 columns:

<div data-o-grid-colspan="full-width L9"></div>
div { @include oGridColspan((default: full-width, L: 9)); }

A half width column that becomes full-width on medium screens and up:

<div data-o-grid-colspan="one-half M12"></div>
div { @include oGridColspan((default: one-half, M: 12)); }

A column which gradually takes up a greater portion of horizontal space as the screen gets smaller:

<div data-o-grid-colspan="4 M3 L2 XL1"></div>
div { @include oGridColspan((default: 4, M: 3, L: 2, XL: 1)); }

A column which has width: auto on small screens, and then takes half the available space on medium screens and up:

<div data-o-grid-colspan="M6"></div>
div { @include oGridColspan((M: 6)); }

Sass

To include all styles call the oGrid mixin.

@include oGrid();

Options

o-grid css may be included granularly by passing options to the oGrid mixin.

@include oGrid($opts: (
    'bleed': true,
    'shuffle-selectors': true,
    'friendly-selectors': true,
    'surface': ('current-layout', 'layout-sizes'),
    'rows': ('compact')
));

If you would not like to use o-grid markup at all, the styles for the surface option may be included independently to enable JavaScript features:

// Surface current breakpoint and gutter size information to JavaScript.
// Supports `getGridBreakpoints` and `enableLayoutChangeEvents`
// JavaScript methods.
@include oGridSurfaceLayoutSizes();

// Surface grid breakpoints to JavaScript.
// Supports the `getCurrentLayout` and `getCurrentGutter` JavaScript methods.
@include oGridSurfaceCurrentLayout();

Advanced usage

Utilities

Hiding elements

hide the column, show it again at Large (L) layout size, and hide it at the largest (XL) layout size:

<div data-o-grid-colspan="hide L12 XLhide"></div>
div { @include oGridColspan((default: hide, L: 12, XL: hide)); }

Centering a column

center the column and uncenter it at Large (L) layout size:

<div data-o-grid-colspan="center Luncenter"></div>
.my-column {
    @include oGridCenter;

    @include oGridRespondTo(L) {
        @include oGridUncenter;
    }
}

Push and pull columns

<div data-o-grid-colspan="8 push4"></div>
<div data-o-grid-colspan="4 pull8"></div>
// Content is first in the source
.content {
    @include oGridColspan(8);
    @include oGridPush(4); // outputs left: -33.333333333%;
}

// Sidebar comes second in the source but appears first on the left
.sidebar {
    @include oGridColspan(4);
    @include oGridPull(8); // outputs right: -66.666666667%;
}

Responsively:

<div data-o-grid-colspan="L8 Lpush4"></div>
<div data-o-grid-colspan="L4 Lpull8"></div>
// Content is first in the source
.content {
    @include oGridColspan((L: 8));
    @include oGridRespondTo(L) {
        @include oGridPush(4); // outputs left: -33.333333333%;
    }
}

// Sidebar comes second in the source but appears first on the left
.sidebar {
    @include oGridColspan((L: 4));
    @include oGridRespondTo(L) {
        @include oGridPull(8); // outputs right: -66.666666667%;
    }
}

Add space before a column

<div data-o-grid-colspan="8 offset4"></div>

<div data-o-grid-colspan="L8 Loffset4"></div>
div {
    @include oGridColspan(8);
    @include oGridOffset(4); // outputs margin-left: 33.333333333%;
}

div {
    @include oGridColspan((L: 8));

    @include oGridRespondTo(L) {
        @include oGridOffset(4); // outputs margin-left: 33.333333333%;
    }
}

Compact (gutterless) rows

To remove gutters from in between columns in a row, use the o-grid-row--compact class or the oGridRowCompact() mixin:

<div class="o-grid-row o-grid-row--compact">
    <div data-o-grid-colspan="6">Look 'ma, no gutters</div>
    <div data-o-grid-colspan="6">Look 'pa, no gutters here either</div>
</div>
div {
    @include oGridContainer();

    > div {
        @include oGridRow();
        @include oGridRowCompact('.column');
    }

    .column {
        @include oGridColspan((default: full-width, S: 3));
    }
}

Full bleed container

To remove gutters from the left and right sides of the grid container, use the o-grid-container--bleed class. Note that it is not possible to remove the outer gutters for an individual row, instead you need to start a new container.

<div class="o-grid-container o-grid-container--bleed">
    <div class="o-grid-row o-grid-row--compact">
        <div data-o-grid-colspan="6">Look 'ma, no gutters</div>
        <div data-o-grid-colspan="6">Look 'pa, no gutters here either</div>
    </div>
</div>

Responsive column helper

For simplicity, examples below don't show the output code that brings support for Internet Explorer.

Give column properties to an element
el { @include oGridColspan(); }

Outputs:

// Fallbacks for Internet Explorer omitted in this example
el {
    position: relative;
    float: left;
    box-sizing: border-box;
    flex: 1 1 0%;
    padding-left: 10px;
}
@media (min-width: 46.25em) {
    el {
        padding-left: 20px;
    }
}
Give a width to an element
el { @include oGridColspan($span: 4); }

Outputs:

el {
    position: relative;
    float: left;
    box-sizing: border-box;
    flex: 1 1 0%;
    padding-left: 10px;
    display: block;
    flex-basis: 33.33333%;
    min-width: 33.33333%;
    max-width: 33.33333%;
    width: 33.33333%;
}
@media (min-width: 46.25em) {
    el {
        padding-left: 20px;
    }
}
Responsive width for different layouts
el {
    @include oGridColspan((
        default: full-width,
        M: 6
    ));
}

Outputs:

el {
    position: relative;
    float: left;
    box-sizing: border-box;
    flex: 1 1 0%;
    padding-left: 10px;
    display: block;
    flex-basis: 100%;
    min-width: 100%;
    max-width: 100%;
    width: 100%;
}
@media (min-width: 46.25em) {
    el {
        display: block;
        flex-basis: 50%;
        min-width: 50%;
        max-width: 50%;
        padding-left: 20px;
    }
}

Responsive layout helper

@include oGridRespondTo($from, $until) {
    // Styles
}

To create styles that respond to the same breakpoints as the grid, this Sass mixin can be used to wrap the styles in the appropriate media query. It should be passed S, M, L or XL depending on which layout size the style should apply to e.g.

@include oGridRespondTo(S) {
    .o-example-module .item-subheading {
        font-size: 0.5em;
    }
}
.o-example-module .item-subheading {
    @include oGridRespondTo(XL) {
        color: red;
    }
}
.o-example-module .item-subheading {
    @include oGridRespondTo($until: L) {
        width: auto;
    }
}

It relies on Sass MQ to output mobile-first @media queries.

$from is inclusive but $until is exclusive – e.g. @include oGridRespondTo(S, L) matches the breakpoints S and M, but not L.

Gutters

el {
    margin-left: oGridGutter();

    @include oGridRespondTo(L) {
        margin-left: oGridGutter(L);
    }
}

Outputs:

el {
    margin-left: 10px;
}

@media (min-width: 61.25em) {
    el {
        margin-left: 20px;
    }
}

Unstyle a row or a column

.un-rowify {
    @include oGridResetRow;
}

.de-columnify {
    @include oGridResetColumn;
}

Variables

Some of the variables used by the grid (see _variables.scss) can be used to customise the grid system.

Here are the most useful ones:

// Show the currently active breakpoint and output loaded settings
$o-grid-debug-mode: true;

// Gutters (distance between 2 columns), in pixels
$o-grid-gutters: (default: 10px, M: 20px);

// Grid mode
// - fluid: full width up to the largest layout's width
// - snappy  fluid width until the layout defined in $o-grid-start-snappy-mode-at (default: M),
//           and then snaps into a larger fixed layout at each breakpoint
// - fixed: always fixed-width with the layout defined by
//          $o-grid-fixed-layout (default: L)
$o-grid-mode: fluid (default) | snappy | fixed;

// Default layouts
$o-grid-layouts: (
    S:  490px,
    M:  740px,
    L:  980px,
    XL: 1220px,
);

Adding a layout

Products who need to add other breakpoints/layouts should use the helper oGridAddLayout():

@import '@financial-times/o-grid/main';

// Add various layouts
@include oGridAddLayout(
    $layout-name: XS,
    $layout-width: 360px
);
@include oGridAddLayout(
    $layout-name: P,
    $layout-width: 600px,
    $gutter-width: 24px
);

// Layouts are now:
//   XS: 360px,
//   S: 490px,
//   P: 600px,
//   M: 740px,
//   L: 980px,
//   XL: 1220px

// Include all o-grid styles, including:
// - Surface the layout currently displayed to make it readable in JS
// - Generate grid helpers classes and data attributes.
@include oGrid();

Snappy mode

The container size can snap between fixed-widths as the viewport gets larger:

<!-- Make the whole document snappy -->
<body class="o-grid-snappy">
    <div class="o-grid-container">
        <div class="o-grid-row">
            …
        </div>
    </div>
</body>

<!-- Make a container snappy -->
<div class="o-grid-container o-grid-container--snappy">
    <div class="o-grid-row">
        …
    </div>
</div>

Debug mode

Enable debug mode to see the currently active breakpoint in the top-right corner of the page (based on sass-mq's show-breakpoints feature).

$o-grid-debug-mode: true;

show-breakpoints demo

JavaScript Helpers

getCurrentLayout()

Returns the name of the layout currently displayed.

import oGrid from '@financial-times/o-grid';

console.log(oGrid.getCurrentLayout());
// > default | S | M | L | XL

CSS must be included so JavaScript can retrieve layout information. If using Sass and the oGrid mixin, ensure the surface option includes current-layout; or include the oGridSurfaceCurrentLayout mixin if your project is not using any o-grid markup.

getCurrentGutter()

Returns the width of the gutter currently displayed.

import oGrid from '@financial-times/o-grid';

console.log(oGrid.getCurrentGutter());
// > 10px | 20px

CSS must be included so JavaScript can retrieve layout information. If using Sass and the oGrid mixin, ensure the surface option includes current-layout; or include the oGridSurfaceCurrentLayout mixin if your project is not using any o-grid markup.

getGridBreakpoints()

Returns the sizes of all grid breakpoints available.

import oGrid from '@financial-times/o-grid';

console.log(oGrid.getGridBreakpoints());
// > { "layouts": { "S": "490px", "M": "740px", "L": "980px", "XL": "1220px" } }

CSS must be included so JavaScript can retrieve layout information. If using Sass and the oGrid mixin, ensure the surface option includes layout-sizes; or include the oGridSurfaceLayoutSizes mixin if your project is not using any o-grid markup.

enableLayoutChangeEvents()

Enable matchMedia queries that fire an o-grid.layoutChange event upon layout change.

import oGrid from '@financial-times/o-grid';

oGrid.enableLayoutChangeEvents();

CSS must be included so JavaScript can retrieve layout information. If using Sass and the oGrid mixin, ensure the surface option includes layout-sizes; or include the oGridSurfaceLayoutSizes mixin if your project is not using any o-grid markup.

Grid Bookmarklet

  1. Create a new Bookmark with this URL:

    javascript:(function(){var s=document.createElement("script");s.src="https://unpkg.com/@financial-times/o-grid@^6.0.0/bookmarklet/bookmarklet.js";document.head.appendChild(s);}());
    
  2. Load a website

  3. Click the bookmarklet (the overlay should appear)

  4. Check the alignment of the layout on the grid

Migration

StateMajor VersionLast Minor ReleaseMigration guide
✨ activeo3N/Amigrate to o3
⚠ maintained6N/Amigrate to v5
╳ deprecated5N/Amigrate to v5
╳ deprecated44.5migrate to v4
╳ deprecated33.2-
╳ deprecated22.4-
╳ deprecated11.4-

Contact

If you have any questions or comments about this component, or need help using it, please either raise an issue, visit #origami-support or email Origami Support.


Licence

Copyright (c) 2016 Financial Times Ltd. All rights reserved.

This software is published under the MIT licence.

版本与发布记录

@financial-times/o-grid 共发布 40 个版本,首次发布于 2019/02/13;过去 12 个月发布了 1 个版本。

版本发布日期距今
6.1.9latest2026/02/268 个月前
6.1.82023/10/273 年前
6.1.72023/07/133 年前
6.1.62023/07/133 年前
6.1.52022/01/254 年前
6.1.42022/01/244 年前

其他发布通道:prerelease → 6.0.0-beta.0。

关于 @financial-times/o-grid 的常见问题

@financial-times/o-grid 是什么?

A 12 column responsive, flexbox-based grid system for laying out documents, templates and components.

如何安装 @financial-times/o-grid?

在项目目录运行 npm install @financial-times/o-grid,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@financial-times/math(^1.0.0)、@financial-times/sass-mq(^5.0.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@financial-times/o-grid 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/financial-times__o-grid 是否存在。

@financial-times/o-grid 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@financial-times/o-grid 可以商用吗?

@financial-times/o-grid 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@financial-times/o-grid 的下载量有多少?

根据 npm 官方下载统计,@financial-times/o-grid 在 2026/10/15 – 2026/11/13 这 30 天内被下载 18,583 次,日均约 619 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@financial-times/o-grid 还在维护吗?

最新版本 6.1.9 发布于 2026/02/26(8 个月前);至今共发布 40 个版本,其中过去 12 个月发布了 1 个;首次发布于 2019/02/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。