Skip to content
BetaDocs

Responsive settings and presentation

Part of the block reference. Changes by Core release are listed in Block changes by Core version.

Headings and prose already shrink fluidly on small screens — no per-page tuning needed. Beyond that, any field marked responsive accepts a per-breakpoint object. Put that object on the field inside block.data (data.cols, for example). The unrelated historical top-level shape block.responsive is not rendered and is rejected by whole-tree writes as well as block-instance tools.

The five breakpoints are Tailwind-compatible:

Token Min width Use
mobile 0 Baseline
tablet 640px Large phones, small tablets
laptop 1024px Landscape tablets, small laptops
desktop 1280px Desktop
wide 1536px Large screens

Mobile-first inheritance: missing breakpoints inherit upward from the previous defined one.

"Make the feature grid 1 column on mobile, 2 on tablet, 3 on desktop."
→ set_block_responsive block_id=<feature_grid_id> field=cols
value={mobile:1, tablet:2, desktop:3}

Block.hidden_on: ['mobile'] hides the entire block at a breakpoint — no BlockType opt-in needed.

These defaults are shared by Typeroll Cloud, self-hosted preview, and newly published static builds. Existing published sites change only after rebuilding. Explicit block settings and site CSS remain in place; remove temporary corrective CSS only after comparing preview with the intended design.

Default Phone Tablet (768px) Desktop (1280px)
H1 / H2 / H3 / H4 28 / 22 / 18 / 16px 32 / 24 / 20 / 17px 36 / 24 / 20 / 18px
Section vertical padding 48px 64px 80px
Gap between section blocks 24px 24px 32px
Card inset / grid gap 16px 24px 24px
Content gutter 20px 28px 28px

H5 and H6 use 16px and 14px at every width.

Values assume a 16px base font. Semantic headings use line heights 1.2 / 1.25 / 1.3 / 1.35; body uses 1.55. Explicit heading sizes such as article retain their own scale. Section padding_y: "auto" and grid/repeater gap: "auto" select the responsive defaults; fixed named sizes remain deliberate overrides.

Use core/section or core/hero as the top-level background carrier. Its background reaches the viewport edge; its inner content has gutters and a maximum width. Do not wrap these blocks in a padded main container. Adjacent sections receive no extra outer gap on top of their vertical padding. Nesting a section inside a constrained column deliberately constrains that section too.

Images use intrinsic height and contain by default. core/image and template/page_featured_image accept fit and aspect_ratio; core/post_card accepts image_fit and image_aspect, and core/media_card accepts image_fit. Choose a ratio plus cover only when cropping is intended. Hero full-image is an explicit background-cover layout; other hero layouts preserve the complete image. Test at 375, 768 and 1280px with the actual artwork.

Navigation uses the same CSS and JavaScript boundary: through 1023px it is a collapsible menu; from 1024px links appear inline. Without JavaScript, links remain reachable. Escape closes the mobile menu and returns focus to its button.

core/list.marker supports auto, none and check. Use none for a custom icon already in each row, or check for one native checkmark. Native checkbox inputs suppress the extra marker. Field-list item_html owns item decoration: Typeroll removes native bullets so a custom checkbox icon is not doubled.

Breadcrumbs have 0.75rem before and 2rem after; from 1024px they use 1rem and 2.5rem. They do not add an additional section-block gap below the trail. Override --breadcrumbs-before and --breadcrumbs-after without changing links or structured data.

The shared scale is --space-1 through --space-12 (4, 8, 12, 16, 24, 32, 40, 48, 64, 80, 96, 128px at a 16px root). Override semantic tokens instead of patching individual blocks: --section-padding, --block-gap, --block-gap-tight, --block-gap-loose, --grid-gap, --card-padding, --content-gutter, --type-h1 … --type-h6, --type-lead, and --body-leading. Theme fonts and colors remain independent.

:root {
--type-h2: 1.5rem;
--content-gutter: 1rem;
}
@media (min-width: 768px) {
:root {
--content-gutter: 1.5rem;
}
}
@media (min-width: 1280px) {
:root {
--content-gutter: 2rem;
}
}

