Black Friday: 50% off all products for the first 50 customers. Only 10 left. Use code
40/50 claimed
See pricing →
November 10, 2026

Quasar Button (QBtn): Every Prop in a Playground

Quasar button guide for 2.35.2: QBtn design, shape and size props, icons and loading states, plus a free playground that writes the q-btn code for you.
Quasar
Vue
Buttons
Tools

The Quasar button, q-btn, has more than 30 props, and most of them change how it looks: flat, outline, push, rounded, round, size, dense, glossy. Some of them cancel each other out, and which one wins isn't obvious from the docs. Today we're launching the QBtn Playground, a free tool where you toggle those props on a live button and copy the q-btn it writes. This post walks through the same props, with what Quasar 2.35.2 does when you combine them.

The QBtn Playground

The QBtn Playground is a live q-btn with a control for each of the props people search for:

  • Color and text color, from the brand colors and the Quasar palette.
  • Design: standard, flat, outline, unelevated or push.
  • Shape: default, rounded, round or square.
  • Size, from xs to xl.
  • Icons: icon and icon-right, from a list of Material Icons or any name you type.
  • Toggles: glossy, dense, no-caps, stack, loading and disable.
  • Quick looks: one click for standard, flat, outline, unelevated, push, rounded, glossy or a round icon button.

As you change a control, the template updates with only the props that differ from the defaults, and one click copies it. Pick the round shape with an icon and the label moves to an aria-label, for the reason explained below. It runs in the browser, so there's no sign-in and nothing is sent to a server. The rest of this post explains what each control does, so you know why the copied code looks the way it does.

Quasar button design props

A q-btn has one design. With no design prop it's the standard button: a filled background with a shadow. The other four:

PropLook
flatNo background, no shadow. The color goes to the text.
outlineA border in the button's color, transparent inside.
unelevatedFilled like standard, but without the shadow.
pushFilled, with a bottom edge that "presses" on click.
<q-btn color="primary" label="Standard" />
<q-btn flat color="primary" label="Flat" />
<q-btn outline color="primary" label="Outline" />
<q-btn unelevated color="primary" label="Unelevated" />
<q-btn push color="primary" label="Push" />

Which design wins when you set two

Only one design applies. In the 2.35.2 source, Quasar checks them in a fixed order: flat, then outline, then push, then unelevated. So <q-btn flat outline> is a flat button, and <q-btn push unelevated> is a push button. The playground treats design as a single choice for this reason.

glossy is separate. It adds a gloss effect on top of whatever design you picked.

How color works

The color prop does different things depending on the design:

  • With flat or outline, color sets the text (and the border, for outline). text-color overrides both, because the outline border is drawn in the text color, so the border and the text always match.
  • With standard, unelevated or push, color sets the background, and the text is white unless you set text-color.

That's why a light background needs both props: <q-btn unelevated color="grey-2" text-color="grey-9" label="Cancel" />.

Shape: rounded, round and square

  • rounded gives the rectangle a pill-shaped radius.
  • square removes the radius.
  • round makes a circle. It's meant for a single icon.

round wins over the other two, since it replaces the rectangle shape. Combining rounded and square makes no sense, so pick one.

A round button usually has only an icon, and an icon has no text a screen reader can read. QBtn has no aria-label prop, but the attribute falls through to the rendered <button>, so add it yourself:

<q-btn round flat icon="delete" aria-label="Delete row" />

The Quasar docs point out that a q-tooltip inside the button doesn't fix this. It becomes the button's description, not its name.

Size, dense and padding

size takes a name or any CSS size. The names set the button's font size. The height and the icon scale with it, because they are set in em, while the side padding stays at 16px:

sizeFont size
xs8px
sm10px
md14px
lg20px
xl24px

md is the same as no size at all. For a size in between, use a unit: size="12px".

dense makes the button more compact at the same font size, which fits table rows and toolbars. padding sets the padding directly (padding="xs lg", or CSS values), and it also removes the button's minimum width and height, so the button can be as small as its content.

Icons and custom content

icon puts an icon before the label and icon-right puts one after it. stack places the icon above the label.

<q-btn unelevated no-caps color="primary" icon="add" label="New project" />
<q-btn outline no-caps color="primary" icon-right="arrow_forward" label="Continue" />
<q-btn flat stack no-caps icon="cloud_upload" label="Upload" />

Icon names follow Quasar's conventions: add is a Material Icon, mdi-plus is from MDI, and so on, provided that icon set is installed. Labels are uppercase by default; no-caps keeps the case you wrote. For anything else, the default slot replaces icon and label, so a badge or an avatar can go inside the button.

QBtn loading states

loading replaces the button's content with a spinner. The button keeps its width, so the layout doesn't jump. Since 2.25, a loading button is marked aria-disabled="true", drops out of the Tab order and ignores clicks, so a double-click can't submit a form twice.

<script setup lang="ts">
import { ref } from 'vue'

const saving = ref(false)

async function save() {
  saving.value = true
  try {
    await saveSettings()
  } finally {
    saving.value = false
  }
}
</script>

<template>
  <q-form @submit="save">
    <!-- fields -->
    <q-btn type="submit" unelevated no-caps color="primary" label="Save changes" :loading="saving">
      <template #loading>
        <q-spinner class="on-left" />
        Saving…
      </template>
    </q-btn>
  </q-form>
</template>
  • The #loading slot replaces the default QSpinner. Here it keeps a word next to the spinner, so the user knows what's happening.
  • type="submit" makes the button submit the form, so Enter in a field works too. The Quasar docs add one catch: a submit button inside the before, after, prepend or append slot of a q-input, q-select or q-field also needs a @click that submits, since clicks in those slots don't propagate.
  • percentage, used with loading, draws a progress bar on the button's background for uploads or long tasks. The button then reports itself as a progressbar to screen readers. dark-percentage darkens the bar for light buttons.

disable is the other inactive state. A disabled button is dimmed, and when it renders as a <button> it also gets the native disabled attribute.

Give a q-btn a to (a Vue Router location) or an href, and it renders an <a> instead of a <button>. It still looks the same. Quasar also makes Space activate a link button, which a native <a> doesn't do.

<q-btn flat no-caps color="primary" to="/settings" label="Settings" />
<q-btn outline no-caps color="primary" href="https://quasar.dev" target="_blank" label="Quasar docs" />

With to, the @click handler also receives a go function. Call evt.preventDefault() in the handler, do your async work, then call go() to navigate.

Common questions about the Quasar button

How do I remove the uppercase text? Add no-caps to the button. Quasar has no global setting for it; a CSS rule .q-btn { text-transform: none; } changes every button at once.

My flat and outline props together don't work. Why? Only one design applies, and flat wins. Pick one.

How do I make a full-width button? Add the full-width class, or class="col" inside a row.

How do I show a spinner without disabling the button? You can't with loading, which always blocks interaction while it's set. Put a q-spinner in the default slot instead.

Ready-made buttons

If you'd rather copy a finished set, the Buttons Block has 5 Components built on q-btn: solid buttons, flat and outline pairs, icon buttons, a size scale, and loading and disabled states. Four of them are free.

Next step

Open the QBtn Playground, toggle the props from this post on a live button, and copy the q-btn straight into your template.