---
title: "Feature"
description: "Put full-height media and a content column side by side in one band, mirrored or themed, stacking on phones."
requested_language: ar
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/ar/next/components/feature
version: unreleased (main)
docs_index: https://docs.systhema.app/ar/next/llms.txt
---
> This page isn't translated yet. Showing English.


`Feature` is a full-width band with media on one half and content on the other. The media runs edge to edge on its side, and the content column lines up with the page container on the other. Below the `md` breakpoint the two stack, media first.

```tsx preview iframe bleed height=520 title="Feature"
import {
  Button,
  Feature,
  FeatureContent,
  FeatureMedia,
  Heading,
  Image,
  Paragraph,
} from '@systhemaui/next'

export default function Demo() {
  return (
    <Feature layoutBackground="alternative">
      <FeatureMedia>
        <Image
          src="/demo-assets/workspace.webp"
          alt="A desk with a laptop and design sketches"
          width={1800}
          height={1200}
        />
      </FeatureMedia>
      <FeatureContent>
        <Paragraph type="label">Studio</Paragraph>
        <Heading.h2>Built around how you work</Heading.h2>
        <Paragraph>
          The media fills its half of the band at any height, and the content column aligns with the
          page container on the other side.
        </Paragraph>
        <Paragraph>
          <Button.a href="#" variant="primary">
            Meet the team
          </Button.a>
        </Paragraph>
      </FeatureContent>
    </Feature>
  )
}
```

## Import

```tsx
import { Feature, FeatureContent, FeatureMedia } from '@systhemaui/next'
```

In a React app without Next.js, import them from `@systhemaui/react`.

## Parts and tags

- `Feature`: the `<section class="feature">` band. It takes `theme`, `layoutBackground` and `reversed`.
- `FeatureMedia`: the media half, at least `--feature-media-min-height` tall (320px when the token is unset). Put an `Image`, `Video` or `MediaWrapper` inside it, or render the media element itself with a tag variant: `FeatureMedia.img`, `FeatureMedia.video`, `FeatureMedia.iframe` or `FeatureMedia.div`. `as` takes any other element.
- `FeatureContent`: the content half, a rich-text box (`feature-content richtext`). `FeatureContent.div` and `as` change its element.

Media inside `FeatureMedia` loses its border radius and shadow and is cropped with `object-fit: cover`, so it reads as part of the band.

## Examples

### Reversed

`reversed` puts the media on the right from `md` up. On a phone the media stays on top.

```tsx preview iframe bleed height=520 title="Reversed"
import { Feature, FeatureContent, FeatureMedia, Heading, Image, Paragraph } from '@systhemaui/next'

export default function Demo() {
  return (
    <Feature reversed>
      <FeatureMedia>
        <Image
          src="/demo-assets/forest-portrait.webp"
          alt="Sunlight through a pine forest"
          width={1200}
          height={1600}
        />
      </FeatureMedia>
      <FeatureContent>
        <Heading.h2>Media on the right</Heading.h2>
        <Paragraph>
          Alternate reversed and regular features down a page to give a long story some rhythm.
        </Paragraph>
      </FeatureContent>
    </Feature>
  )
}
```

### Theme

`theme` switches the band to another color-system mode, and `layoutBackground` picks the `main` or `alternative` background of that mode.

```tsx preview iframe bleed height=480 title="Dark feature"
import { Feature, FeatureContent, FeatureMedia, Heading, Paragraph } from '@systhemaui/next'

export default function Demo() {
  return (
    <Feature theme="dark" layoutBackground="main">
      <FeatureMedia.img src="/demo-assets/city.webp" alt="A city skyline at night" />
      <FeatureContent>
        <Heading.h2>After dark</Heading.h2>
        <Paragraph>
          theme="dark" sets data-theme on the band. Here the media is rendered as the img element
          itself with FeatureMedia.img.
        </Paragraph>
      </FeatureContent>
    </Feature>
  )
}
```

### Features in a row