Preview and static output load CSS in the same order: platform defaults and theme variables → block definitions and generated instance/responsive styles → site Custom CSS → Page Custom CSS. This is source order, not a replacement for the CSS cascade: specificity, inline declarations and !important still take precedence. Use block settings first, theme tokens for shared decisions, and scoped custom CSS for deliberate exceptions. Preview does not yet diagnose cascade conflicts.

Whole-tree writes assign missing, invalid or duplicate block IDs recursively, including children and slots. Malformed trees are rejected with a field path; they are never silently accepted or turned into empty content. IDs are assigned before storage, including editor working copies, API batch writes and MCP calls.

read_publishing_readiness also validates the saved, version-resolved content: invalid IDs, unsupported block types and missing referenced Page templates block publication with content_export_invalid and an editable resource path. Draft Pages and unsaved editor changes do not enter the public export. The same validation runs when freezing source and exporting content. It reads content and validates the export contract; it does not build the site or process images. Readiness is a preflight, not a guarantee that a later provider operation will succeed. Accepted jobs continue from their frozen source, not later edits.

Optional dimensions need no custom CSS. Use read_block_type to confirm that the connected runtime exposes these fields. Existing size presets remain the default. Numeric dimensions accept a number or a responsive object, for example font_size_px: { mobile: 30, laptop: 48 }. Breakpoints are mobile 0, tablet 640, laptop 1024, desktop 1280 and wide 1536 pixels. Values inherit from the previous breakpoint; dimensions are bounded by the field’s minimum and maximum.

Block Additional controls
Heading / Page title font_size_px, unitless line_height, color; semantic level stays independent
Section max_width_px for the inner content, content_gap_px, padding_x (auto, none, sm, md, lg)
Container max_width_px, gap_px, padding_x_px, padding_y_px, padding_top_px, padding_bottom_px; opt-in sticky and sticky_top_px
Two columns gap_px, right_width_px; optional stack_below selects the shared column/outline boundary
Site logo height_px, with intrinsic aspect ratio
Icon box icon_size_px, heading_size_px, min_height_px, padding_px, radius_px, background, shadow: subtle, whole_card_link
Table of contents padding_px, radius_px, border, shadow: subtle, link_color: neutral, list_style: chevron
Breadcrumbs padding_before_px, padding_after_px, divider

For an edge-to-edge composition use a top-level Container with width: full, padding_x_px: 0, padding_y_px: 0 and gap_px: 0. Sections keep backgrounds full width while max_width_px constrains their inner content. A 1140px inner area with a 280px right column and 60px gap leaves 800px for the article when space permits. Use smaller responsive gaps on narrow screens.

An Icon box with whole_card_link: true links its heading and stretches that single link over the card. Body links remain independently accessible. Supply a heading and link; an empty target never produces an empty anchor. In repeaters, map the heading and link from the referenced Page so navigation follows its route.

Image blocks now explicitly reset their own image margin and radius: none. Prose images retain their prose styles. Keep fit: contain and aspect_ratio: auto to show the complete image; a crop remains an explicit editorial choice.

Set settings.fonts.heading and/or settings.fonts.body to system for the visitor’s native system font stack, with no Google Fonts request for that family. This works identically in preview and static output. Other values remain Google Fonts family names. Check geometry and keyboard focus at each relevant breakpoint before publishing; precise dimensions cannot replace visual review.

Columns default to stack_below: "721" (the existing layout at 720px and below). Choose "768", "1024" or "1280" to stack below that viewport width. For example, "1024" gives a single column at 768 and 1023px, then two columns at 1024px. A Table of contents placed directly in a column slot follows this boundary: mobile_display: "hidden" hides the outline and its otherwise empty slot; "visible" keeps it in normal flow while stacked. Sticky behavior returns with the two-column layout. An empty generated outline never reserves a spare track or row; other sidebar blocks remain visible. Standalone outlines retain their 720px mobile behavior. Select the breakpoint from measured source/readability needs, not solely from whether the layout overflows.

