---
title: Element parameters — Design
audience: content
source: us-core 9.0
generated: 2026-06-12 manual
---

<!-- Manual file — not regenerated by scripts/llms/build.php (the `css` design_options param needs prose). -->

# 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`, …).

**Applies to**: most us-core shortcodes — every container plus most leaves. See the per-shortcode files under [shortcodes/](shortcodes/) (index at [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

Full spec — encoding, breakpoint keys, property whitelist, gradient channel (only `background-color` accepts `linear-gradient(…)`), single-quoted-JSON trap, palette tokens, `font-family` typography roles, anti-patterns — lives in [composition-rules.md §3.3](composition-rules.md#33-css--per-element-css-rules). It applies verbatim here.

Quick anchor: URL-encoded JSON in double quotes, keyed by breakpoint (`default` / `laptops` / `tablets` / `mobiles`), CSS property names in kebab-case, only whitelisted properties emit CSS. The animation enum on `animation-name` is: `fade`, `afc` / `afl` / `afr` / `afb` / `aft`, `hfc`, `wfc`, `bounce`.

---

## `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="%7B%22url%22%3A%22%23pricing%22%7D" 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="%7B%22url%22%3A%22%23pricing%22%7D"]
```

**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 — URL-encoded JSON in double quotes (same group-attribute encoding as `us_cform`'s `items`, see [composition-rules.md §3.5](composition-rules.md#35-group-json-attributes-items-orderby_items-responsive-tax_query-meta_query-)). Single-quoted raw JSON is mangled by `wptexturize` and the attribute silently fails — never use it.

**Shape** (one item per attribute):

```text
custom_html_atts="%5B%7B%22name%22%3A%22data-track%22%2C%22value%22%3A%22hero-cta%22%7D%2C%7B%22name%22%3A%22aria-label%22%2C%22value%22%3A%22Open%20the%20pricing%20modal%22%7D%5D"
```

decodes to:

```json
[{"name":"data-track","value":"hero-cta"},{"name":"aria-label","value":"Open the pricing modal"}]
```

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="%7B%22url%22%3A%22%23more%22%7D" 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="%7B%22url%22%3A%22%2Fsignup%22%7D"
      color_scheme="primary"
      enable_custom_html_atts="1"
      custom_html_atts="%5B%7B%22name%22%3A%22data-track%22%2C%22value%22%3A%22hero-cta%22%7D%5D"
    ]
  [/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]
```