Consecutive features inside an [`Article`](https://docs.systhema.app/ar/next/components/article.md) sit edge to edge: a feature is a `<section>`, and the article puts one section padding above and below a run of sections and none between them.

```tsx preview iframe bleed height=880 title="Alternating features"
import {
  Article,
  Feature,
  FeatureContent,
  FeatureMedia,
  Heading,
  Image,
  Paragraph,
} from '@systhemaui/next'

export default function Demo() {
  return (
    <Article>
      <Feature>
        <FeatureMedia>
          <Image src="/demo-assets/dunes-portrait.webp" alt="Sand dunes" width={1200} height={1600} />
        </FeatureMedia>
        <FeatureContent>
          <Heading.h3>Research</Heading.h3>
          <Paragraph>We start with the people who will use the site.</Paragraph>
        </FeatureContent>
      </Feature>
      <Feature reversed layoutBackground="alternative">
        <FeatureMedia>
          <Image
            src="/demo-assets/abstract-square.webp"
            alt="Abstract colored shapes"
            width={1200}
            height={1200}
          />
        </FeatureMedia>
        <FeatureContent>
          <Heading.h3>Design</Heading.h3>
          <Paragraph>Then we turn what we learned into a design system.</Paragraph>
        </FeatureContent>
      </Feature>
    </Article>
  )
}
```

## Props

### `Feature`

All other props go to the `<section>` element.

<!-- generated:props @systhemaui/react FeatureProps -->

| Prop                            | Type                                       | Default | Description |
| ------------------------------- | ------------------------------------------ | ------- | ----------- |
| `theme`                         | `ColorSystem` (`dark`, `default`)          | -       |             |
| `layoutBackground`              | `LayoutBackground` (`main`, `alternative`) | -       |             |
| `reversed`                      | `boolean`                                  | `false` |             |
| …and all `<section>` attributes |                                            |         |             |

<!-- /generated -->

### `FeatureMedia`

<!-- generated:props @systhemaui/react FeatureMediaProps -->

| Prop                        | Type          | Default | Description |
| --------------------------- | ------------- | ------- | ----------- |
| `as`                        | `ElementType` | `'div'` |             |
| `className`                 | `string`      | -       |             |
| …and all `<div>` attributes |               |         |             |

<!-- /generated -->

### `FeatureContent`

<!-- generated:props @systhemaui/react FeatureContentProps -->

| Prop                        | Type          | Default | Description |
| --------------------------- | ------------- | ------- | ----------- |
| `as`                        | `ElementType` | `'div'` |             |
| `className`                 | `string`      | -       |             |
| …and all `<div>` attributes |               |         |             |

<!-- /generated -->

## HTML and CSS

The same band in plain HTML:

```html
<section class="feature feature-reversed bg-layout-alternative" data-theme="dark">
  <img class="feature-media" src="/images/studio.webp" alt="Our studio" />
  <div class="feature-content richtext">
    <h2 class="color-heading text-h2">Built around how you work</h2>
    <p class="text-body color-body">Media on one half, content on the other.</p>
  </div>
</section>
```

The content padding comes from the `--feature-content-padding-side`, `--feature-content-padding-center` and `--feature-content-padding-y` tokens, and the media height from `--feature-media-min-height`:

<!-- generated:utilities feature -->

| Class              | Styles                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `feature`          | `& { width: 100%; display: flex; flex-direction: row; justify-content: flex-start; }`<br>`@media (width < 640px) { & { flex-direction: column; } }`<br>`@media (width >= 640px) { &.feature-reversed { flex-direction: row-reverse; } }`<br>`@media (width >= 640px) { &.feature-reversed .feature-content { margin-right: 0; margin-left: var(--container-margin); padding-left: var(--feature-content-padding-side); padding-right: var(--feature-content-padding-center); } }`                      |
| `feature-media`    | `& { flex-grow: 0; flex-shrink: 0; display: flex; width: 100%; min-height: var(--feature-media-min-height, 320px); }`<br>`@media (width >= 640px) { & { width: 50%; } }`<br>`&:is(img, svg, video, iframe, .media, .media-wrapper), .feature-media   > *:is(img, svg, video, iframe, .media, .media-wrapper) { height: unset; object-fit: cover; object-position: center; border-radius: 0; box-shadow: none; }`                                                                                       |
| `feature-content`  | `& { width: 100%; padding-left: var(--feature-content-padding-center); padding-right: var(--feature-content-padding-side); padding-block: var(--feature-content-padding-y, 48px); align-self: stretch; }`<br>`@media (max-width: 639px) { & { width: calc(100% - var(--container-margin) * 2); max-width: var(--container-width); margin-inline: auto; } }`<br>`@media (width >= 640px) { & { width: calc(var(--container-width) / 2); margin-right: var(--container-margin); align-self: center; } }` |
| `feature-reversed` | `@media (width >= 640px) { .feature.feature-reversed { flex-direction: row-reverse; } }`<br>`@media (width >= 640px) { .feature.feature-reversed .feature-content { margin-right: 0; margin-left: var(--container-margin); padding-left: var(--feature-content-padding-side); padding-right: var(--feature-content-padding-center); } }`                                                                                                                                                               |

<!-- /generated -->

## Next.js

`@systhemaui/next` re-exports `Feature`, `FeatureMedia` and `FeatureContent` from `@systhemaui/react` unchanged. Put the `@systhemaui/next` [`Image`](https://docs.systhema.app/ar/next/components/image.md) inside `FeatureMedia` to get `next/image` optimization; the tag variant `FeatureMedia.img` renders a plain `<img>`.

## Accessibility

The media comes first in the source and the content second, whichever side `reversed` shows them on, so screen readers always read media then text. Give informative images an `alt`; pass `alt=""` when the image only decorates the band.

## Related

- [Feature block](https://docs.systhema.app/ar/next/payload/blocks/feature.md)
- [Hero](https://docs.systhema.app/ar/next/components/hero.md)
- [Image](https://docs.systhema.app/ar/next/components/image.md)
- [Section](https://docs.systhema.app/ar/next/components/section.md)