Container padding_top_px and padding_bottom_px independently override padding_y_px (then the spacing token). All three accept breakpoint maps; zero is a real value. For example, a hero can use top padding { "mobile": 12, "tablet": 20, "laptop": 25 } and bottom padding { "mobile": 35, "tablet": 50, "laptop": 60 } without spacer blocks.

Grid, Repeater and its aliases accept gap_px (0–240, responsive). This overrides gap for that instance across grid, list, carousel and other repeater layouts. For example { "mobile": 15, "tablet": 20, "laptop": 25 } gives four 271.25px cards in a 1160px desktop well. Nested layouts use their own settings.

For a persistent site header, make the header partial’s outer Container a tag: "header" with sticky: true. It stays in normal document flow until it reaches sticky_top_px (default 0; optional responsive 0–240px) and uses stacking level 100. Choose an opaque background. Keep it outside the article/main and avoid a short enclosing wrapper or overflow-clipping ancestor: CSS sticky is bounded by its containing block. Other Containers remain static by default. A top-sticky or fixed site header reserves its own space: the page runtime measures the header’s bottom edge and sets html { scroll-padding-top } to it plus 16px, updating when the header changes height or the viewport crosses a breakpoint. Fragment links and :target, scrollIntoView() from blocks and Extensions, and focus() on form fields therefore land below the header, on the published site and in preview. Pages without a sticky header keep the browser default, and a site that sets its own scroll-padding-top keeps it. The outline uses the same landing line and adds only clearance the page has not already reserved. Remove tenant scroll-margin-top or scroll-padding-top offsets that duplicate this native clearance, rather than adding another compensation.

Button new_tab: true opens its link in a new tab using native HTML target="_blank" with rel="noopener noreferrer", even without JavaScript. Omitted or false keeps navigation in the same tab. Supply a JSON boolean, not a string. Keep the label meaningful; long labels wrap within the available width. During migration verify the rendered link’s query parameters, fragment and tab behavior. Source CTA classes copied into Prose do not recreate a Button. For affiliate or paid links set link_rel, a space-separated list such as nofollow sponsored, exactly as on image links; with new_tab: true the button renders rel="nofollow sponsored noopener noreferrer". Tokens other than plain names are ignored. A forced download is not supported; verify other link semantics in the selected block before converting it.

Use typed block fields before writing corrective CSS. These controls work in Page bodies, shared Page templates, partials and repeater item overrides.

  • core/prose: font_size_px, line_height, paragraph_spacing_px, text_align and font_weight support responsive values; font selects inherit, body or heading. For footer copy, use font_size_px: 14.4, line_height: 1.6, text_align: "center" and paragraph_spacing_px: 0 on ordinary prose.
  • core/container: min_height_px supports responsive minimum height. Content may grow beyond it; this never clips longer translations or zoomed text.
  • core/post_card: actions_direction, actions_gap_px, action_size_px, action_weight and body_gap_px control the action group and panel spacing. Keep the page and download destinations separate. whole_card_link is disabled when secondary actions are present.
  • For an image-free link card, set show_image: false, whole_card_link: true, title_icon: "arrow-right", and optionally title_icon_color, title_icon_size_px and title_icon_gap_px. The decorative icon stays inside the named title link; it does not add a second keyboard target.

Example Post Card data for a repeater with a public PDF field named pdf:

{
"layout": { "mobile": "column", "laptop": "row" },
"image_width_percent": 40,
"action_label": "Read",
"download_url_field": "pdf",
"download_style": "outline",
"actions_direction": { "mobile": "column", "laptop": "row" },
"actions_gap_px": 20,
"action_size_px": 14.4,
"body_gap_px": 20
}

Missing media is omitted. Action rows may wrap when space is limited. Cards retain their data order; these fields do not sort the listing. See site-specific widths for exact authored breakpoints. Existing sites must be republished to use the new renderer.

These controls require template capability version 0.48.0. Inspect read_block_type and site capabilities before writing them. Cloud and self-hosted installations use the same schema, renderer and editor controls.

