Borders Utilities
useUtilitiesPreset). For most projects, applying them via the preset is the recommended approach.Overview
Border utilities help you control border styling including colors, widths, radiuses, styles, outlines, and focus rings. These utilities include directional variants for fine-grained control.
Why Use Border Utilities?
Border utilities help you:
- Create consistent borders: Generate reusable border styles across your application
- Support directional control: Apply borders to specific sides or use logical properties for RTL support
- Integrate with design tokens: Reference your color and spacing systems with
ref() - Build accessible focus states: Create visible focus rings for keyboard navigation
useBorderColorUtility
The useBorderColorUtility() function creates utility classes for setting border colors.
import { styleframe } from "styleframe";
import { useColorDesignTokens } from "@styleframe/theme";
import { useBorderColorUtility } from "@styleframe/theme";
const s = styleframe();
const { ref } = s;
const { colorPrimary, colorGray300 } = useColorDesignTokens(s, {
primary: '#006cff',
gray300: '#d1d5db',
} as const);
useBorderColorUtility(s, {
inherit: 'inherit',
current: 'currentColor',
transparent: 'transparent',
primary: ref(colorPrimary),
gray: ref(colorGray300),
});
export default s;
:root {
--color--primary: oklch(0.5749 0.233917 259.9541 / 1);
--color--gray-300: oklch(0.8694 0.0068 264.53 / 1);
}
._border-color\:inherit { border-color: inherit; }
._border-color\:current { border-color: currentColor; }
._border-color\:transparent { border-color: transparent; }
._border-color\:primary { border-color: var(--color--primary); }
._border-color\:gray { border-color: var(--color--gray-300); }
<div class="_border-color:primary">Primary border</div>
<input class="_border-color:gray" type="text" placeholder="Gray border input">
Directional Variants
Border color utilities include directional variants for applying colors to specific sides:
| Utility | Description |
|---|---|
useBorderColorUtility | All sides |
useBorderColorXUtility | Left and right |
useBorderColorYUtility | Top and bottom |
useBorderColorTopUtility | Top only |
useBorderColorRightUtility | Right only |
useBorderColorBottomUtility | Bottom only |
useBorderColorLeftUtility | Left only |
useBorderColorStartUtility | Inline start (RTL-aware) |
useBorderColorEndUtility | Inline end (RTL-aware) |
useBorderWidthUtility
The useBorderWidthUtility() function creates utility classes for setting border widths.
import { styleframe } from "styleframe";
import { useBorderWidthUtility } from "@styleframe/theme";
const s = styleframe();
useBorderWidthUtility(s, {
'0': '0px',
'1': '1px',
'2': '2px',
'4': '4px',
'8': '8px',
});
export default s;
._border-width\:0 { border-width: 0px; }
._border-width\:1 { border-width: 1px; }
._border-width\:2 { border-width: 2px; }
._border-width\:4 { border-width: 4px; }
._border-width\:8 { border-width: 8px; }
<div class="_border-width:1">Thin border</div>
<div class="_border-width:2">Medium border</div>
<div class="_border-width:4">Thick border</div>
Directional Variants
Border width utilities include directional variants for applying widths to specific sides:
| Utility | Description |
|---|---|
useBorderWidthUtility | All sides |
useBorderWidthXUtility | Left and right |
useBorderWidthYUtility | Top and bottom |
useBorderWidthTopUtility | Top only |
useBorderWidthRightUtility | Right only |
useBorderWidthBottomUtility | Bottom only |
useBorderWidthLeftUtility | Left only |
useBorderWidthStartUtility | Inline start (RTL-aware) |
useBorderWidthEndUtility | Inline end (RTL-aware) |
useBorderRadiusUtility
The useBorderRadiusUtility() function creates utility classes for setting border radius.
import { styleframe } from "styleframe";
import { useBorderRadiusUtility } from "@styleframe/theme";
const s = styleframe();
useBorderRadiusUtility(s, {
none: '0px',
sm: '0.125rem',
default: '0.25rem',
md: '0.375rem',
lg: '0.5rem',
xl: '0.75rem',
'2xl': '1rem',
'3xl': '1.5rem',
full: '9999px',
});
export default s;
._border-radius\:none { border-radius: 0px; }
._border-radius\:sm { border-radius: 0.125rem; }
._border-radius { border-radius: 0.25rem; }
._border-radius\:md { border-radius: 0.375rem; }
._border-radius\:lg { border-radius: 0.5rem; }
._border-radius\:xl { border-radius: 0.75rem; }
._border-radius\:2xl { border-radius: 1rem; }
._border-radius\:3xl { border-radius: 1.5rem; }
._border-radius\:full { border-radius: 9999px; }
<div class="_border-radius:md">Rounded card</div>
<button class="_border-radius:full">Pill button</button>
<img class="_border-radius:lg" src="avatar.jpg" alt="Avatar">
Directional Radius Variants
Border radius utilities include variants for rounding specific corners:
| Utility | Description |
|---|---|
useBorderRadiusUtility | All corners |
useBorderRadiusTopUtility | Top left and top right |
useBorderRadiusRightUtility | Top right and bottom right |
useBorderRadiusBottomUtility | Bottom left and bottom right |
useBorderRadiusLeftUtility | Top left and bottom left |
useBorderRadiusStartUtility | Start corners (RTL-aware) |
useBorderRadiusEndUtility | End corners (RTL-aware) |
useBorderRadiusTopLeftUtility | Top left only |
useBorderRadiusTopRightUtility | Top right only |
useBorderRadiusBottomRightUtility | Bottom right only |
useBorderRadiusBottomLeftUtility | Bottom left only |
useBorderStyleUtility
The useBorderStyleUtility() function creates utility classes for setting border styles.
import { styleframe } from "styleframe";
import { useBorderStyleUtility } from "@styleframe/theme";
const s = styleframe();
// Uses built-in defaults: solid, dashed, dotted, double, hidden, none
useBorderStyleUtility(s);
export default s;
._border-style\:solid { border-style: solid; }
._border-style\:dashed { border-style: dashed; }
._border-style\:dotted { border-style: dotted; }
._border-style\:double { border-style: double; }
._border-style\:hidden { border-style: hidden; }
._border-style\:none { border-style: none; }
<div class="_border-style:solid">Solid border</div>
<div class="_border-style:dashed">Dashed border</div>
<div class="_border-style:dotted">Dotted border</div>
Default Values
| Key | Value | Description |
|---|---|---|
solid | solid | Solid line border |
dashed | dashed | Dashed line border |
dotted | dotted | Dotted line border |
double | double | Double line border |
hidden | hidden | Hidden border (takes up space) |
none | none | No border |
useOutlineWidthUtility
The useOutlineWidthUtility() function creates utility classes for setting outline widths.
import { styleframe } from "styleframe";
import { useOutlineWidthUtility, useOutlineStyleUtility, useOutlineColorUtility } from "@styleframe/theme";
const s = styleframe();
useOutlineWidthUtility(s, {
'0': '0px',
'1': '1px',
'2': '2px',
'4': '4px',
});
useOutlineStyleUtility(s); // Uses defaults
useOutlineColorUtility(s, {
primary: '#006cff',
transparent: 'transparent',
});
export default s;
._outline\:0 { outline-width: 0px; }
._outline\:1 { outline-width: 1px; }
._outline\:2 { outline-width: 2px; }
._outline\:4 { outline-width: 4px; }
._outline-style\:none { outline-style: none; }
._outline-style\:solid { outline-style: solid; }
._outline-style\:dashed { outline-style: dashed; }
._outline-style\:dotted { outline-style: dotted; }
._outline-style\:double { outline-style: double; }
._outline-color\:primary { outline-color: #006cff; }
._outline-color\:transparent { outline-color: transparent; }
<button class="_outline:2 _outline-style:solid _outline-color:primary">
Outlined button
</button>
<input class="_outline:0" type="text" placeholder="No outline">
Outline Utilities
| Utility | Description |
|---|---|
useOutlineWidthUtility | Set outline width |
useOutlineColorUtility | Set outline color |
useOutlineStyleUtility | Set outline style (has defaults) |
useOutlineOffsetUtility | Set outline offset |
useRingWidthUtility
The ring utilities create focus ring effects using box-shadow. This is useful for accessible focus indicators that don't affect layout.
import { styleframe } from "styleframe";
import { useRingWidthUtility, useRingColorUtility, useRingOffsetWidthUtility } from "@styleframe/theme";
const s = styleframe();
useRingWidthUtility(s, {
'0': '0px',
'1': '1px',
'2': '2px',
default: '3px',
'4': '4px',
});
useRingColorUtility(s, {
primary: '#006cff',
white: '#fff',
});
useRingOffsetWidthUtility(s, {
'0': '0px',
'1': '1px',
'2': '2px',
});
export default s;
._ring\:0 {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
._ring\:1 {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
._ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
._ring-color\:primary { --tw-ring-color: #006cff; }
._ring-color\:white { --tw-ring-color: #fff; }
._ring-offset\:0 { --tw-ring-offset-width: 0px; }
._ring-offset\:1 { --tw-ring-offset-width: 1px; }
._ring-offset\:2 { --tw-ring-offset-width: 2px; }
<button class="_ring:2 _ring-color:primary">
Button with focus ring
</button>
<input class="_focus:ring:2 _ring-color:primary" type="text">
Ring Utilities
| Utility | Description |
|---|---|
useRingWidthUtility | Set ring width |
useRingColorUtility | Set ring color |
useRingInsetUtility | Make ring inset |
useRingOffsetWidthUtility | Set ring offset width |
useRingOffsetColorUtility | Set ring offset color |
Examples
Card with Rounded Corners
import { styleframe } from "styleframe";
import { useBorderRadiusUtility, useBorderWidthUtility, useBorderColorUtility } from "@styleframe/theme";
import { useColorDesignTokens } from "@styleframe/theme";
const s = styleframe();
const { ref } = s;
const { colorGray200 } = useColorDesignTokens(s, { gray200: '#e5e7eb' } as const);
useBorderRadiusUtility(s, {
md: '0.375rem',
lg: '0.5rem',
xl: '0.75rem',
});
useBorderWidthUtility(s, {
'1': '1px',
});
useBorderColorUtility(s, {
gray: ref(colorGray200),
});
export default s;
:root {
--color--gray-200: oklch(0.9218 0.0042 264.53 / 1);
}
._border-radius\:md { border-radius: 0.375rem; }
._border-radius\:lg { border-radius: 0.5rem; }
._border-radius\:xl { border-radius: 0.75rem; }
._border-width\:1 { border-width: 1px; }
._border-color\:gray { border-color: var(--color--gray-200); }
Usage in HTML:
<div class="_border-width:1 _border-color:gray _border-radius:lg">
Card content
</div>
Focus Ring for Buttons
import { styleframe } from "styleframe";
import { useRingWidthUtility, useRingColorUtility, useRingOffsetWidthUtility } from "@styleframe/theme";
import { useColorDesignTokens } from "@styleframe/theme";
const s = styleframe();
const { ref, selector, modifier } = s;
const { colorPrimary } = useColorDesignTokens(s, { primary: '#006cff' } as const);
useRingWidthUtility(s, { '2': '2px', default: '3px' });
useRingColorUtility(s, { primary: ref(colorPrimary) });
useRingOffsetWidthUtility(s, { '2': '2px' });
// Create a focus modifier
const focus = modifier('focus', ({ declarations }) => ({
'&:focus': declarations,
}));
// Apply focus ring with modifier
useRingWidthUtility(s, { '2': '2px' }, [focus]);
export default s;
:root {
--color--primary: oklch(0.5749 0.233917 259.9541 / 1);
}
._ring\:2 {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
._ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
._ring-color\:primary { --tw-ring-color: var(--color--primary); }
._ring-offset\:2 { --tw-ring-offset-width: 2px; }
._focus\:ring\:2:focus {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
Best Practices
- Use design tokens: Reference your color variables with
ref()for consistent border colors - Consider accessibility: Ensure sufficient contrast for borders, especially for form inputs
- Use ring for focus states: Ring utilities don't affect layout, making them ideal for focus indicators
- Leverage logical properties: Use start/end variants for RTL-friendly designs
- Be consistent with radius: Use a consistent radius scale across your components
- Test border styles: Dashed and dotted borders render differently across browsers
FAQ
border-inline-start automatically flip in RTL (right-to-left) layouts. This makes your styles work correctly for both LTR and RTL languages without additional CSS.border-radius: full (9999px) on elements with a defined height. The large value ensures fully rounded ends regardless of the element's size.border-radius: full (9999px) may cause unexpected intermediate states. Consider using fixed pixel values for smoother animations.