---
title: Writing HTML
description: How to write concise html markup in Jaspr.
---

---

With jaspr, you write html as part of your component tree. Each html tag (like `div`, `p`, `img`, etc.) has an assigned
method you can use (reps. `div()`, `p()`, `img()`, etc.).

Let's look at the following html snippet:

```html
<div>
  <h1>This is a title</h1>
  <p>Hello <b>World!</b></p>
</div>
```

Within a jaspr component, this can be represented as such:

```dart
div([
  h1([text('This is a title')]),
  p([text('Hello '), b([text('World!')])]),
]);
```

The special `text()` method does not add a html tag but renders plain text inside other elements.

## HTML utilities

There exist methods for the most common html tags, like `div`, `a`, `p`, `img` as well as more special tags like
`video`, `form`, `input` and others.

<Info>
If you want support for a tag that does not have such a method yet, please don't hesitate to open an issue on github.
</Info>

Each method has the following signature:

```dart
Component <tagname>(List<Component> children, {
  Key? key,
  String? id,
  String? classes,
  Styles? styles,
  Map<String, String>? attributes,
  Map<String, EventCallback>? events,
});
```

In addition to these parameters some methods have tag-specific attributes, like `img(src: "...")` or `a(href: "...")`.

For readability, it is recommended to put the list of child components last in the parameter list:
`div(id: "main", [text('Hello World')])` is more readable than `div([text('Hello World')], id: "main")`.
In case of no children specify an empty list (`[]`). Some tags also omit this parameter, like `img`.

[Try it out on JasprPad](https://jasprpad.schultek.de/?sample=html)

---

Finally, here are some more examples of this syntax. You can switch between the dart code and rendered html output.

<CodeGroup title="Paragraph with rich text">
  ```dart
    p([text('This is some '),b([text('html')]),text(' content.')])
  ```
  ```html
    <p>This is some <b>html</b> content.</p>
  ```
</CodeGroup>

<CodeGroup title="Heading with blue text">
    ```dart
    h1(styles: Styles.text(color: Colors.blue), [text('Hello Jaspr!')])
    ```
    ```html
    <h1 style="color: blue;">Hello Jaspr!</h1>
    ```
</CodeGroup>

<CodeGroup title="Anchor with an image">
  ```dart
    a(href: "https://github.com/schultek/jaspr", target: Target.blank, [
      img(src: "https://jasprpad.schultek.de/jaspr-192.png"),
    ])
  ```
  ```html
    <a href="https://github.com/schultek/jaspr" target="_blank">
      <img src="https://jasprpad.schultek.de/jaspr-192.png" />
    </a>
  ```
</CodeGroup>

<CodeGroup title="Select input">
  ```dart
    select([
      option(value: 'test', [text('Select me!')]),
      option(value: 'other', selected: true, [text('Or me!')])
    ])
  ```
  ```html
    <select>
      <option value="test">Select me!</option>
      <option value="other" selected>Or me!</option>
    </select>
  ```
</CodeGroup>

<CodeGroup title="Progress bar">
    ```dart
    progress(value: 85, max: 100, [])
    ```
    ```html
    <progress value="85" max="100"></progress>
    ```
</CodeGroup>

## Lower-Level Components

### DomComponent

Under the hood, every html element in jaspr is represented by a `DomComponent`, which is a special component that takes
a **tag**, some other parameters and a list of children, which can again be other `DomComponents`.

If you want to, you can write `DomComponent`s manually instead of using the utility methods. This gives you great low-level
control over your html structure, but is more verbose.

```dart
  var component = DomComponent(
    tag: 'div',
    id: 'my-id',
    classes: 'class-a class-b',
    styles: Styles.text(color: Colors.black),
    attributes: {'my-attribute': 'my-value'},
    events: {'click': (e) => print('clicked')},
    children: [
      /* ... */
    ],
  );
```

Using this component would render the following html:

```html
<div id="my-id" style="color: red" class="class-a class-b" my-attribute="my-value">
  ...
</div>
```

### Text

A simple component that renders a text node. The `text()` method simply returns a `Text` component.

A text node in html is just some standalone string that is placed inside another html element. Therefore the `Text`
component also only receives a single string to render to the page.

```dart
  var text = Text('Hello World!');
```

As usual for web, styling is done through a combination of CSS attributes, either in a **Stylesheet** or inline though
the **`styles` attribute** of the parent elements.

## Formatting Whitespace

When pre-rendering your components in **server** and **static** mode, Jaspr will output cleanly formatted html on a best-effort
basis. This means it will add newlines and indentations to your html element, while trying to not affect the way the html
is rendered.

For example lets look at this simple Jaspr code:

```dart
div([
  b([text('A')]),
  em([text('B')]),
  span([text('C')]),
])
```

Which will generate the following html:

```html
<div>
  <b>A</b>
  <em>B</em>
  <span>C</span>
</div>
```

Here Jaspr adds newlines and indentation for each child element. However in some cases, you might not want Jaspr
to introduce extra whitespace because it would affect the way the html is rendered.

If you don't want Jaspr to format the output html for a part of your code, wrap it in a `<span>` element. This works
since Jaspr will not apply and additional formatting to `<span>` elements.

So for example this code:

```dart
span([
  b([text('A')]),
  em([text('B')]),
  span([text('C')]),
]),
```

will generate to following html:

```html
<span><b>A</b><em>B</em><span>C</span></span>
```
