LinkButton
Overview
The LinkButton component renders a <button> that visually looks like text or a link.
It provides an accessible replacement for <div onClick> anti-patterns by wrapping the Button component with is-text or is-ghost styling and CSS overrides.
Three variants:
text(default) — like Bulma'sis-textbutton but without the underline. Hover shows a background highlight.ghost— like Bulma'sis-ghostbutton but without the link color. Hover shows an underline.underline— no button chrome at all: transparent background and border, plain text color, and an underline on hover or focus.
All three support an optional color prop to set the text color.
Use LinkButton instead of <div onClick> or unstyled click handlers to get proper keyboard navigation, focus handling, and screen reader support for free.
Import
import { LinkButton } from '@allxsmith/bestax-bulma';
Usage
Default (Text Variant)
The default variant renders a minimal text button without underline. On hover it shows a background highlight.
<LinkButton>Click me</LinkButton>
Ghost Variant
The ghost variant renders a link-like button with default text color (not link color). On hover it shows an underline.
<LinkButton variant="ghost">Ghost LinkButton</LinkButton>
Underline Variant
The underline variant drops the button chrome entirely — transparent background and border, plain text color — and underlines on hover or focus. Use it for an inline action inside a sentence or a summary step ("go back and edit"), where a second solid button would compete with the primary one.
<LinkButton variant="underline">Go back and edit</LinkButton>
Text Variant with Color
Add a color prop to set the text color. The hover behavior remains the same.
<LinkButton color="primary">Primary Text</LinkButton>
Ghost Variant with Color
Colors work with the ghost variant too.
<LinkButton variant="ghost" color="danger"> Danger Ghost </LinkButton>
All Colors
<Buttons> {['primary', 'link', 'info', 'success', 'warning', 'danger'].map(color => ( <LinkButton key={color} color={color}> {color.charAt(0).toUpperCase() + color.slice(1)} </LinkButton> ))} </Buttons>
Disabled
<LinkButton isDisabled disabled> Disabled LinkButton </LinkButton>
All Sizes
<Buttons> {['small', 'normal', 'medium', 'large'].map(size => ( <LinkButton key={size} size={size}> {size.charAt(0).toUpperCase() + size.slice(1)} </LinkButton> ))} </Buttons>
Polymorphic as (Router Links)
Since LinkButton forwards its props to Button, it inherits the same polymorphic as prop — render it as a router's Link component to get a link-styled, a11y-friendly, client-side-navigating call to action.
import { Link as RouterLink } from 'react-router-dom';
import { LinkButton } from '@allxsmith/bestax-bulma';
<LinkButton as={RouterLink} to="/dashboard" variant="underline">
Go to Dashboard
</LinkButton>;
Forwarded ref
LinkButton forwards a ref to the element it renders. That is a <button> by default — the component styles a button to look like a link — and whatever as selects otherwise, so as="a" with an href gives you an anchor.
function example() { const defaultRef = React.useRef(null); const anchorRef = React.useRef(null); const [tags, setTags] = React.useState(null); return ( <> <LinkButton ref={defaultRef}>Default</LinkButton> <LinkButton as="a" href="#forwarded-ref" ml="2" ref={anchorRef}> As an anchor </LinkButton> <Button ml="2" onClick={() => setTags( `${defaultRef.current?.tagName} / ${anchorRef.current?.tagName}` ) } > Read both from their refs </Button> <p>Rendered elements: {tags ?? '—'}</p> </> ); }
Visual Behavior
| Default text color | Hover | |
|---|---|---|
| text variant | var(--bulma-text) | Background highlight, no underline |
| ghost variant | var(--bulma-text) | Underline appears |
| underline variant | var(--bulma-text) | Underline appears, background stays transparent |
| + color | Uses specified color | Same hover behavior, color maintained |
Accessibility
- Semantic HTML: Renders a native
<button>element, providing correct keyboard navigation, focus management, and screen reader announcements. - States: The
isDisabledanddisabledprops ensure correctaria-disabledanddisabledattributes. - Keyboard: Fully keyboard accessible with Enter and Space activation.
- Replaces anti-patterns: Use this instead of
<div onClick>or<span onClick>for interactive elements that should not navigate.
If your LinkButton has only an icon, use aria-label to provide accessible text.
Related Components
Button: Full-featured button with all Bulma styles.Buttons: Group multiple buttons together.- Helper Props: List of all supported Bulma helper props.
Additional Resources
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as | React.ElementType | 'button' | Render as a <button>, <a>, or a custom component (e.g. a router Link). |
variant | 'text' | 'ghost' | 'underline' | 'text' | Display mode. text has no underline and highlights its background on hover; ghost uses the default text color and underlines on hover; underline drops the button chrome entirely (transparent background and border) and underlines on hover or focus. |
color | 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger' | 'white' | 'light' | 'dark' | 'black' | — | Text color override for the button. |
size | 'small' | 'normal' | 'medium' | 'large' | — | Size of the button. |
isRounded | boolean | false | Makes the button rounded. |
isLoading | boolean | false | Displays a loading spinner. |
isStatic | boolean | false | Makes the button non-interactive. |
isFullwidth | boolean | false | Makes the button full-width. |
isFullWidth | boolean | false | Deprecated. Use isFullwidth instead — isFullwidth wins if both are set. Makes the button full-width. |
isFocused | boolean | false | Applies focused styling (visual only). |
isActive | boolean | false | Applies active styling (visual only). |
isHovered | boolean | false | Applies hovered styling (visual only). |
isDisabled | boolean | false | Applies disabled styling. |
className | string | — | Custom class name. |
textColor | Bulma color | 'inherit' | 'current' | — | Text color helper. |
bgColor | Bulma color | 'inherit' | 'current' | — | Background color helper. |
children | React.ReactNode | — | Button content. |
ref | PolymorphicRef<React.ElementType> | — | Ref forwarded to the element as renders, typed from as: the DOM node for an intrinsic tag, or whatever handle a custom component exposes. |
... | Remaining props of the element or component selected by as (default <button>) and Bulma helper props | — | See Helper Props |
The isOutlined, isInverted, and isLight props from Button are not available on LinkButton — they don't apply to link-like buttons.
CSS & Sass Variables
LinkButton registers these variables on a compound selector (higher specificity than a single class). Override them with inline style, or with a selector that exceeds that specificity (one that only matches it must load after the library styles to win by source order) — a lone class via className loses to the component-level declaration. See Theme.
| CSS Variable | Sass Variable | Default |
|---|---|---|
--bulma-link-button-underline-offset | $link-button-underline-offset | 0.2em |
--bulma-link-button-transition-duration | $link-button-transition-duration | var(--bulma-duration) |
--bulma-link-button-ghost-color | $link-button-ghost-color | var(--bulma-text) |
--bulma-link-button-ghost-hover-color | $link-button-ghost-hover-color | var(--bulma-text-strong) |