How to Build Responsive Layouts Using Ant Design's Grid System

Use Ant Design's Row and Col components with breakpoint-specific props (xs, sm, md, lg, xl, xxl) to create fluid, 12-column responsive layouts that adapt to any screen size.

The ant-design/ant-design repository provides a robust CSS-in-JS Grid system that eliminates the need for custom media queries. By leveraging the underlying responsive observer and flex-based architecture implemented in components/grid/row.tsx and components/grid/col.tsx, you can build complex, responsive interfaces using only React props.

Understanding the 12-Column Grid Foundation

Ant Design's Grid is built on a 12-column flexbox architecture where the viewport is divided into 12 equal-width columns. The system centers around two components:

  • Row – A flex container defined in components/grid/row.tsx that manages horizontal alignment, vertical alignment, and gutter spacing between columns.
  • Col – A flex item defined in components/grid/col.tsx that specifies how many of the 12 columns an element should occupy.

The Grid integrates with Ant Design's responsive observer (components/_util/responsiveObserver.ts), which monitors viewport changes and triggers re-renders when breakpoints are crossed.

Core Components and Source Implementation

Row Component (components/grid/row.tsx)

The Row component serves as the layout container. According to the source code, it accepts align and justify props that can be either static strings or responsive objects keyed by breakpoints. The component uses useMergedPropByScreen (lines 41-73) to determine the current effective value based on the active breakpoint.

Key Row props include:

  • gutter: Controls spacing between columns
  • align: Vertical alignment (top, middle, bottom, stretch)
  • justify: Horizontal distribution (start, end, center, space-around, space-between, space-evenly)
  • wrap: Whether flex items wrap to new lines

Col Component (components/grid/col.tsx)

The Col component implements the actual column sizing logic. It processes responsive breakpoint objects using responsiveArrayReversed to generate CSS class names like ant-col-md-8. The component also handles:

  • Span: Column width (1-12)
  • Offset: Left margin offset
  • Order: Visual reordering via flex order property
  • Flex: Flex-grow values or shorthand strings

The useGutter hook (imported from components/grid/hooks/useGutter.ts) normalizes gutter values and applies them as inline padding styles to each column.

Implementing Responsive Breakpoints

Ant Design defines six breakpoints that map to common device widths:

  • xs: < 576px (mobile phones)
  • sm: ≥ 576px (large phones)
  • md: ≥ 768px (tablets)
  • lg: ≥ 992px (desktops)
  • xl: ≥ 1200px (large desktops)
  • xxl: ≥ 1600px (extra large screens)

You can pass an object to any responsive prop to define different behaviors per breakpoint:

import { Row, Col } from 'antd';

const ResponsiveLayout = () => (
  <Row gutter={[16, 24]}>
    <Col xs={24} sm={12} md={8} lg={6} xl={4}>
      Adapts from full-width (mobile) to narrow (desktop)
    </Col>
    <Col xs={24} sm={12} md={8} lg={6} xl={4}>
      Second item with same responsive pattern
    </Col>
    <Col xs={24} sm={24} md={8} lg={12} xl={16}>
      Full width on mobile, expands on large screens
    </Col>
  </Row>
);

The responsiveArray defined in components/_util/responsiveObserver.ts determines the priority order for these breakpoints, ensuring that the most specific applicable breakpoint wins.

Controlling Spacing with Gutters

The gutter prop controls the gap between columns. According to components/grid/hooks/useGutter.ts, it accepts:

  • Number: Horizontal spacing in pixels
  • Array: [horizontal, vertical] spacing
  • Object: Breakpoint-specific spacing like { xs: 8, sm: 16, md: 24 }
import { Row, Col } from 'antd';

const GutterExamples = () => (
  <>
    {/* Uniform 16px gutter */}
    <Row gutter={16}>
      <Col span={12}>Content</Col>
      <Col span={12}>Content</Col>
    </Row>

    {/* Different horizontal and vertical gutters */}
    <Row gutter={[16, 24]}>
      <Col span={8}>Row 1, Col 1</Col>
      <Col span={8}>Row 1, Col 2</Col>
      <Col span={8}>Row 1, Col 3</Col>
      <Col span={8}>Row 2, Col 1</Col>
      <Col span={8}>Row 2, Col 2</Col>
      <Col span={8}>Row 2, Col 3</Col>
    </Row>

    {/* Responsive gutter */}
    <Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
      <Col span={6}>Responsive spacing</Col>
      <Col span={6}>Responsive spacing</Col>
      <Col span={6}>Responsive spacing</Col>
      <Col span={6}>Responsive spacing</Col>
    </Row>
  </>
);

The useGutter hook processes these values and applies them as paddingInline and paddingBlock styles to each column, creating the visual gap while maintaining the flex container's integrity.

Alignment, Justification, and Flex Control

Horizontal and Vertical Alignment

The Row component provides align (vertical) and justify (horizontal) props that map directly to CSS flexbox properties. As implemented in components/grid/row.tsx, these can be responsive objects:

