---
title: "Small screens — Svelte"
description: "How the viewer adapts to a phone, a narrow column and a wide screen, and how to give each size a layout of its own."
integration: "Svelte"
source: "https://www.embedpdf.com/docs/viewer/svelte/customize/small-screens"
---

# Small screens

The viewer adapts to its own width, not the window's. On a phone, or in a narrow column of a wide
screen, it gets a phone's layout: panels and menus slide up from the bottom, and buttons that don't
fit move into the "More" menu. You don't set anything for this.

To change what happens at a size, use the second argument of the layout function:

```js
{
  layout: (layout, env) =>
    env.size === 'compact' ? layout.place('main', 'bottom') : layout,
}
```

On a phone, the main toolbar now sits at the bottom, under the thumb. The function runs again
whenever the size changes, so turning the phone or resizing the window switches layouts as it
happens.

Here the viewer sits in a box as wide as a phone, with that layout function, so it has a phone's
layout on any screen:

**`phone.svelte`**

```svelte
<script lang="ts">
  import { PDFViewer, type Layout, type LayoutEnv } from '@embedpdf/viewer-svelte';

  import './phone.css';

  const welcome = '/pdfs/welcome.pdf';

  const layout = (layout: Layout, env: LayoutEnv) =>
    env.size === 'compact' ? layout.place('main', 'bottom') : layout;
</script>

<div class="phone">
  <PDFViewer src={welcome} {layout} style="height: 100%" />
</div>
```

**`phone.css`**

```css
/* A box as wide as a phone: the viewer measures its own width, so it takes a phone's layout */
.phone {
  box-sizing: border-box;
  width: 375px;
  max-width: 100%;
  height: 100%;
  margin: 0 auto;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  overflow: hidden;
}
```

> **Try it:** open the search from the bar at the bottom: it slides up as a sheet. Search for
> "PDF" and pick a match: the sheet closes on its page. The mode tabs that don't fit are behind the
> chevron next to **View**.

## The three sizes

| `env.size`   | The viewer's width | What the default does                                                                                                                                 |
| :----------- | :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `'compact'`  | Under 600 px       | Panels and menus are sheets from the bottom. The mode tabs after the first fold behind a chevron, which is marked while the open mode is one of them. |
| `'medium'`   | 600 to 1023 px     | Panels open over the pages instead of pushing them aside.                                                                                             |
| `'expanded'` | 1024 px and wider  | Panels dock beside the pages.                                                                                                                         |

At every size, a toolbar keeps what fits and moves the rest into its "More" menu, least important
first (see [Layout](layout#when-theres-no-room)).

## One size at every width

The viewer picks its size from its width. `size` picks one for every width instead, as for a kiosk
on a big screen that should work like a phone:

```js
{
  size: 'compact',
}
```

`'auto'` (the default) measures. With a size set, `env.size` is that size, and `env.width` is still
the viewer's own width. It's read once, when the viewer starts.

## What `env` tells you

| Field   | What it is                                                                                                          |
| :------ | :------------------------------------------------------------------------------------------------------------------ |
| `size`  | `'compact'`, `'medium'` or `'expanded'`: from the viewer's width, or the [`size`](#one-size-at-every-width) you set |
| `width` | The viewer's width in px, for a size of your own: `env.width < 480`                                                 |
| `touch` | Whether the main way of pointing is a finger, or the [`touch`](#touch) you set                                      |
| `dir`   | `'ltr'` or `'rtl'`, from the user's language                                                                        |

## Sheets

A panel or a menu on a phone is a sheet: it slides up from the bottom of the viewer, over the
pages, with a handle at the top.

- Drag the handle to make it taller or shorter, or down to close it.
- A tap on the pages above it closes it.
- A sheet that holds a list, such as the thumbnails or the search results, closes when you pick
  something, so you see where it took you.

To make a panel a sheet at other sizes too, or never, set its `present`. With
`layout.panels({ present: { compact: 'overlay' } })` no panel is a sheet on a phone: each one
opens over the pages instead. See [Panels](panels#how-a-panel-opens). On a wider viewer, a sheet
is as wide as its panel, centered.

## Touch

When `env.touch` is true, every button and menu row is at least 44 px tall, the size a fingertip
hits, the rows of a panel show their menu button without a hover, and the viewer's own fields
write in 16 px text.
It's true when the main way of pointing is a finger. `touch` sets it instead: `true` for every
pointer, as on a touchscreen kiosk with a mouse plugged in, and `false` for none:

```js
{
  touch: true,
}
```

`'auto'` (the default) asks the browser. It's read once, when the viewer starts.

Touch gestures work wherever a finger touches the pages, whatever `touch` says: pinch to zoom, a
long press to select a word, the handles to stretch the selection.

## The notch and the home bar

When the viewer reaches the edge of the screen, as it does in full screen or as the whole page of
a phone app, its bars and sheets keep clear of the notch, the rounded corners and the home bar.

## Good to know

### Why the viewer's width, not the window's

A viewer in a sidebar or a dashboard card is small even on a big screen, and the layout that works
there is the phone's. Measuring the viewer itself gives every embed the right layout without media
queries.

### Change the sizes

To switch at other widths, decide on `env.width` yourself:

```js
{
  layout: (layout, env) =>
    env.width < 720 ? layout.place('main', 'bottom') : layout,
}
```
