---
title: Element parameters — Design
audience: content
source: us-core 8.45.2
generated: 2026-05-26 manual
---

<!--
  MANUAL FILE — edit directly.
  Source of truth for the Design parameter group. Not regenerated by
  scripts/llms/build.php — common-params.php skips this group because the
  central `css` parameter is a nested `design_options` config that needs
  prose explanation (encoding, whitelist, anti-patterns) rather than a flat
  param table.
  Underlying us-core config: plugins/us-core/config/elements_design_options.php
-->

# Element parameters — Design

> Per-element CSS, extra classes, IDs, custom HTML attributes, and visibility breakpoints. Available on virtually every us-core shortcode (`vc_row`, `vc_column`, `us_btn`, `us_text`, `us_iconbox`, `us_image`, …).

**Source**: [plugins/us-core/config/elements_design_options.php](../config/elements_design_options.php)

**Applies to**: most us-core shortcodes — every container plus most leaves. See per-shortcode entries in [shortcodes.md](shortcodes.md) for the few elements that opt out (e.g. some shortcodes that only emit markup with no styled container).

## Parameters at a glance

| Name | Type | Default | Show if | Purpose |
|------|------|---------|---------|---------|
| `css` | design_options | — | — | Per-element CSS overrides (color, sizes, paddings, borders, shadows, transforms, …) keyed by breakpoint. **The main Design param.** |
| `el_class` | text | — | — | Extra CSS class(es) added to the element's outer wrapper. |
| `el_id` | text | — | — | DOM `id` attribute on the element's outer wrapper. |
| `enable_custom_html_atts` | switch | `0` | — | Turn on the custom-HTML-attributes group below. |
| `custom_html_atts` | group | — | `enable_custom_html_atts="1"` | Extra HTML attributes (name/value pairs) merged into the element's main container — `data-*`, `aria-*`, schema.org microdata, etc. |
| `hide_on_states` | checkboxes | — | — | Hide the element on selected responsive states. Comma-separated list. |

The five rows above are the entire in-scope Design surface for shortcode authors. (Three more params — `hide_for_sticky`, `hide_for_not_sticky`, `hide_below`, `hide_above` — exist in the config but are scoped to the Header Builder and Grid Layout contexts respectively; they cannot be set via shortcode attributes.)

---

## `css="…"` — per-element CSS rules

