# Block

A centred layout container that constrains its children to a chosen article column width, from narrower to fluid.

**Category:** Components/Page layout/Block

**Import:** `import { Block } from '@reuters-graphics/graphics-components'`

## Props

| Prop | Type | Default | Required | Description |
|------|------|---------|:--------:|-------------|
| `children` | `Snippet` | — | ✓ | Content that goes inside `<Block>` |
| `width` | `ContainerWidth` | `'normal'` |  | Width of the block within the article well. Options: `narrower`, `narrow`, `normal`, `wide`, `wider`, `widest`, `fluid` |
| `id` | `string` | `''` |  | Add an id to the block tag to target it with custom CSS. |
| `class` | `string` | `''` |  | Add custom classes to the block tag to target it with custom CSS. |
| `snap` | `boolean` | `false` |  | Snap block to column widths, rather than fluidly resizing them. |
| `role` | `string` | — |  | ARIA [role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles) for the block |
| `ariaLabel` | `string` | — |  | ARIA [label](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label) for the block |

## Examples

### Demo

```svelte
<Article id="block-demo-article">
  <div class="article-boundaries">
    <div class="label">Article</div>
    <Block>
      <div class="label">Block</div>
    </Block>
  </div>
</Article>
```

### Custom layout

```svelte
<Block width="fluid">
  <!-- Enter bootstrap grid! -->
  <div id="block-flex-example">
    <div class="row">
      <div class="col">Column</div>
      <div class="col-6">Column</div>
      <div class="col">Column</div>
    </div>
    <div class="row">
      <div class="col">Column</div>
      <div class="col">Column</div>
    </div>
  </div>
</Block>
```

### Snap widths

```svelte
<Article id="block-demo-article">
  <div class="article-boundaries">
    <div class="label">Article</div>
    <h4>snap widths</h4>
    <Block snap={true}>
      <div class="label">Block</div>
    </Block>
  </div>
</Article>
```

### Snap and skip widths

```svelte
<Article id="block-demo-article">
  <div class="article-boundaries">
    <div class="label">Article</div>
    <h4>Regular layout</h4>

    <Block width="narrower" snap={true} class="block-snap-widths-demo">
      narrower
    </Block>
    <Block width="narrow" snap={true} class="block-snap-widths-demo">
      narrow
    </Block>
    <Block width="normal" snap={true} class="block-snap-widths-demo">
      normal
    </Block>
    <Block width="wide" snap={true} class="block-snap-widths-demo">
      wide
    </Block>
    <Block width="wider" snap={true} class="block-snap-widths-demo">
      wider
    </Block>

    <h4>with snap and skip</h4>
    <Block width="narrower" snap={true} class="block-snap-widths-demo even">
      narrower
    </Block>
    <Block width="narrow" snap={true} class="block-snap-widths-demo even">
      narrow
    </Block>
    <Block
      width="normal"
      snap={true}
      class="block-snap-widths-demo even skip-narrow"
    >
      normal.skip-narrow
    </Block>
    <Block
      width="wide"
      snap={true}
      class="block-snap-widths-demo even skip-normal skip-narrow"
    >
      wide.skip-normal.skip-narrow
    </Block>
    <Block
      width="wider"
      snap={true}
      class="block-snap-widths-demo even skip-wide"
    >
      wider.skip-wide
    </Block>
  </div>
</Article>
```

## Documentation

# Block

The `Block` component is the basic building block of pages, a responsive container that wraps around each section of your piece.

Blocks are stacked vertically within the well created by the [Article](./?path=/docs/components-page-layout-article--docs) component. They can have different widths on larger screens depending on the `width` prop.

> 📌 Many of our other components already use the `Block` component internally. You'll usually only need to use it yourself if you're making something custom.

```svelte
<script>
  import { Block } from '@reuters-graphics/graphics-components';
</script>

<Block>
  <!-- Contents for this block goes here -->
</Block>
```

## Custom layouts

Our article well is designed to provide a basic responsive layout for you, but it also lets you customise.

The radical but easiest way to do this is to create a `Block` with a `fluid` width -- which basically cancels out the article well dimensions -- and then code whatever you need from scratch or with another framework.

The demo below does exactly that to create an edge-to-edge grid with [flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/).

```svelte
<Block width="fluid">
  <div class="my-radical-container">
    <!-- Now, you have full control over layout! -->
  </div>
</Block>
```

## Snap widths

Normally, `Block` containers resize fluidly below the original `width`. Sometimes, though, you may want the container to snap to the next breakpoint -- for example, if you have a static graphic that looks fine at the set block breakpoints, but isn't so great at widths inbetween.

You can use the `snap` prop to force the container to snap to each block width successively as the window sizes down.

```svelte
<Block width="wider" snap={true}>
  <!-- Contents for this block -->
</Block>
```

If you want to skip certain block widths entirely, you can add one or more class of `skip-{block width class}` to the `Block`.

> **NOTE:** The snap width breakpoints only work on `Block` components with widths `wider` and below. `widest` and `fluid` are both **always** fluid, since they go edge-to-edge.

```svelte
<!-- Will skip wide and go straight to normal column width on resize. -->
<Block width="wider" snap={true} class="skip-wide">
  <!-- Contents for this block -->
</Block>
```

This is probably easier to see in action than explain in words, so [resize the demo](./?path=/docs/components-page-layout-block--snap-skip-widths) to get a better picture of how it all works.

## Using with custom column widths

Snap width breakpoints are hard-coded to the default article well column widths, so if you set custom `columnWidths` on the [Article](./?path=/docs/components-page-layout-article--docs) component (**rare!**), you need to do a littie work to use this functionality.

Luckily, it's still pretty easy. Just add a `cls` or `id` to your `Block` so you can target it with some custom SCSS. Then define a few SCSS variables corresponding to your custom column widths, and use the `block-snap-widths` SCSS mixin to get the same functionality at your custom breakpoints.

```svelte
<Block width="wider" snap={true} class="custom-blocks">
  <!-- Contents for this block -->
</Block>

<style lang="scss">
  // Define custom column widths
  $column-width-narrower: 310px;
  $column-width-narrow: 450px;
  $column-width-normal: 600px;
  $column-width-wide: 860px;
  $column-width-wider: 1400px;

  @use '@reuters-graphics/graphics-components/scss/mixins' as mixins;

  :global {
    div.custom-blocks {
      @include mixins.block-snap-widths; // Use the `block-snap-widths` mixin
    }
  }
</style>
```
