Borders
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 { useColor } from "@styleframe/theme";
import { useBorderColorUtility } from "@styleframe/theme";
const s = styleframe();
const { ref } = s;
const { colorPrimary, colorGray300 } = useColor(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>
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 { useColor } from "@styleframe/theme";
const s = styleframe();
const { ref } = s;
const { colorGray200 } = useColor(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 { useColor } from "@styleframe/theme";
const s = styleframe();
const { ref, selector, modifier } = s;
const { colorPrimary } = useColor(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.