The full encoding spec, JSON shape, allowed property whitelist, breakpoint keys, special cases (palette tokens, `background-image` media IDs, `font-family` typography roles), and anti-patterns live in [`composition-rules.md` §3.3](composition-rules.md#33-css--per-element-css-rules). Read it once — every shortcode example in this set follows the rules described there.

**TL;DR for quick reference:**

- The value is **URL-encoded JSON in double quotes**: `css="%7B%22default%22%3A%7B%22color%22%3A%22%23ff0000%22%7D%7D"`.
- Top-level keys are breakpoint slugs: `default` (≥1381px), `laptops` (1025-1380px), `tablets` (601-1024px), `mobiles` (≤600px).
- Within each breakpoint, keys are CSS property names in **kebab-case** (`font-size`, not `font_size`). Underscores are silently dropped.
- Only properties from the whitelist in `elements_design_options.php` `css.params` emit CSS — `display`, `gap`, `flex-direction` and friends are silently ignored. Restructure with the appropriate container shortcode instead.
- Single-quoted `css='{…}'` adds the unique class but **never emits the rule** (the post-save extractor regex only matches double quotes — `plugins/us-core/functions/post.php:320`). Always double-quote and URL-encode.

**Whitelisted property categories** (the full list is in [composition-rules.md §3.3](composition-rules.md#33-css--per-element-css-rules)):

- **Text** — `color`, `text-align`, `font-size`, `line-height`, `letter-spacing`, `font-family`, `font-weight`, `text-transform`, `text-wrap`, `font-style`.
- **Background** — `background-color`, `background-image`, `background-position`, `background-size`, `background-blend-mode`, `background-repeat`, `background-attachment`, `backdrop-filter`.
- **Sizes** — `width`, `height`, `max-width`, `max-height`, `min-width`, `min-height`, `aspect-ratio`.
- **Spacing** — `margin-top` / `margin-right` / `margin-bottom` / `margin-left` (and `padding-*` equivalents). Use the four sub-properties; the compiler auto-collapses to shorthand when all four are equal.
- **Border** — `border-radius`, `border-style`, `border-{top,right,bottom,left}-width`, `border-color`.
- **Position** — `position`, `top`, `right`, `bottom`, `left`, `z-index`.
- **Text Shadow** — `text-shadow-h-offset`, `text-shadow-v-offset`, `text-shadow-blur`, `text-shadow-color`.
- **Box Shadow** — `box-shadow-h-offset`, `box-shadow-v-offset`, `box-shadow-blur`, `box-shadow-spread`, `box-shadow-color`.
- **Overflow** — `overflow`, `clip-path`.
- **Transformation** — `transform`, `transform-origin`.
- **Animation** — `animation-name` (`fade`, `afc`/`afl`/`afr`/`afb`/`aft`, `hfc`, `wfc`, `bounce`), `animation-delay`.

---

## `el_class` — extra CSS class

Plain space-separated list of class names. Emitted on the element's outer wrapper alongside the theme's own classes.

```text
[us_btn label="Get started" link="url:%23pricing" el_class="cta-primary"]
```

**Useful when:**

- You need a JS hook (a class to query in custom script).
- You're styling via a child-theme stylesheet rather than `css="…"`. (Prefer `css="…"` for one-off styling; reach for `el_class` + child-theme CSS when the same rule has to apply across many pages.)
- You want to target the element from another element's `css="…"` selector (rare — most overrides should be on the element itself).

**Avoid:**

- Putting design rules inline via `el_class` to "save bytes" — `css="…"` is the framework's intended channel and integrates with responsive breakpoints, palette tokens, and the compiled-CSS cache.
- Class names that collide with the theme's own utility classes (`l-section-h`, `w-btn`, `usg_post_*`). The element's outer wrapper already carries those; duplicating them can produce unexpected cascade resolution.

---

## `el_id` — DOM id

Single identifier emitted as the element's `id` attribute. Used for in-page anchors and JS hooks.

```text
[vc_row el_id="pricing"]…[/vc_row]
[us_btn label="Pricing" link="url:%23pricing"]
```

**Useful when:**

- Linking to a section from another spot on the same page (the example above).
- Targeting one specific element from custom JS (`document.getElementById('pricing')`).
- Building a table-of-contents component that anchors to section headings.

**Avoid:**

- Reusing the same id on multiple elements. HTML allows only one element per id; duplicates break in-page anchor scrolling.
- Using ids that match the theme's own (`page`, `content`, `primary`) — same selector collision risk.

---

## `custom_html_atts` — custom HTML attributes

Activated by setting `enable_custom_html_atts="1"`. The value is a list of `{name, value}` pairs — same group-encoding pattern as `us_cform`'s `items` (URL-encoded JSON in double quotes, or single-quoted raw JSON when the content has no `+` characters).

**Shape** (one item per attribute):

```text
custom_html_atts='[{"name":"data-track","value":"hero-cta"},{"name":"aria-label","value":"Open the pricing modal"}]'
```

Or URL-encoded:

```text
custom_html_atts="%5B%7B%22name%22%3A%22data-track%22%2C%22value%22%3A%22hero-cta%22%7D%5D"
```

Each pair becomes a literal HTML attribute on the element's main container: `<a data-track="hero-cta" aria-label="Open the pricing modal" …>`.

**Useful for:**

- Analytics hooks — `data-track`, `data-event`, `data-category`.
- Accessibility — `aria-label`, `aria-describedby`, `role` (when the default role is wrong for the use-case).
- Microdata — `itemscope`, `itemtype`, `itemprop`.
- Lazy-load directives — `loading="eager"` on a critical image, `decoding="sync"`.
- Anti-spam markers — `rel="nofollow"` on outbound links inside `us_btn` / `vc_btn` (use `link`'s native `rel` field if available; this is a fallback).

**Anti-patterns:**

- Re-defining attributes the framework already manages — `id` (use `el_id`), `class` (use `el_class` or `css="…"`), `style` (use `css="…"`). The custom value will be appended but the framework's value usually wins on cascade.
- JSON booleans — `"value":true` is silently coerced; pass the string `"value":"1"` or the literal HTML form (`"value":""` for valueless attributes like `hidden` / `required` is fine — empty string emits `name=""`, which browsers still honour as "present").
- Forgetting to set `enable_custom_html_atts="1"` — the group is parsed but the attributes never reach the DOM.

---

## `hide_on_states` — hide on responsive breakpoints

Comma-separated list of breakpoint slugs at which the element should be hidden via CSS (`display: none` inside the corresponding media query).

**Allowed slugs:**

| Slug | Default range | Theme option |
|------|---------------|--------------|
| `default` | ≥ 1381 px (Desktops) | n/a — derived from `laptops_breakpoint + 1` |
| `laptops` | 1025-1380 px | Theme Options → `laptops_breakpoint` (default `1380`) |
| `tablets` | 601-1024 px | Theme Options → `tablets_breakpoint` (default `1024`) |
| `mobiles` | ≤ 600 px | Theme Options → `mobiles_breakpoint` (default `600`) |

**Format:** plain comma-separated string, no JSON.

```text
[us_image image="123" hide_on_states="mobiles"]
[us_btn label="Read more" link="url:%23more" hide_on_states="tablets,mobiles"]
[vc_row hide_on_states="default,laptops"]…[/vc_row]
```

**Useful for:**

- Hero illustrations that don't read on small screens — `hide_on_states="mobiles"`.
- Decorative side-rails / sticky widgets — `hide_on_states="tablets,mobiles"`.
- Mobile-only call-outs that should not show on desktop — `hide_on_states="default,laptops"`.

**Anti-patterns:**

- Using it for **content** that the visitor actually needs — hidden content still ships in HTML (extra weight, sometimes confusing for assistive tech). For "different content per breakpoint" build two separate elements and hide each on the opposite states, or use `css="…"` to restyle a single element.
- Hiding everything on `mobiles` and assuming the layout collapses gracefully — the row still emits empty spacing. Combine with `mobiles_columns="1"` on the parent row, or design a dedicated mobile variant.
- Trying to pass an array — the attribute is a flat string. `hide_on_states="['mobiles']"` is silently treated as a literal slug `['mobiles']` that doesn't match anything.

---

## Combined example

A two-column hero: full-bleed image on desktop / laptop, hidden on tablet / mobile (where the headline takes the full width), with a tracked CTA.

```text
[vc_row full_height="1" v_align="center"]
  [vc_column width="1/2" css="%7B%22mobiles%22%3A%7B%22padding-top%22%3A%2240px%22%7D%7D"]
    [us_text text="Headline" tag="h1" el_id="hero-headline"]
    [us_btn
      label="Start free trial"
      link="url:%2Fsignup"
      color_scheme="primary"
      enable_custom_html_atts="1"
      custom_html_atts='[{"name":"data-track","value":"hero-cta"}]'
    ]
  [/vc_column]
  [vc_column width="1/2" hide_on_states="tablets,mobiles"]
    [us_image image="123" css="%7B%22default%22%3A%7B%22border-radius%22%3A%2212px%22%7D%7D"]
  [/vc_column]
[/vc_row]
```
