# Styling Elements

Anytime you click on a component in the **Layout** tab, its editable properties will open on the right side of the editor window in the **component editor**. Here, you can see that clicking on the component in the layout tab opened its relevant properties in the component editor:

<img src="__img0" />

Component Specific Properties [#component-specific-properties]

By default, when you select a component you'll see properties that are specific to it at the top of the component editor. For example, when you select a stack, you'll see stack-specific options. The same is true of text and any other component. Notice how the options change at the top-right here when a stack versus a text component are selected:

<img src="__img1" />

Image generation [#image-generation]

You can use A.I. to generate images. By selecting any image component, you can **click** on the **AI Tools** button to create an image based on the text and style you provide:

<img src="__img2" />

You are presented with two options:

1. **Generate Image:** Use this to create a brand new image, or regenerate an existing one.
2. **Remove Background:** This attempts to remove the background of the existing image element.

**Generating images:**<br />
When the image generation editor modal is open, you can provide:

* **Image description:** A description of the image you'd like to generate. Generally speaking, the more detail you provide, the better the result will be. Instead of saying "Coffee up close", you might say "A close-up of a steaming cup of coffee with a heart-shaped foam design.""
* **Style:** The primary style of the image you're generating. Each one has several sub styles associated with it.
* **Sub-style:** A more specific style within the primary style you've chosen. For example, if you've chosen "Realistic Image", you might choose "Black and White" as a sub-style.
* **Remove background automatically:** Select this to have the image generator attempt to remove the background from the resulting image.

Here's an example prompt:

<img src="__img3" />

And, its result:

<img src="__img4" />

Common component properties [#common-component-properties]

Most components share similar properties related to things such as sizing, padding and more. Those are covered in more detail below.

Note that for any property that deals with editing a particular size, you can click on the disclosure arrow to choose a specific unit (such as `rems`):

<img src="__img5" />

Further, most values accept either an input amount or you can use a slider to set one. Some elements support hovering over them to reveal a slider, as well:

<img src="__img6" />

Tap Behaviors [#tap-behaviors]

You can have a component trigger a specific action when it's tapped or clicked by adding a **tap behavior**. To add a tap behavior, **click** a component from either the Layout tab or the preview canvas, and in the **component editor** under under **Tap Behavior*&#x2A; click **+ Add Action**:

<img src="__img7" />

Available tap actions are:

**Purchases**

* **Purchase:** Begins the purchase flow for a specific product. Choose a product directly, or use **Selected** to purchase whichever product the user selected earlier in the paywall.
* **Select Product:** Puts the chosen product in a selected state. Useful for scenarios such as focusing a product in a paywall drawer, for example, when something is tapped or clicked.
* **Restore:** Begins a purchase restore operation. Useful for restoring purchases someone may have made prior.

Purchase outcome actions [#purchase-outcome-actions]

Purchase actions can run follow-up actions after the purchase flow resolves. This lets one purchase button handle the success path and the abandon path separately.

<img alt="Purchase tap behavior showing After purchase and On Abandon actions" src="__img8" />

The Purchase action includes three important settings:

| Setting            | What it does                                                                                                                                                                            |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Product**        | The product to purchase. Choose a product by position, such as the first or second product, or choose **Selected** to use the product currently selected on the paywall.                |
| **After purchase** | Actions that run after Superwall receives a successful transaction result. The default is **Close**.                                                                                    |
| **On Abandon**     | Actions that run when the user starts the purchase flow, then cancels or dismisses it before the transaction completes. Leave this empty if you do not want a special abandon response. |

You can add multiple actions to either **After purchase** or **On Abandon**. They run in order from top to bottom. Available outcome actions include:

* **Close:** Dismisses the paywall or Flow.
* **Navigate Page:** Moves forward or backward in a Flow.
* **Open URL:** Opens a URL after the purchase outcome.
* **Custom Action:** Sends a custom action to your app.
* **Custom Placement:** Registers a placement, which can present another paywall if your campaign is configured for it.
* **Set User Attribute:** Sets one or more user attributes.
* **Update Variable:** Updates a paywall state variable.
* **Redeem Purchase:** For Web Checkout purchases, sends the completed checkout through a redemption destination, such as the application default, Superwall's redemption page, a direct deep link, or a custom redirect URL.

Before these actions run, Superwall updates transaction state variables for the current paywall. After a successful purchase, `state.didCompleteTransaction` is set to `true` and `products.purchased` points to the purchased product. After an abandoned purchase, `state.didAbandonTransaction` is set to `true` and `products.abandoned` points to the product the user tried to buy. You can use those variables in follow-up actions, conditional content, drawers, or Liquid values.

> **Warning**

On iOS and Android, **On Abandon** actions and **After purchase** actions other than
**Close** require iOS SDK 4.12.6+ or Android SDK 2.6.9+.



> **Note**

Post-purchase action lists are not available for external checkout. For external Stripe
checkout, Superwall uses the application-level redeem purchase behavior instead.



For mobile purchases, use the standard outcome actions above. The following option only appears when the purchase resolves through Web Checkout.

Redeem Purchase for web checkout [#redeem-purchase-for-web-checkout]

Post-purchase actions are available for regular mobile paywalls and web checkout paywalls. **Redeem Purchase** is the Web Checkout-specific post-purchase action: it controls the redemption destination after Stripe checkout completes.

Use it when a Web2App or Web Flow checkout needs to override the application-level post-purchase behavior for one paywall. For example, one checkout button can use the application default while another opens Superwall's hosted redemption page, deep links into the app, or redirects to your own success page.

Add it from the web checkout purchase button's **After purchase** section:

1. Select the button that starts checkout.
2. In **Tap Behavior**, choose **Purchase**.
3. Under **After purchase*&#x2A;, click **+ Add**.
4. Choose **Redeem Purchase**.
5. Select a **Destination**.

<img alt="Tap Behavior menu showing Redeem Purchase in the After purchase action selector" src="__img9" />

| Destination                 | What happens                                                                                                                                                                                                                               |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Use Application Setting** | Uses the app-level [post-purchase behavior](/docs/web-checkout/web-checkout-configuring-stripe-keys-and-settings#post-purchase-behavior). This is the default and is best when every paywall should follow the same Web Checkout behavior. |
| **Open Redemption Page**    | Opens Superwall's hosted redemption page for the completed checkout, even if the application setting is configured to redirect elsewhere.                                                                                                  |
| **Deep Link**               | Opens the generated app deep link for the completed checkout directly. If no completed checkout redemption target is available, the action does nothing.                                                                                   |
| **Custom Redirect**         | Redirects to the URL you enter when the checkout produces a single successful redemption code. Superwall appends checkout context, including placement parameters, the app user ID when available, and Stripe purchase identifiers.        |

**Custom Redirect** URLs must include a protocol, such as `https://example.com/success`. You can insert paywall variables into the URL from the variable picker. Use this when the next step is your own onboarding, analytics, account creation, or success page rather than Superwall's hosted redemption page.

If Superwall cannot safely use the custom redirect, such as when the checkout has multiple redemption codes, it falls back to the hosted redemption page.

> **Note**

**Redeem Purchase** only runs when Superwall has a completed Web Checkout redemption
target. For non-web-checkout purchases, use the standard **After purchase** actions,
such as **Close**, **Navigate Page**, **Open URL**, or **Custom Action**.



**Navigation**

* **Navigate Page:** Moves through a [Flow](/docs/dashboard/dashboard-creating-flows/getting-started). Use this to progress users through multi-page experiences like onboarding.
  * **Next:** Advances to the next page in the flow.
  * **Back:** Returns to the previous page in the flow.
* **Close:** Closes the paywall or flow.
* **Open URL:** Opens the given URL via one of three different ways:
  1. **In-app browser:** Attempts to open the link *inside* of the app using the platform's web browser control. For example, on iOS, this opens an instance of [`SFSafariViewController`](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller).
  2. **External:** Attempts to open the link *outside* of the app using the platform's web browser app. For example, on iOS, this opens Safari. Please note that the paywall stays presented when the link is opened.
  3. **Deep Link:** Similar to the **external** option, but it'll *close* the paywall before opening the URL. This is useful for internal navigation or when you are attempting to link to something in a web page and you'd like the paywall to close when doing so.
* **Scroll To Element:** Scrolls the view to a specific element on the page.

> **Warning**

For Stripe Checkout or other external purchase links on iOS, use the **External** option. Do not use the in-app browser option for purchase flows.



**State & Variables**

* **Update Variable:** Sets or updates an existing variable's value. Options specific to the variable type will also be displayed. For example, a **Number** variable will have an option to choose an **Operation** such as Set, Increment or Decrement. Or, a **Boolean** variable's **Operation** will offer to either **Set** or **Toggle** the boolean value.
* **Set Attribute:** Sets a user attribute directly from the paywall. Enter a **Key** (e.g., `preferredPlan`, `onboardingComplete`) and a **Value** (e.g., `premium`, `true&#x60;). You can add multiple attributes per tap using **+ Add Attribute**. This behaves the same as calling `setUserAttributes()` in the SDK. Common use cases include capturing user preferences from paywall surveys, tracking paywall engagement, or segmenting users for A/B tests based on their choices. &#x2A;Requires iOS SDK v4.10.7+.*

**Prompts**

* **Request Permission:** Requests a system permission. Useful for gathering permissions during onboarding flows. Available permissions are:

  * **Notification:** Ask for permission to send system notifications.
  * **Background Location:** Request location access when the app isn't in use.
  * **Location:** Request location access while the app is in use.
  * **Read Images:** Access the user's photo library.
  * **Contacts:** Access the user's contacts.
  * **Camera:** Access the device camera.
  * **App Tracking Transparency:** Ask to track the user across apps and websites.
  * **Microphone:** Access the device microphone.

  You can add follow-up actions using **If Granted** and **If Denied** to run different actions depending on the user's response. For example, navigate to the next page when granted, or show a different page when denied. In the editor preview, permission requests are simulated with **Grant** and **Deny** buttons so you can test both paths without deploying.
* **Request Store Review:** Requests a review for the given app storefront.
  1. **Rating Prompt:** Attempts to display the system-level ratings prompt for the platform. On Android, you may use `useMockReviews` on `SuperwallOptions` to ensure a prompt shows while testing.
  2. **Written Review:** This option deeplinks to the respective App Store so the user can write a written review.

**Custom Actions**

* **Custom Action:** Performs a custom action that you specify. Using custom actions, you can tie application logic to anything tapped or clicked on your paywall. Check out the docs [here](/docs/sdk/guides/advanced/custom-paywall-actions).
* **Custom Placement:** Registers the placement you specify in the **Name** field. The name field supports dynamic values via Liquid templates, so you can insert state variables to create placement names that resolve at runtime (e.g., a name that includes the user's selected plan). Use the variable picker button next to the name field to insert variables. One common use-case is presenting another paywall from a currently opened one. Check out the example [here](/docs/dashboard/guides/presenting-paywalls-from-one-another).
* **Delay:** Pauses the action chain for a specified number of **Seconds** before continuing to the next action. This is useful when you have multiple actions on a single tap and want to space them out. For example, setting a variable and then closing the paywall after a short pause. It's also useful for driving animation states or creating auto-advance timers. The **Interruptible** option controls what happens if the user taps the same element again while a delay is pending: **Yes** cancels the current delay and restarts the action chain, while **No** ignores the tap until the delay completes.
* **Custom Callback:** Sends a named callback request to the SDK, allowing you to run custom app logic and respond with a result. Enter a **Name** for the callback and choose a **Behavior**: **Blocking** waits for the SDK to respond before continuing the action chain, while **Non-blocking*&#x2A; fires the request and continues immediately. You can pass paywall variables to the SDK using **+ Add Variable**. Use the **On Success** and **On Failure** sections to add follow-up actions that run depending on the SDK's response. For example, you could validate something in your app and then update a variable or close the paywall based on the result. In the editor preview, callbacks are simulated with **Success** and **Failure** buttons so you can test both paths. &#x2A;Requires iOS SDK v4.12.10+ or Android SDK v2.7.0+.*

Animation [#animation]

Each tap behavior includes an **Animation** dropdown that plays a visual effect when the element is tapped. Available options are:

* **None:** No animation (default).
* **Shrink:** The element briefly scales down and back up.
* **Grow:** The element briefly scales up and back down.
* **Fade:** The element briefly fades out and back in.

Haptics [#haptics]

Each tap behavior includes a **Haptics** dropdown that triggers a platform-native haptic feedback pattern on the user's device. Available on iOS and Android. Available options are:

* **None:** No haptic feedback (default).
* **Light:** A subtle, light tap.
* **Medium:** A moderate tap.
* **Heavy:** A strong, pronounced tap.
* **Success:** A feedback pattern indicating a successful action.
* **Warning:** A feedback pattern indicating a cautionary action.
* **Error:** A feedback pattern indicating a failed action.
* **Selection:** A light tap suited for selection changes.

If a component has a tap action associated to it, you'll also see a **triangle** icon next to it within the sidebar:

<img src="__img10" />

Component styling properties [#component-styling-properties]

The properties below are editable regardless of which kind of component you are editing. The most important thing to keep in mind is that all of the properties below will work the same as they would on a web page. When you change these properties, behind the scenes — Superwall is applying the corresponding CSS code to the paywall.

Typography [#typography]

Edit the text, size, color and more of a component's text:

<img src="__img11" />

If you've added a [custom font](/docs/dashboard/dashboard-creating-paywalls/paywall-editor-theme#custom-fonts), you can also select it here.

Layer [#layer]

Properties here edit the underlying layer of the component:

<img src="__img12" />

If you want a background fill, to toggle its overall opacity or other similar things — the layer is a great spot to do it.

Size [#size]

Use size properties to set an explicitly width or height on the component:

<img src="__img13" />

Using the dropdown arrow, you can set a range of minimum and maximum values:

<img src="__img14" />

Padding [#padding]

Apply padding to the content within the component:

<img src="__img15" />

To have more granular control, expand each disclosure arrow to set only the top, bottom, left or right padding values:

<img src="__img16" />

Margin [#margin]

Apply spacing to the content outside of the component, further separating it from adjacent components:

<img src="__img17" />

Corners [#corners]

Applies a corner radius to the component:

<img src="__img18" />

Note that you may not see any change unless the component has some sort of background or layer fill. Further, if you'd like to adjust just one or more corners, click the dashed square icon to individually enter values:

<img src="__img19" />

Borders [#borders]

Set a border around the the component:

<img src="__img20" />

You can set its width, style (i.e. dashed, solid, etc) and more.

Position [#position]

Specifies the position strategy used to place the component:

<img src="__img21" />

If you'd like to layer a component on top or below another component, the `Z Index` value is perfect here.

The most important value is what you use for `position`. Again, all of these options mirror their CSS counterpart. The available options are:

* **Normal:** The default option. The component will be positioned according to the normal flow of the paywall's hierarchy. This is analogous to `static` in CSS.
* **Relative:** Positions the component relative to its normal position, allowing you to move it with top, right, bottom, and left offsets *without* affecting the layout of surrounding components.
* **Absolute:** Removes the component from the normal paywall hierarchy flow and positions it relative to its nearest positioned component (which won't necessarily be a parent component).
* **Fixed:** Positions the component relative to the viewport, meaning it will stay in the same place even when the paywall is scrolled.
* **Sticky:** The component will behave as if it has a `normal` position *until* it teaches a certain point in the viewport. Then, it acts like it has a `fixed` position, sticking in place. This is great for sticky headers,footers or banners.

Mozilla has excellent developer docs over how the [position](https://developer.mozilla.org/en-US/docs/Web/CSS/position) CSS property works, along with interactive code samples. If you're having some issues getting things placed how you'd like, this is a great resource to check out.

Effects [#effects]

Applies CSS effects to the component:

<img src="__img22" />

If you're new to CSS transitions and animations, check out this interactive [reference](https://www.w3schools.com/css/css3_transitions.asp).

Custom CSS [#custom-css]

If you need to add some one-off custom CSS code, you can add them here. Just click **+ Add Property**:

<img src="__img23" />

From there, type in the CSS property you need and select it from our dropdown menu:

<img src="__img24" />

Here, you can see a manually set background value for the selected component:

<img src="__img25" />

> **Warning**

Using the Custom CSS section should be your last step, and only if you absolutely cannot achieve
the design you need. For example, here we should simply use the `layer` section to set a
background color.



This section applies CSS properties to the selected component. It is not a full stylesheet editor, so it cannot define CSS rules or `@keyframes` blocks. CSS `@keyframes` are not currently supported in the paywall editor's Custom CSS fields; use tap behavior animations, Effects, Lottie, GIFs, or video for motion.

CSS Output [#css-output]

As you make any changes to these properties, you can see the actual CSS that Superwall is applying by scrolling down in the component editor to the **CSS Output** section:

<img src="__img26" />

This can be useful for debugging or further refining your designs.