Each core block can set a complete data.responsive_breakpoints map:

{
"responsive_breakpoints": {
"tablet": 577,
"laptop": 769,
"desktop": 1041,
"wide": 1440
}
}

This changes only that block’s responsive fields and hidden_on, never siblings or child blocks. A listing’s own map controls its grid; set the map in item_overrides to control its repeated cards independently. Four increasing integer widths between 320 and 2560 are required. Set the map to null to reuse the Site widths. The editor’s Block viewport widths section applies all four numbers together; Use Site widths resets them. The selected block’s device labels use its local widths. Explicit menu collapse and column stacking remain separate controls.

Cards with a fixed mobile image and a stretching desktop image

Section titled “Cards with a fixed mobile image and a stretching desktop image”

Example Post Card data for a listing with a pdf URL field:

{
"responsive_breakpoints": {
"tablet": 577,
"laptop": 769,
"desktop": 1041,
"wide": 1440
},
"appearance": "card",
"layout": { "mobile": "column", "desktop": "row" },
"image_width_percent": 40,
"image_sizing": { "mobile": "fixed", "desktop": "stretch" },
"image_height_px": 200,
"image_fit": "cover",
"border_width_px": 3,
"border_color": "#dddddd",
"radius_px": 6,
"body_padding_x_px": 16,
"body_padding_y_px": 12,
"action_label": "Read",
"action_size_px": 14,
"action_weight": "600",
"actions_direction": { "mobile": "column", "desktop": "row" },
"actions_align": "center",
"actions_gap_px": 20,
"download_url_field": "pdf",
"download_behavior": "download",
"download_style": "outline",
"download_width": { "mobile": "full", "desktop": "fill" },
"download_color": "#009d9d",
"download_border_width_px": 3,
"download_radius_px": 6,
"download_padding_x_px": 20,
"download_padding_y_px": 12,
"download_size_px": 13,
"download_weight": "700"
}

image_sizing: "auto" preserves a supplied pixel height, otherwise intrinsic height. intrinsic explicitly ignores pixel height; fixed uses it (200px fallback); stretch fills the media column to the card’s content height and is intended for row layouts. Combine stretch with an explicit image_fit: "cover" only when cropping is intended. Missing media creates no empty panel.

The title stays linked when action_label adds a separate action. Set title_link: false to opt out; this also disables the whole-card overlay. Secondary actions always disable that overlay. download_behavior: "navigate" is the default; download emits the native HTML download attribute. Browsers may navigate instead for cross-origin files, depending on the file server’s response. Typeroll does not proxy a file to force a download.

For a subtle link card, use background: "#f8f9fa", title_font: "body", body_padding_x_px: 16 and body_padding_y_px: 12. Keep show_image: false, whole_card_link: true and an optional title_icon for one named link.

core/columns.left_width_px: 150 reserves a 150px left track; the right track uses the remaining space. stack_below_px: 481 stacks through 480px and takes precedence over the preset stack_below. It accepts 320–1600px. Set only one fixed side; if both are supplied, left_width_px takes precedence. These fields do not change sibling columns or the Site’s responsive widths.

Wrap the icon, heading and link cards in core/container with radius_px: 6 and shadow: "subtle". A header can instead use shadow: "header". Container shadows default to none. From render version 9 a container with a shadow is raised above the blocks after it (z-index: 10; a sticky container keeps 100), so a hero or image section that follows no longer covers the shadow, and the header shadow is 0 2px 6px rgb(0 0 0 / 20%). No inline_style is needed. Its child icon panel can independently use min_height_px: { "mobile": 120, "tablet": 150 } with tablet starting at 481px. An image link remains a normal accessible link.

Navigation uses matching SVG open/close symbols. toggle_size_px controls the open symbol; close_size_px optionally overrides the close symbol while both retain their minimum 44px hit area. Existing modal focus, Escape and scrolling behavior is unchanged. Republish after upgrading to include the new static presentation; no customer content is rewritten by the upgrade.