import { Row, Col } from 'antd';

const AlignmentDemo = () => (
  <>
    {/* Center content vertically and horizontally */}
    <Row align="middle" justify="center" style={{ height: 200 }}>
      <Col span={12}>Perfectly centered content</Col>
    </Row>

    {/* Responsive alignment */}
    <Row 
      align={{ xs: 'top', md: 'middle', xl: 'bottom' }}
      justify={{ xs: 'center', md: 'space-between' }}
    >
      <Col span={6}>Item 1</Col>
      <Col span={6}>Item 2</Col>
      <Col span={6}>Item 3</Col>
    </Row>
  </>
);

Flex-Based Column Sizing

For more granular control, the Col component accepts a flex prop that supports CSS flex shorthand values. According to components/grid/col.tsx, the parseFlex function handles numeric values, 'auto', 'none', and complex flex strings:

import { Row, Col } from 'antd';

const FlexDemo = () => (
  <Row gutter={16} wrap={false}>
    <Col flex={2}>Takes 2/3 of remaining space</Col>
    <Col flex={1}>Takes 1/3 of remaining space</Col>
    <Col flex="0 0 200px">Fixed 200px width</Col>
    <Col flex="auto">Shrinks to fit content</Col>
  </Row>
);

Setting wrap={false} on the Row prevents columns from wrapping to new lines, creating a horizontal scroll or overflow scenario when combined with fixed-width flex columns.

Advanced Layout Techniques

Offset and Order

The Col component supports offset, order, pull, and push props for precise positioning. These map to CSS margin-left, order, right, and left properties respectively:

import { Row, Col } from 'antd';

const AdvancedPositioning = () => (
  <>
    {/* Offset creates empty space on the left */}
    <Row>
      <Col span={12} offset={6}>
        Centered 50% width column with 25% offset on each side
      </Col>
    </Row>

    {/* Reorder columns visually without changing DOM order */}
    <Row>
      <Col span={8} order={3}>
        This appears third (DOM order: 1)
      </Col>
      <Col span={8} order={1}>
        This appears first (DOM order: 2)
      </Col>
      <Col span={8} order={2}>
        This appears second (DOM order: 3)
      </Col>
    </Row>

    {/* Push and pull for source ordering (legacy but supported) */}
    <Row>
      <Col span={18} push={6}>
        Main content (visually on right)
      </Col>
      <Col span={6} pull={18}>
        Sidebar (visually on left)
      </Col>
    </Row>
  </>
);

The order property is particularly useful for accessibility, allowing you to maintain semantic DOM order for screen readers while presenting a different visual hierarchy to sighted users.

Summary

  • Ant Design's Grid system provides a 12-column flexbox-based layout engine through the Row and Col components, implemented in components/grid/row.tsx and components/grid/col.tsx.
  • Responsive breakpoints (xs, sm, md, lg, xl, xxl) allow columns to adapt their width, offset, and order across device sizes using the responsive observer in components/_util/responsiveObserver.ts.
  • Gutter control via the useGutter hook supports uniform, array-based, or responsive spacing between columns without manual CSS.
  • Flex alignment props (align, justify) on Row and the flex prop on Col provide fine-grained control over distribution and sizing using CSS flexbox.
  • Advanced positioning through offset, order, push, and pull props enables semantic source ordering and precise visual placement without altering DOM structure.

Frequently Asked Questions

How do I make a column take full width only on mobile devices?

Use the xs breakpoint prop set to 24 (full width) and specify smaller values for larger screens. Since Ant Design uses a 12-column system internally but accepts values up to 24 for convenience, setting xs={24} ensures the column spans 100% width on extra-small screens while sm={12} or md={8} would reduce the width on larger viewports.

<Col xs={24} md={12} lg={8}>
  Full width on mobile, half on tablet, one-third on desktop
</Col>

What is the difference between gutter as a number versus an array?

When gutter is a number (e.g., gutter={16}), the useGutter hook applies that value as horizontal padding only, resulting in uniform spacing between columns in a single row. When gutter is an array like gutter={[16, 24]}, the first value controls horizontal spacing (column gaps) and the second controls vertical spacing (row gaps when columns wrap), creating a two-dimensional grid gap system.

Can I use the Grid system without importing the entire Ant Design library?

Yes, Ant Design supports tree-shaking, so importing only the Grid components will not bundle the entire library. Import Row and Col directly from antd or from the specific component path if your build tool supports sub-path imports. The Grid components are self-contained and only depend on Ant Design's internal utility hooks (useBreakpoint, useGutter) and the responsive observer, not on other UI components like Buttons or Modals.

How does the order property affect accessibility?

The order property changes the visual presentation of columns using CSS flexbox's order property without modifying the DOM order. Screen readers and keyboard navigation follow the DOM order (source order), while sighted users see the reordered layout. This allows you to place important content first in the DOM for accessibility (e.g., main content before sidebar) while visually displaying the sidebar on the left and content on the right using order props, improving both SEO and screen reader experience.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →