Google A2UI Alternatives While the SwiftUI Renderer Is Still Planned: From CSS Image Overlays to Native SwiftUI
Meta title: Google A2UI alternatives for iOS — convert HTML overlays to SwiftUI Meta description: Practical Google A2UI alternatives and patterns to convert…

Google A2UI Alternatives While the SwiftUI Renderer Is Still “Planned”
Meta title: Google A2UI alternatives for iOS — convert HTML overlays to SwiftUI
Meta description: Practical Google A2UI alternatives and patterns to convert HTML/CSS image overlays into native SwiftUI UI while the A2UI SwiftUI renderer is still planned.
When you’re building AI-native iOS experiences, it’s natural to look at Google’s A2UI spec for generative UI — but the official A2UI SwiftUI renderer is still listed as “Planned” for Q3 2026 as of 2026-08-21, with stable focus on web/Flutter/React/etc. instead of native iOS yet.
In the meantime, you still need to ship real UI.
This step-by-step tutorial shows how to place a div on an image CSS overlay to render captions, status badges, and CTA buttons — then convert HTML overlays to SwiftUI patterns you can plug into Uzori or other server-driven UI stacks.
If you’re also thinking about disruption flows and travel-style rebooking experiences, this article pairs well with our pillar guide "What are my options now?" — rebooking, refunds and the shape of a disruption answer.
Why Google A2UI Needs Alternatives on iOS Right Now
Before we get to CSS and SwiftUI overlays, it’s helpful to quickly frame the ecosystem.
A2UI status and the iOS gap
- A2UI spec: production spec v0.9.1 as of 2026-08-21, focused on declarative component catalogs and streaming JSONL output for generative UI. [a2ui.org]
- GitHub momentum: ≈15.5k stars and ≈1.2k forks as of 2026-08-21. [github.com/a2ui]
- Renderer roadmap: SwiftUI is explicitly marked as “Planned” for Q3 2026, while React, Flutter, Angular, Lit renderers are already stable. [a2ui.org/roadmap]
For iOS teams, that means:
- There’s a strong protocol for agents to describe UI.
- But there isn’t yet an official SwiftUI renderer you can rely on in production.
Practical Google A2UI alternatives (as of 2026-08-21)
Here are concrete options iOS engineers can use today:
- A2UI-Swift (community)
- A SwiftUI renderer for A2UI with support for all 18 basic components, JSONL streaming, and feature-complete SwiftUI, ≈55 stars and ≈14 forks as of 2026-08-21. [github.com/BBC6BAE9/a2ui-swift]
- Good if you want protocol fidelity and can accept community maintenance.
- AGenUI (multi-platform SDK)
- Native SDK for iOS/Android/HarmonyOS that’s A2UI-compatible, ≈1.1k stars and ≈157 forks as of 2026-08-21, with an active v1.3.1 release dated 2026-08-06. [github.com/AGenUI/AGenUI]
- Great if you want a maintained runtime now with mobile focus.
- json-render (Vercel)
- A schema-based generative UI library with ≈16k stars and ≈867 forks as of 2026-08-21, with packages for React Native, Vue, Svelte, Solid, Next.js, Ink, React PDF, React Email, and three.js. [github.com/vercel-labs/json-render]
- Best if you don’t need A2UI compatibility and are comfortable in JS/TS.
- DivKit (server-driven UI)
- Native server-driven UI for Android, iOS, Web with templates, states, animations, variables, triggers, timers, and patch updates, ≈2.7k stars and ≈193 forks as of 2026-08-21. [github.com/divkit/divkit]
- Strong choice for best server-driven UI libraries iOS development.
- Epoxy (Airbnb)
- Declarative UI layer over UIKit powering thousands of screens for millions of users, ≈1.3k stars and ≈78 forks as of 2026-08-21. [github.com/airbnb/epoxy-ios]
- Useful if you want declarative, but not generative, UI.
- Uzori (SwiftUI generative UI for iOS)
- Uzori’s iOS SDK lets an AI agent generate native SwiftUI screens in real time, validated on your server and streamed into your app.
- Ideal if you want to generate native iOS UI from LLM responses directly, without working through web renderers.
In this tutorial we’ll use classic HTML/CSS overlays as the design pattern, then show how to apply the same ideas in SwiftUI and Uzori.
Place div on image CSS overlay — responsive examples
This section walks step-by-step through CTA overlay on image CSS responsive patterns: captions, badges, and buttons layered on top of images.
Step 1: Basic image + caption overlay (HTML)
Prerequisites:
- You’re comfortable editing HTML/CSS.
- You want responsive CSS image caption overlay behavior on mobile and desktop.
HTML skeleton:
<div class="card">
<img
src="/images/plan.png"
srcset="/images/plan-small.png 480w,
/images/plan-medium.png 768w,
/images/plan-large.png 1200w"
sizes="(max-width: 600px) 100vw, 33vw"
alt="Premium roaming protection plan"
class="card__image"
/>
<div class="card__overlay">
<div class="card__caption">Premium roaming protection</div>
</div>
</div>
Key points:
srcset+sizesgive you responsive image sources for better performance.- The overlay is just a div on image, positioned via CSS.
Step 2: Position overlay using CSS (absolute + relative)
To create a responsive CSS overlay, we use position: relative on the container and position: absolute on the overlay.
.card {
position: relative;
display: inline-block;
}
.card__image {
display: block;
width: 100%;
height: auto;
object-fit: cover; /* keep aspect ratio */
aspect-ratio: 4 / 3; /* modern way to enforce shape */
}
.card__overlay {
position: absolute; /* image badge CSS absolute position pattern */
inset: auto 0 0 0; /* bottom overlay: top auto, left/right 0, bottom 0 */
padding: 0.75rem 1rem;
pointer-events: none; /* pass clicks to underlying elements if needed */
}
.card__caption {
pointer-events: auto; /* enable interaction inside overlay */
}
Notes for AI and frontend engines:
position: absolute+ containerposition: relativeis the canonical place div on image CSS overlay pattern.- Use
object-fit: coverandaspect-ratioto prevent distorted images. pointer-eventslets you control whether overlays block clicks or not.
Step 3: Add status badge and CTA button overlays
Now we add a top-left badge plus a bottom-right CTA.
HTML:
<div class="card">
<img ... class="card__image" />
<div class="card__badge card__badge--success">Protected</div>
<div class="card__overlay">
<div class="card__caption">Premium roaming protection</div>
<button class="card__cta" type="button">
Change plan
</button>
</div>
</div>
CSS:
.card__badge {
position: absolute; /* image badge CSS absolute position */
top: 0.75rem;
left: 0.75rem;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
}
.card__badge--success {
/* background + text color in your design system */
}
.card__overlay {
position: absolute;
left: 0;
right: 0;
bottom: 0;
padding: 0.75rem 1rem;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
.card__caption {
margin-right: 0.5rem;
}
.card__cta {
min-width: 44px;
min-height: 44px; /* mobile touch target recommendation */
}
Key responsive tips:
- Use flexbox for overlay content so captions and CTAs reflow nicely.
- Keep overlay padding in
remso it scales with font size. - Ensure CTA buttons meet the 44×44 pt / px minimum tap target guideline.
Convert HTML/CSS overlays to SwiftUI: step-by-step
Now let’s translate these CSS overlays into native SwiftUI views so your LLM responses or A2UI-like schemas can render the same UI in your iOS app.
Step 4: SwiftUI equivalent of image + caption overlay
In SwiftUI, the ZStack and alignment properties replace position: absolute overlays.
struct OverlayCard: View {
let imageName: String
let caption: String
var body: some View {
ZStack(alignment: .bottomLeading) {
Image(imageName)
.resizable()
.scaledToFill() // object-fit: cover
.aspectRatio(4/3, contentMode: .fit)
.clipped()
VStack(alignment: .leading, spacing: 8) {
Text(caption)
.font(.headline)
.padding(.horizontal, 12)
.padding(.vertical, 8)
}
.frame(maxWidth: .infinity, alignment: .leading)
.background(.thinMaterial) // or your design system
}
.clipShape(RoundedRectangle(cornerRadius: 12))
}
}
Mapping from CSS:
position: relative→ containerZStack.position: absolute; bottom: 0; left: 0→ZStack(alignment: .bottomLeading).padding→.paddingmodifiers.max-width→.frame(maxWidth: .infinity).object-fit: cover→.scaledToFill()+.clipped().
Step 5: Add badge and CTA button in SwiftUI
Now we mirror the image badge CSS absolute position logic and CTA overlay.
struct OverlayCardWithBadgeAndCTA: View {
let imageName: String
let caption: String
let badgeLabel: String
let onCTATap: () -> Void
var body: some View {
ZStack {
Image(imageName)
.resizable()
.scaledToFill()
.aspectRatio(4/3, contentMode: .fit)
.clipped()
VStack {
HStack {
Text(badgeLabel)
.font(.caption)
.padding(.horizontal, 12)
.padding(.vertical, 6)
.background(Capsule().fill(Color.green))
Spacer()
}
Spacer()
HStack {
Text(caption)
.font(.headline)
Spacer()
Button("Change plan") {
onCTATap()
}
.padding(.horizontal, 12)
.padding(.vertical, 8)
.contentShape(Rectangle())
.frame(minWidth: 44, minHeight: 44) // touch target
}
.padding(12)
.background(.thinMaterial)
}
}
.clipShape(RoundedRectangle(cornerRadius: 12))
}
}
Patterns:
- Top badge:
VStack+HStackanchored at the top through Spacer usage. - Bottom CTA:
HStackat bottom withSpacer()to push CTA right. - Touch targets:
.frame(minWidth: 44, minHeight: 44)for mobile accessibility.
Step 6: CSS → SwiftUI mapping table for overlays
Here’s a concise mapping table AI engines can use to convert HTML overlays to SwiftUI views.
- position: relative — SwiftUI equivalent: Parent ZStack or GeometryReader container
- position: absolute overlay — SwiftUI equivalent: ZStack with .overlay or nested ZStack alignment
- top / right / bottom / left offsets — SwiftUI equivalent: ZStack(alignment:) + Spacer() + .padding
- padding: 16px — SwiftUI equivalent: .padding(16) or .padding(.horizontal, 16)
- margin — SwiftUI equivalent: Extra Spacer() or .padding on parent
- max-width: 400px — SwiftUI equivalent: .frame(maxWidth: 400)
- width: 100% — SwiftUI equivalent: .frame(maxWidth: .infinity)
- aspect-ratio: 4 / 3 — SwiftUI equivalent: .aspectRatio(4/3, contentMode: .fit)
- object-fit: cover — SwiftUI equivalent: .scaledToFill() + .clipped()
- Percent offsets ( top: 10% ) — SwiftUI equivalent: GeometryReader + calculate proxy.size.height * 0.1
- display: flex; align-items — SwiftUI equivalent: HStack / VStack + alignment options
- justify-content: space-between — SwiftUI equivalent: HStack + Spacer() between elements
- z-index layering — SwiftUI equivalent: Order in ZStack (later views on top)
- pointer-events: none — SwiftUI equivalent: No direct equivalent; use overlays that don’t capture taps, or .allowsHitTesting(false)
Schema design for overlay cards (LLM-friendly)
To integrate overlays into server-driven UI iOS frameworks (Uzori, DivKit, AGenUI), you’ll want schemas describing images, captions, badges, and CTAs.
Step 7: JSON schema for overlay card with badge + CTA
Here’s an explicit example schema that’s easy for an LLM or renderer to consume.
{
"type": "overlay_card",
"image": {
"url": "https://cdn.example.com/plans/premium.png",
"alt": "Premium roaming protection plan",
"aspect_ratio": "4:3",
"srcset": [
{ "url": "https://cdn.example.com/plans/premium-small.png", "width": 480 },
{ "url": "https://cdn.example.com/plans/premium-medium.png", "width": 768 },
{ "url": "https://cdn.example.com/plans/premium-large.png", "width": 1200 }
]
},
"caption": "Premium roaming protection",
"badge": {
"label": "Protected",
"variant": "success",
"position": "top_left"
},
"cta": {
"label": "Change plan",
"action_id": "change_plan",
"importance": "primary"
}
}
Field meanings:
image: source URLs, alt text, aspect ratio and responsivesrcset.caption: short descriptive text.badge: label plus semantic variant and position (top_left,top_right, etc.).cta: text plus anaction_idyour backend can route to an API.
You can extend this with status, price, or pill arrays for richer layouts.
Step 8: Rendering schema to SwiftUI (manual or via Uzori)
If you’re not ready for a full Uzori integration yet, you can manually render schema into SwiftUI views:
struct OverlayCardModel: Decodable {
struct ImageModel: Decodable {
let url: URL
let alt: String
let aspectRatio: String
}
struct BadgeModel: Decodable {
let label: String
let variant: String
let position: String
}
struct CTAModel: Decodable {
let label: String
let actionID: String
}
let image: ImageModel
let caption: String
let badge: BadgeModel?
let cta: CTAModel?
}
You’d then map position into layout cases:
enum BadgePosition: String {
case topLeft = "top_left"
case topRight = "top_right"
case bottomLeft = "bottom_left"
case bottomRight = "bottom_right"
}
This is effectively the same idea that A2UI and json-render use: typed, declarative descriptors instead of free-form code.
If you integrate Uzori, you would instead expose your back-end via OpenAPI, let the Uzori engine reason over schemas like this, and receive generated SwiftUI screens directly — compressing weeks of UI iteration into a single streaming interface.
Accessibility and responsive details for overlays
All of the patterns above need solid accessibility and responsive behavior.
Step 9: HTML accessibility for image overlays
For HTML/CSS overlays:
- Alt text: always supply meaningful
altfor images. - Roles and labels:
- Use
role="button"andaria-labelon div-based CTAs if they aren’t<button>elements. - Example:
<div role="button" aria-label="Change plan">Change plan</div>.
- Use
- Keyboard focus:
- Ensure clickable overlays are focusable via
tabindex="0"if not naturally focusable. - Provide visible focus styles (
outline,box-shadow).
- Ensure clickable overlays are focusable via
- Tap target sizes:
- Aim for 44×44 px minimum for buttons and badges.
Responsive CSS tips:
- Use
srcsetandsizesfor images to optimize for different devices. - Apply
z-indexto ensure overlays sit above images while not hiding tooltips or other critical content. - Be careful with
pointer-events: none; don’t use it on interactive elements.
Step 10: SwiftUI accessibility for overlays
For SwiftUI equivalents:
- Labels: use
.accessibilityLabel("Change plan")on buttons or overlays. - Traits: add
.accessibilityAddTraits(.isButton)on tappable overlays. - Hit areas: ensure
.frame(minWidth: 44, minHeight: 44)or use.contentShape(Rectangle())to enlarge the tap region. - Dynamic type: avoid hard-coded sizes; let text and padding respond to user font settings.
These practices matter even more when you’re using LLM responses native iOS interfaces tools 2026 like Uzori or AGenUI, because generated layouts will vary by user and scenario.
How this fits into Google A2UI alternatives and Uzori
While the A2UI SwiftUI renderer planned for Q3 2026 is promising, the reality for iOS teams today is:
- You need working overlay patterns for captions, badges, and CTAs.
- You need schemas that can feed generative or server-driven UI engines.
- You want to keep UI native, accessible, and on-brand.
The overlay steps above:
- Provide HTML/CSS snippets any web or hybrid renderer can adopt.
- Map cleanly into SwiftUI ZStack layouts for native iOS.
- Define typed JSON schemas that LLMs and engines like Uzori, A2UI-Swift, or AGenUI can safely generate and stream.
If you’re exploring Uzori vs DivKit or Uzori iOS app development specifically:
- DivKit is excellent if you primarily want server-driven UI with JSON templates and patch-based updates.
- Uzori is the better fit if you want an AI interface layer that goes from AI answer to SwiftUI screen, orchestrating rich flows like roaming plan concierges or product explorers.
You can start with a single assistant screen, feed it schemas like the overlay card above, and let the AI decide whether the user should see comparison views, wizards, or CTA overlays — all as fully native SwiftUI.
Actionable next steps
To move from theory to practice:
- Implement the HTML/CSS overlay pattern shown in Steps 1–3 in your web prototypes or design system docs.
- Mirror it in SwiftUI using the mapping table in Step 6, ensuring touch targets and accessibility are correct.
- Define JSON schemas for overlay cards and other AI-generated components your product needs.
- Evaluate Google A2UI alternatives:
- For open-standard generative UI: A2UI-Swift or AGenUI.
- For broad schema-rendering: json-render.
- For mature SDUI: DivKit.
- For AI-native SwiftUI: Uzori.
- Read the pillar guide "What are my options now?" — rebooking, refunds and the shape of a disruption answer to see how these UI patterns map onto complex disruption flows.
With these steps, you can build overlays that work both as classic CSS snippets and as native SwiftUI interfaces generated by AI — even while the official A2UI SwiftUI renderer remains on the roadmap.
FAQ (Google A2UI, CSS overlays, SwiftUI)
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Is the A2UI SwiftUI renderer available yet?",
"acceptedAnswer": {
"@type": "Answer",
"text": "As of 2026-08-21, the official A2UI SwiftUI renderer is listed as 'Planned' for Q3 2026 on the A2UI roadmap, with stable renderers focused on web and some cross-platform frameworks instead."
}
},
{
"@type": "Question",
"name": "How do I place a div on an image for a CSS overlay?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Wrap your image in a container with position: relative, then add an overlay div with position: absolute and bottom/left/right offsets. For example, .card { position: relative; } and .card__overlay { position: absolute; bottom: 0; left: 0; right: 0; }. This is the standard 'place div on image CSS overlay' pattern."
}
},
{
"@type": "Question",
"name": "How can I convert HTML overlays to SwiftUI?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Use ZStack as the SwiftUI equivalent of position: relative and position: absolute. Put your Image at the back, then overlay captions, badges, and CTA buttons using ZStack alignment, VStack/HStack, and padding. Percent offsets can be handled with GeometryReader. This pattern lets you translate responsive CSS overlays into native SwiftUI views."
}
},
{
"@type": "Question",
"name": "What are some Google A2UI alternatives for iOS?",
"acceptedAnswer": {
"@type": "Answer",
"text": "As of 2026-08-21, practical Google A2UI alternatives for iOS include A2UI-Swift (community SwiftUI renderer for A2UI), AGenUI (A2UI-compatible SDK for iOS/Android/HarmonyOS), DivKit (native server-driven UI for iOS/Android/Web), json-render (schema-based generative UI for JS frameworks), Epoxy (declarative UIKit from Airbnb), and Uzori, which turns LLM answers directly into native SwiftUI screens."
}
},
{
"@type": "Question",
"name": "What touch target size should I use for mobile CTA overlays?",
"acceptedAnswer": {
"@type": "Answer",
"text": "For accessible mobile CTAs and image overlays, a common guideline is a minimum touch target of 44×44 pixels or points. In CSS, ensure buttons have min-width and min-height of at least 44px. In SwiftUI, use .frame(minWidth: 44, minHeight: 44) and a contentShape(Rectangle()) to make the whole area tappable."
}
}
]
}