@fpkit/acss 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/{chunk-2NRIP6RB.cjs → chunk-2C3YLBWP.cjs} +3 -3
- package/libs/{chunk-NWJDAHP6.cjs → chunk-2GJHKWEK.cjs} +3 -3
- package/libs/{chunk-FVROL3V5.js → chunk-2JCDEC32.js} +3 -3
- package/libs/{chunk-IRLFZ3OL.js → chunk-3XJC4XUG.js} +2 -2
- package/libs/{chunk-23ANBDCR.js → chunk-4I5MF54P.js} +3 -3
- package/libs/chunk-4I5MF54P.js.map +1 -0
- package/libs/chunk-5CJPTDK3.cjs +31 -0
- package/libs/chunk-5CJPTDK3.cjs.map +1 -0
- package/libs/{chunk-E4OSROCA.cjs → chunk-5QSNJQVH.cjs} +3 -3
- package/libs/{chunk-O3JIHC5M.cjs → chunk-6BUJZ4DJ.cjs} +3 -3
- package/libs/{chunk-WXBFBWYF.cjs → chunk-AFINOD2L.cjs} +3 -3
- package/libs/{chunk-HRRHPLER.js → chunk-AWZLSWDO.js} +2 -2
- package/libs/chunk-DDSXKOUB.js +7 -0
- package/libs/chunk-DDSXKOUB.js.map +1 -0
- package/libs/{chunk-CWRNJA4P.js → chunk-DIJBIOFE.js} +3 -3
- package/libs/chunk-EJ6KYBFE.cjs +13 -0
- package/libs/chunk-EJ6KYBFE.cjs.map +1 -0
- package/libs/{chunk-GUJSMQ3V.cjs → chunk-EKJYOCLY.cjs} +3 -3
- package/libs/{chunk-X5RKCLDC.cjs → chunk-F64GE6RG.cjs} +4 -4
- package/libs/chunk-FMIM3332.js +8 -0
- package/libs/chunk-FMIM3332.js.map +1 -0
- package/libs/{chunk-5RAWNUVD.js → chunk-IBUTNPTQ.js} +2 -2
- package/libs/chunk-IWP4VJEP.cjs +18 -0
- package/libs/chunk-IWP4VJEP.cjs.map +1 -0
- package/libs/{chunk-ZFJ4U45S.js → chunk-KDMX3FAW.js} +2 -2
- package/libs/{chunk-DYFAUAB7.cjs → chunk-LXODKKA3.cjs} +4 -4
- package/libs/chunk-M7JLT62Q.js +9 -0
- package/libs/chunk-M7JLT62Q.js.map +1 -0
- package/libs/{chunk-IQ76HGVP.js → chunk-MBWI67UT.js} +2 -2
- package/libs/{chunk-O5XAJ7BY.cjs → chunk-NCGVF2QS.cjs} +4 -4
- package/libs/{chunk-W2UIN7EV.cjs → chunk-NPWHQVYB.cjs} +3 -3
- package/libs/{chunk-G55UJ53G.cjs → chunk-NZVSXRTB.cjs} +3 -3
- package/libs/chunk-NZVSXRTB.cjs.map +1 -0
- package/libs/{chunk-43TK2ICH.js → chunk-PMWL5XZ4.js} +3 -3
- package/libs/{chunk-KVKQLRJG.js → chunk-TF3GQKOY.js} +2 -2
- package/libs/chunk-TNEJXNZA.cjs +22 -0
- package/libs/chunk-TNEJXNZA.cjs.map +1 -0
- package/libs/{chunk-IEB64SWY.js → chunk-U5VA34SU.js} +2 -2
- package/libs/chunk-UGMP72J2.js +8 -0
- package/libs/chunk-UGMP72J2.js.map +1 -0
- package/libs/{chunk-MGPWZRBX.cjs → chunk-URBGDUFN.cjs} +6 -6
- package/libs/{chunk-QKHPHMG2.js → chunk-ZF6Y7W57.js} +5 -5
- package/libs/component-props-50e69975.d.ts +66 -0
- package/libs/components/box/box.css +1 -0
- package/libs/components/box/box.css.map +1 -0
- package/libs/components/box/box.min.css +3 -0
- package/libs/components/breadcrumbs/breadcrumb.cjs +6 -6
- package/libs/components/breadcrumbs/breadcrumb.js +3 -3
- package/libs/components/button.cjs +4 -4
- package/libs/components/button.d.cts +10 -3
- package/libs/components/button.d.ts +10 -3
- package/libs/components/button.js +2 -2
- package/libs/components/card.cjs +7 -7
- package/libs/components/card.d.cts +13 -85
- package/libs/components/card.d.ts +13 -85
- package/libs/components/card.js +2 -2
- package/libs/components/cards/card.css +1 -1
- package/libs/components/cards/card.css.map +1 -1
- package/libs/components/cards/card.min.css +2 -2
- package/libs/components/cluster/cluster.css +1 -0
- package/libs/components/cluster/cluster.css.map +1 -0
- package/libs/components/cluster/cluster.min.css +3 -0
- package/libs/components/dialog/dialog.cjs +7 -7
- package/libs/components/dialog/dialog.js +5 -5
- package/libs/components/form/fields.cjs +4 -4
- package/libs/components/form/fields.js +2 -2
- package/libs/components/form/textarea.cjs +4 -4
- package/libs/components/form/textarea.js +2 -2
- package/libs/components/grid/grid.css +1 -0
- package/libs/components/grid/grid.css.map +1 -0
- package/libs/components/grid/grid.min.css +3 -0
- package/libs/components/heading/heading.cjs +3 -3
- package/libs/components/heading/heading.js +2 -2
- package/libs/components/icons/icon.cjs +4 -4
- package/libs/components/icons/icon.d.cts +2 -2
- package/libs/components/icons/icon.d.ts +2 -2
- package/libs/components/icons/icon.js +2 -2
- package/libs/components/link/link.cjs +6 -6
- package/libs/components/link/link.js +2 -2
- package/libs/components/list/list.cjs +5 -5
- package/libs/components/list/list.js +2 -2
- package/libs/components/modal.cjs +4 -4
- package/libs/components/modal.d.cts +1 -1
- package/libs/components/modal.d.ts +1 -1
- package/libs/components/modal.js +3 -3
- package/libs/components/nav/nav.cjs +7 -7
- package/libs/components/nav/nav.js +3 -3
- package/libs/components/popover/popover.cjs +4 -4
- package/libs/components/popover/popover.d.cts +1 -1
- package/libs/components/popover/popover.d.ts +1 -1
- package/libs/components/popover/popover.js +1 -1
- package/libs/components/stack/stack.css +1 -0
- package/libs/components/stack/stack.css.map +1 -0
- package/libs/components/stack/stack.min.css +3 -0
- package/libs/components/tables/table.cjs +4 -4
- package/libs/components/tables/table.d.cts +2 -2
- package/libs/components/tables/table.d.ts +2 -2
- package/libs/components/tables/table.js +1 -1
- package/libs/components/text/text.cjs +5 -5
- package/libs/components/text/text.js +2 -2
- package/libs/hooks.cjs +4 -4
- package/libs/hooks.js +3 -3
- package/libs/{icons-287fce3a.d.ts → icons-df8e744f.d.ts} +1 -1
- package/libs/icons.cjs +3 -3
- package/libs/icons.d.cts +2 -2
- package/libs/icons.d.ts +2 -2
- package/libs/icons.js +2 -2
- package/libs/index.cjs +74 -73
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +925 -6
- package/libs/index.d.ts +925 -6
- package/libs/index.js +30 -30
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/App.tsx +1 -3
- package/src/components/alert/STYLES.mdx +790 -0
- package/src/components/badge/STYLES.mdx +610 -0
- package/src/components/box/README.mdx +401 -0
- package/src/components/box/STYLES.mdx +360 -0
- package/src/components/box/box.scss +245 -0
- package/src/components/box/box.stories.tsx +395 -0
- package/src/components/box/box.test.tsx +425 -0
- package/src/components/box/box.tsx +170 -0
- package/src/components/box/box.types.ts +166 -0
- package/src/components/breadcrumbs/STYLES.mdx +99 -0
- package/src/components/breadcrumbs/bc-item.tsx +0 -1
- package/src/components/buttons/STYLES.mdx +766 -0
- package/src/components/cards/STYLES.mdx +835 -0
- package/src/components/cards/card.scss +29 -21
- package/src/components/cards/card.tsx +13 -3
- package/src/components/cards/card.types.ts +13 -0
- package/src/components/cluster/README.mdx +595 -0
- package/src/components/cluster/STYLES.mdx +626 -0
- package/src/components/cluster/cluster.scss +86 -0
- package/src/components/cluster/cluster.stories.tsx +385 -0
- package/src/components/cluster/cluster.test.tsx +655 -0
- package/src/components/cluster/cluster.tsx +94 -0
- package/src/components/cluster/cluster.types.ts +75 -0
- package/src/components/details/STYLES.mdx +445 -0
- package/src/components/dialog/STYLES.mdx +888 -0
- package/src/components/flexbox/STYLES.mdx +857 -0
- package/src/components/flexbox/flex.stories.tsx +842 -141
- package/src/components/flexbox/flex.types.ts +25 -6
- package/src/components/form/STYLES.mdx +821 -0
- package/src/components/grid/README.mdx +709 -0
- package/src/components/grid/STYLES.mdx +785 -0
- package/src/components/grid/grid.scss +287 -0
- package/src/components/grid/grid.stories.tsx +486 -0
- package/src/components/grid/grid.test.tsx +981 -0
- package/src/components/grid/grid.tsx +222 -0
- package/src/components/grid/grid.types.ts +344 -0
- package/src/components/icons/STYLES.mdx +56 -0
- package/src/components/icons/components/arrow-right.tsx +0 -5
- package/src/components/images/STYLES.mdx +75 -0
- package/src/components/kit.tsx +8 -4
- package/src/components/layout/STYLES.mdx +556 -0
- package/src/components/link/STYLES.mdx +75 -0
- package/src/components/list/STYLES.mdx +631 -0
- package/src/components/nav/STYLES.mdx +460 -0
- package/src/components/popover/popover.tsx +1 -1
- package/src/components/progress/STYLES.mdx +64 -0
- package/src/components/stack/README.mdx +400 -0
- package/src/components/stack/STYLES.mdx +414 -0
- package/src/components/stack/stack.scss +109 -0
- package/src/components/stack/stack.stories.tsx +559 -0
- package/src/components/stack/stack.test.tsx +426 -0
- package/src/components/stack/stack.tsx +141 -0
- package/src/components/stack/stack.types.ts +133 -0
- package/src/components/tables/table-elements.tsx +1 -1
- package/src/components/tables/table.tsx +2 -2
- package/src/components/tag/STYLES.mdx +105 -0
- package/src/components/text-to-speech/STYLES.mdx +80 -0
- package/src/components/text-to-speech/TextToSpeech.tsx +0 -4
- package/src/components/text-to-speech/useTextToSpeech.tsx +2 -6
- package/src/components/ui.tsx +3 -3
- package/src/decorators/instructions.tsx +22 -18
- package/src/hooks/popover/popover.tsx +1 -1
- package/src/index.scss +5 -1
- package/src/index.ts +305 -12
- package/src/sass/GLOBALS-STYLES.md +631 -0
- package/src/sass/_globals.scss +45 -24
- package/src/styles/box/box.css +220 -0
- package/src/styles/box/box.css.map +1 -0
- package/src/styles/cards/card.css +22 -17
- package/src/styles/cards/card.css.map +1 -1
- package/src/styles/cluster/cluster.css +71 -0
- package/src/styles/cluster/cluster.css.map +1 -0
- package/src/styles/grid/grid.css +238 -0
- package/src/styles/grid/grid.css.map +1 -0
- package/src/styles/index.css +667 -49
- package/src/styles/index.css.map +1 -1
- package/src/styles/stack/stack.css +86 -0
- package/src/styles/stack/stack.css.map +1 -0
- package/src/types/component-props.ts +42 -13
- package/src/types/layout-primitives.ts +48 -0
- package/src/types/shared.ts +10 -26
- package/libs/chunk-23ANBDCR.js.map +0 -1
- package/libs/chunk-5QD3DWFI.js +0 -9
- package/libs/chunk-5QD3DWFI.js.map +0 -1
- package/libs/chunk-6WTC4JXH.cjs +0 -31
- package/libs/chunk-6WTC4JXH.cjs.map +0 -1
- package/libs/chunk-ENTCUJ3A.cjs +0 -13
- package/libs/chunk-ENTCUJ3A.cjs.map +0 -1
- package/libs/chunk-G55UJ53G.cjs.map +0 -1
- package/libs/chunk-HHLNOC5T.js +0 -7
- package/libs/chunk-HHLNOC5T.js.map +0 -1
- package/libs/chunk-KK47SYZI.js +0 -8
- package/libs/chunk-KK47SYZI.js.map +0 -1
- package/libs/chunk-US2I5GI7.cjs +0 -22
- package/libs/chunk-US2I5GI7.cjs.map +0 -1
- package/libs/chunk-W5TKWBFC.cjs +0 -18
- package/libs/chunk-W5TKWBFC.cjs.map +0 -1
- package/libs/chunk-Y2PFDELK.js +0 -8
- package/libs/chunk-Y2PFDELK.js.map +0 -1
- package/libs/component-props-67d978a2.d.ts +0 -38
- /package/libs/{chunk-2NRIP6RB.cjs.map → chunk-2C3YLBWP.cjs.map} +0 -0
- /package/libs/{chunk-NWJDAHP6.cjs.map → chunk-2GJHKWEK.cjs.map} +0 -0
- /package/libs/{chunk-FVROL3V5.js.map → chunk-2JCDEC32.js.map} +0 -0
- /package/libs/{chunk-IRLFZ3OL.js.map → chunk-3XJC4XUG.js.map} +0 -0
- /package/libs/{chunk-E4OSROCA.cjs.map → chunk-5QSNJQVH.cjs.map} +0 -0
- /package/libs/{chunk-O3JIHC5M.cjs.map → chunk-6BUJZ4DJ.cjs.map} +0 -0
- /package/libs/{chunk-WXBFBWYF.cjs.map → chunk-AFINOD2L.cjs.map} +0 -0
- /package/libs/{chunk-HRRHPLER.js.map → chunk-AWZLSWDO.js.map} +0 -0
- /package/libs/{chunk-CWRNJA4P.js.map → chunk-DIJBIOFE.js.map} +0 -0
- /package/libs/{chunk-GUJSMQ3V.cjs.map → chunk-EKJYOCLY.cjs.map} +0 -0
- /package/libs/{chunk-X5RKCLDC.cjs.map → chunk-F64GE6RG.cjs.map} +0 -0
- /package/libs/{chunk-5RAWNUVD.js.map → chunk-IBUTNPTQ.js.map} +0 -0
- /package/libs/{chunk-ZFJ4U45S.js.map → chunk-KDMX3FAW.js.map} +0 -0
- /package/libs/{chunk-DYFAUAB7.cjs.map → chunk-LXODKKA3.cjs.map} +0 -0
- /package/libs/{chunk-IQ76HGVP.js.map → chunk-MBWI67UT.js.map} +0 -0
- /package/libs/{chunk-O5XAJ7BY.cjs.map → chunk-NCGVF2QS.cjs.map} +0 -0
- /package/libs/{chunk-W2UIN7EV.cjs.map → chunk-NPWHQVYB.cjs.map} +0 -0
- /package/libs/{chunk-43TK2ICH.js.map → chunk-PMWL5XZ4.js.map} +0 -0
- /package/libs/{chunk-KVKQLRJG.js.map → chunk-TF3GQKOY.js.map} +0 -0
- /package/libs/{chunk-IEB64SWY.js.map → chunk-U5VA34SU.js.map} +0 -0
- /package/libs/{chunk-MGPWZRBX.cjs.map → chunk-URBGDUFN.cjs.map} +0 -0
- /package/libs/{chunk-QKHPHMG2.js.map → chunk-ZF6Y7W57.js.map} +0 -0
|
@@ -0,0 +1,821 @@
|
|
|
1
|
+
import { Meta } from "@storybook/addon-docs/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.REACT Components/Forms/Styles" />
|
|
4
|
+
|
|
5
|
+
# Form Styles
|
|
6
|
+
|
|
7
|
+
Comprehensive form control styling system with CSS custom properties for inputs,
|
|
8
|
+
textareas, selects, and form layouts.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
The fpkit form styling system provides consistent, accessible form controls with
|
|
13
|
+
extensive customization through CSS variables. All form elements support focus
|
|
14
|
+
states, disabled states, placeholder styling, and validation indicators.
|
|
15
|
+
|
|
16
|
+
### Key Features
|
|
17
|
+
|
|
18
|
+
- **Universal input styling** - Text inputs, textareas, and selects with
|
|
19
|
+
consistent appearance
|
|
20
|
+
- **Custom select arrows** - SVG-based dropdown indicator
|
|
21
|
+
- **Accessible focus indicators** - Visible focus states for keyboard navigation
|
|
22
|
+
- **Disabled state styling** - Visual feedback for disabled form controls
|
|
23
|
+
- **Required field indicators** - ARIA-based required field styling
|
|
24
|
+
- **Placeholder customization** - Full control over placeholder appearance
|
|
25
|
+
- **Flexible layouts** - Column or row-based form layouts
|
|
26
|
+
- **CSS custom properties** - Extensive theming via CSS variables
|
|
27
|
+
- **Rem-based sizing** - All measurements use rem units (1rem = 16px)
|
|
28
|
+
|
|
29
|
+
## CSS Custom Properties
|
|
30
|
+
|
|
31
|
+
### Input Properties
|
|
32
|
+
|
|
33
|
+
Core styling variables for inputs, textareas, and selects:
|
|
34
|
+
|
|
35
|
+
```css
|
|
36
|
+
:root {
|
|
37
|
+
/* Appearance */
|
|
38
|
+
--input-appearance: none; /* Remove browser defaults */
|
|
39
|
+
--input-bg: inherit; /* Background color */
|
|
40
|
+
--input-border-color: gray; /* Border/outline color */
|
|
41
|
+
|
|
42
|
+
/* Borders & Outlines */
|
|
43
|
+
--input-border: none; /* Inner border */
|
|
44
|
+
--input-outline: thin solid var(--input-border-color); /* Outer outline */
|
|
45
|
+
--input-radius: var(--radius); /* Border radius */
|
|
46
|
+
|
|
47
|
+
/* Spacing */
|
|
48
|
+
--input-padding-inline: 0.6rem; /* Horizontal padding (9.6px) */
|
|
49
|
+
--input-padding-block: 0.4rem; /* Vertical padding (6.4px) */
|
|
50
|
+
|
|
51
|
+
/* Typography */
|
|
52
|
+
--input-fs: var(--fs); /* Font size */
|
|
53
|
+
|
|
54
|
+
/* Dimensions */
|
|
55
|
+
--input-width: clamp(200px, 100%, 500px); /* Responsive width */
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Focus State Properties
|
|
60
|
+
|
|
61
|
+
```css
|
|
62
|
+
:root {
|
|
63
|
+
/* Focus indicators */
|
|
64
|
+
--input-focus-outline: medium solid var(--input-border-color);
|
|
65
|
+
--input-focus-outline-offset: 0;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Disabled State Properties
|
|
70
|
+
|
|
71
|
+
```css
|
|
72
|
+
:root {
|
|
73
|
+
/* Disabled styling */
|
|
74
|
+
--input-disabled-bg: #f5f5f5;
|
|
75
|
+
--input-disabled-opacity: 0.6;
|
|
76
|
+
--input-disabled-cursor: not-allowed;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Placeholder Properties
|
|
81
|
+
|
|
82
|
+
```css
|
|
83
|
+
:root {
|
|
84
|
+
/* Placeholder styling */
|
|
85
|
+
--placeholder-color: gray;
|
|
86
|
+
--placeholder-style: italic;
|
|
87
|
+
--placeholder-fs: smaller;
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Form Layout Properties
|
|
92
|
+
|
|
93
|
+
```css
|
|
94
|
+
:root {
|
|
95
|
+
/* Form layout */
|
|
96
|
+
--form-direction: column; /* Form flex direction */
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Select Properties
|
|
101
|
+
|
|
102
|
+
```css
|
|
103
|
+
:root {
|
|
104
|
+
/* Custom select arrow */
|
|
105
|
+
--select-arrow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><polyline points='6,9 10,13 14,9' stroke='%23000000' stroke-width='1.5' fill='none' /></svg>");
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Customizing Form Styles
|
|
110
|
+
|
|
111
|
+
Override CSS variables globally or per-element:
|
|
112
|
+
|
|
113
|
+
```css
|
|
114
|
+
/* Global customization */
|
|
115
|
+
:root {
|
|
116
|
+
--input-border-color: #0066cc;
|
|
117
|
+
--input-padding-inline: 1rem;
|
|
118
|
+
--input-radius: 0.5rem;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* Per-element customization */
|
|
122
|
+
.custom-input {
|
|
123
|
+
--input-bg: #f9f9f9;
|
|
124
|
+
--input-border-color: #333;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Or inline:
|
|
129
|
+
|
|
130
|
+
```html
|
|
131
|
+
<input type="text" style="--input-bg: #f0f0f0; --input-border-color: blue" />
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Form Structure
|
|
135
|
+
|
|
136
|
+
### Basic Form
|
|
137
|
+
|
|
138
|
+
Standard vertical form layout:
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<form>
|
|
142
|
+
<div>
|
|
143
|
+
<label for="name">Name</label>
|
|
144
|
+
<input type="text" id="name" name="name" />
|
|
145
|
+
</div>
|
|
146
|
+
<div>
|
|
147
|
+
<label for="email">Email</label>
|
|
148
|
+
<input type="email" id="email" name="email" />
|
|
149
|
+
</div>
|
|
150
|
+
<button type="submit">Submit</button>
|
|
151
|
+
</form>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**CSS Applied:**
|
|
155
|
+
|
|
156
|
+
```css
|
|
157
|
+
form {
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: column; /* Vertical layout */
|
|
160
|
+
gap: 1rem; /* 16px spacing between fields */
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
form > div {
|
|
164
|
+
display: flex;
|
|
165
|
+
gap: 1rem;
|
|
166
|
+
flex-direction: column; /* Vertical label/input pairing */
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
form label {
|
|
170
|
+
display: block;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Horizontal Form Layout
|
|
175
|
+
|
|
176
|
+
Change form direction to row:
|
|
177
|
+
|
|
178
|
+
```html
|
|
179
|
+
<form style="--form-direction: row">
|
|
180
|
+
<div>
|
|
181
|
+
<label for="search">Search</label>
|
|
182
|
+
<input type="text" id="search" name="search" />
|
|
183
|
+
</div>
|
|
184
|
+
<button type="submit">Go</button>
|
|
185
|
+
</form>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Input Types
|
|
189
|
+
|
|
190
|
+
### Text Input
|
|
191
|
+
|
|
192
|
+
Standard text input with outline:
|
|
193
|
+
|
|
194
|
+
```html
|
|
195
|
+
<input type="text" placeholder="Enter text" />
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**CSS Applied:**
|
|
199
|
+
|
|
200
|
+
```css
|
|
201
|
+
input[type]:not([type="checkbox"], [type="radio"]) {
|
|
202
|
+
-webkit-appearance: none;
|
|
203
|
+
-moz-appearance: none;
|
|
204
|
+
appearance: none;
|
|
205
|
+
width: clamp(200px, 100%, 500px);
|
|
206
|
+
border: none;
|
|
207
|
+
outline: thin solid gray;
|
|
208
|
+
padding-inline: 0.6rem;
|
|
209
|
+
padding-block: 0.4rem;
|
|
210
|
+
border-radius: var(--radius);
|
|
211
|
+
background-color: #fff;
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Note:** Checkboxes and radios are excluded from these styles to preserve their
|
|
216
|
+
native appearance.
|
|
217
|
+
|
|
218
|
+
### Textarea
|
|
219
|
+
|
|
220
|
+
Multi-line text input:
|
|
221
|
+
|
|
222
|
+
```html
|
|
223
|
+
<textarea placeholder="Enter message" rows="4"></textarea>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**CSS:** Same as text input, with resizable height.
|
|
227
|
+
|
|
228
|
+
### Select Dropdown
|
|
229
|
+
|
|
230
|
+
Dropdown with custom arrow:
|
|
231
|
+
|
|
232
|
+
```html
|
|
233
|
+
<select>
|
|
234
|
+
<option value="">Choose an option</option>
|
|
235
|
+
<option value="1">Option 1</option>
|
|
236
|
+
<option value="2">Option 2</option>
|
|
237
|
+
<option value="3">Option 3</option>
|
|
238
|
+
</select>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**CSS Applied:**
|
|
242
|
+
|
|
243
|
+
```css
|
|
244
|
+
select {
|
|
245
|
+
border: thin solid gray; /* Border instead of outline */
|
|
246
|
+
outline: none;
|
|
247
|
+
-webkit-appearance: none;
|
|
248
|
+
-moz-appearance: none;
|
|
249
|
+
appearance: none;
|
|
250
|
+
background: var(--select-arrow) no-repeat;
|
|
251
|
+
background-position: right 0.5rem top 50%;
|
|
252
|
+
padding-inline-end: 0; /* Remove right padding for arrow space */
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Custom Arrow:** The select uses an SVG data URL for the dropdown arrow,
|
|
257
|
+
positioned on the right side.
|
|
258
|
+
|
|
259
|
+
## Input States
|
|
260
|
+
|
|
261
|
+
### Default State
|
|
262
|
+
|
|
263
|
+
Standard input appearance:
|
|
264
|
+
|
|
265
|
+
```html
|
|
266
|
+
<input type="text" value="Default value" />
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Focus State
|
|
270
|
+
|
|
271
|
+
Enhanced outline on focus:
|
|
272
|
+
|
|
273
|
+
```html
|
|
274
|
+
<input type="text" placeholder="Focus me" />
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**CSS:**
|
|
278
|
+
|
|
279
|
+
```css
|
|
280
|
+
input:focus-visible,
|
|
281
|
+
input:focus {
|
|
282
|
+
outline: medium solid var(--input-border-color);
|
|
283
|
+
outline-offset: 0;
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Customization:**
|
|
288
|
+
|
|
289
|
+
```html
|
|
290
|
+
<input
|
|
291
|
+
type="text"
|
|
292
|
+
style="--input-focus-outline: 3px solid blue; --input-focus-outline-offset: 2px"
|
|
293
|
+
/>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Disabled State
|
|
297
|
+
|
|
298
|
+
Grayed-out appearance with strikethrough text:
|
|
299
|
+
|
|
300
|
+
```html
|
|
301
|
+
<input type="text" value="Disabled" disabled />
|
|
302
|
+
<input type="text" value="Disabled" aria-disabled="true" />
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**CSS:**
|
|
306
|
+
|
|
307
|
+
```css
|
|
308
|
+
input[aria-disabled="true"],
|
|
309
|
+
input:disabled {
|
|
310
|
+
--input-border-color: lightgray;
|
|
311
|
+
background-color: #f5f5f5;
|
|
312
|
+
opacity: 0.6;
|
|
313
|
+
cursor: not-allowed;
|
|
314
|
+
text-transform: capitalize;
|
|
315
|
+
text-decoration: line-through;
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Required Fields
|
|
320
|
+
|
|
321
|
+
Visual indicator for required fields:
|
|
322
|
+
|
|
323
|
+
```html
|
|
324
|
+
<input type="text" aria-required="true" placeholder="Required field" />
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**CSS:**
|
|
328
|
+
|
|
329
|
+
```css
|
|
330
|
+
input[aria-required="true"]::placeholder {
|
|
331
|
+
color: var(--color-required, gray);
|
|
332
|
+
font-weight: 600;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
input[aria-required="true"]::placeholder::after {
|
|
336
|
+
content: "* ";
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Note:** The asterisk (\*) is automatically appended to the placeholder text
|
|
341
|
+
for required fields.
|
|
342
|
+
|
|
343
|
+
## Placeholder Styling
|
|
344
|
+
|
|
345
|
+
### Default Placeholder
|
|
346
|
+
|
|
347
|
+
Italic, gray, smaller text:
|
|
348
|
+
|
|
349
|
+
```html
|
|
350
|
+
<input type="text" placeholder="Enter your name" />
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**CSS:**
|
|
354
|
+
|
|
355
|
+
```css
|
|
356
|
+
input::placeholder {
|
|
357
|
+
color: gray;
|
|
358
|
+
font-style: italic;
|
|
359
|
+
font-size: smaller;
|
|
360
|
+
text-transform: capitalize;
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Custom Placeholder
|
|
365
|
+
|
|
366
|
+
```html
|
|
367
|
+
<input
|
|
368
|
+
type="text"
|
|
369
|
+
placeholder="Custom placeholder"
|
|
370
|
+
style="--placeholder-color: blue; --placeholder-style: normal; --placeholder-fs: 1rem"
|
|
371
|
+
/>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Real-World Examples
|
|
375
|
+
|
|
376
|
+
### Login Form
|
|
377
|
+
|
|
378
|
+
```html
|
|
379
|
+
<form>
|
|
380
|
+
<div>
|
|
381
|
+
<label for="username">Username</label>
|
|
382
|
+
<input type="text" id="username" name="username" aria-required="true" />
|
|
383
|
+
</div>
|
|
384
|
+
<div>
|
|
385
|
+
<label for="password">Password</label>
|
|
386
|
+
<input type="password" id="password" name="password" aria-required="true" />
|
|
387
|
+
</div>
|
|
388
|
+
<div>
|
|
389
|
+
<label>
|
|
390
|
+
<input type="checkbox" name="remember" />
|
|
391
|
+
Remember me
|
|
392
|
+
</label>
|
|
393
|
+
</div>
|
|
394
|
+
<button type="submit">Log In</button>
|
|
395
|
+
</form>
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Contact Form
|
|
399
|
+
|
|
400
|
+
```html
|
|
401
|
+
<form style="--input-border-color: #0066cc">
|
|
402
|
+
<div>
|
|
403
|
+
<label for="name">Name *</label>
|
|
404
|
+
<input type="text" id="name" name="name" aria-required="true" />
|
|
405
|
+
</div>
|
|
406
|
+
<div>
|
|
407
|
+
<label for="email">Email *</label>
|
|
408
|
+
<input type="email" id="email" name="email" aria-required="true" />
|
|
409
|
+
</div>
|
|
410
|
+
<div>
|
|
411
|
+
<label for="subject">Subject</label>
|
|
412
|
+
<select id="subject" name="subject">
|
|
413
|
+
<option value="">Choose a subject</option>
|
|
414
|
+
<option value="support">Support</option>
|
|
415
|
+
<option value="sales">Sales</option>
|
|
416
|
+
<option value="feedback">Feedback</option>
|
|
417
|
+
</select>
|
|
418
|
+
</div>
|
|
419
|
+
<div>
|
|
420
|
+
<label for="message">Message *</label>
|
|
421
|
+
<textarea
|
|
422
|
+
id="message"
|
|
423
|
+
name="message"
|
|
424
|
+
rows="5"
|
|
425
|
+
aria-required="true"
|
|
426
|
+
></textarea>
|
|
427
|
+
</div>
|
|
428
|
+
<button type="submit">Send Message</button>
|
|
429
|
+
</form>
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Search Form (Horizontal)
|
|
433
|
+
|
|
434
|
+
```html
|
|
435
|
+
<form style="--form-direction: row; align-items: flex-end">
|
|
436
|
+
<div style="flex: 1">
|
|
437
|
+
<label for="search">Search</label>
|
|
438
|
+
<input
|
|
439
|
+
type="search"
|
|
440
|
+
id="search"
|
|
441
|
+
name="q"
|
|
442
|
+
placeholder="Search..."
|
|
443
|
+
style="--input-width: 100%"
|
|
444
|
+
/>
|
|
445
|
+
</div>
|
|
446
|
+
<button type="submit">Search</button>
|
|
447
|
+
</form>
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Inline Label Form
|
|
451
|
+
|
|
452
|
+
```html
|
|
453
|
+
<form>
|
|
454
|
+
<div style="--form-direction: row; align-items: center">
|
|
455
|
+
<label for="email" style="width: 8rem">Email Address</label>
|
|
456
|
+
<input type="email" id="email" name="email" style="flex: 1" />
|
|
457
|
+
</div>
|
|
458
|
+
<div style="--form-direction: row; align-items: center">
|
|
459
|
+
<label for="phone" style="width: 8rem">Phone Number</label>
|
|
460
|
+
<input type="tel" id="phone" name="phone" style="flex: 1" />
|
|
461
|
+
</div>
|
|
462
|
+
<button type="submit">Submit</button>
|
|
463
|
+
</form>
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Form with Fieldset
|
|
467
|
+
|
|
468
|
+
```html
|
|
469
|
+
<form>
|
|
470
|
+
<fieldset
|
|
471
|
+
style="border: 1px solid gray; padding: 1rem; border-radius: 0.5rem"
|
|
472
|
+
>
|
|
473
|
+
<legend>Personal Information</legend>
|
|
474
|
+
<div>
|
|
475
|
+
<label for="firstName">First Name</label>
|
|
476
|
+
<input type="text" id="firstName" name="firstName" />
|
|
477
|
+
</div>
|
|
478
|
+
<div>
|
|
479
|
+
<label for="lastName">Last Name</label>
|
|
480
|
+
<input type="text" id="lastName" name="lastName" />
|
|
481
|
+
</div>
|
|
482
|
+
</fieldset>
|
|
483
|
+
<button type="submit">Continue</button>
|
|
484
|
+
</form>
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Multi-Column Form
|
|
488
|
+
|
|
489
|
+
```html
|
|
490
|
+
<form>
|
|
491
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem">
|
|
492
|
+
<div>
|
|
493
|
+
<label for="firstName">First Name</label>
|
|
494
|
+
<input type="text" id="firstName" name="firstName" />
|
|
495
|
+
</div>
|
|
496
|
+
<div>
|
|
497
|
+
<label for="lastName">Last Name</label>
|
|
498
|
+
<input type="text" id="lastName" name="lastName" />
|
|
499
|
+
</div>
|
|
500
|
+
</div>
|
|
501
|
+
<div>
|
|
502
|
+
<label for="address">Address</label>
|
|
503
|
+
<input type="text" id="address" name="address" />
|
|
504
|
+
</div>
|
|
505
|
+
<button type="submit">Submit</button>
|
|
506
|
+
</form>
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Form with Validation States
|
|
510
|
+
|
|
511
|
+
```html
|
|
512
|
+
<form>
|
|
513
|
+
<div>
|
|
514
|
+
<label for="valid">Valid Input</label>
|
|
515
|
+
<input
|
|
516
|
+
type="text"
|
|
517
|
+
id="valid"
|
|
518
|
+
value="Valid value"
|
|
519
|
+
style="--input-border-color: green"
|
|
520
|
+
/>
|
|
521
|
+
</div>
|
|
522
|
+
<div>
|
|
523
|
+
<label for="invalid">Invalid Input</label>
|
|
524
|
+
<input
|
|
525
|
+
type="text"
|
|
526
|
+
id="invalid"
|
|
527
|
+
value="Invalid value"
|
|
528
|
+
style="--input-border-color: red"
|
|
529
|
+
aria-invalid="true"
|
|
530
|
+
/>
|
|
531
|
+
<small style="color: red">This field has an error.</small>
|
|
532
|
+
</div>
|
|
533
|
+
<button type="submit">Submit</button>
|
|
534
|
+
</form>
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
## Accessibility Considerations
|
|
538
|
+
|
|
539
|
+
### Labels
|
|
540
|
+
|
|
541
|
+
Always associate labels with inputs:
|
|
542
|
+
|
|
543
|
+
```html
|
|
544
|
+
<!-- Good: Explicit association -->
|
|
545
|
+
<label for="email">Email</label>
|
|
546
|
+
<input type="email" id="email" name="email" />
|
|
547
|
+
|
|
548
|
+
<!-- Good: Implicit association -->
|
|
549
|
+
<label>
|
|
550
|
+
Email
|
|
551
|
+
<input type="email" name="email" />
|
|
552
|
+
</label>
|
|
553
|
+
|
|
554
|
+
<!-- Bad: No association -->
|
|
555
|
+
<label>Email</label>
|
|
556
|
+
<input type="email" name="email" />
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Required Fields
|
|
560
|
+
|
|
561
|
+
Use `aria-required` for screen reader support:
|
|
562
|
+
|
|
563
|
+
```html
|
|
564
|
+
<label for="name">Name *</label>
|
|
565
|
+
<input type="text" id="name" name="name" aria-required="true" required />
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**Note:** Include both `aria-required="true"` (for styling) and `required` (for
|
|
569
|
+
HTML5 validation).
|
|
570
|
+
|
|
571
|
+
### Error Messages
|
|
572
|
+
|
|
573
|
+
Associate error messages with inputs:
|
|
574
|
+
|
|
575
|
+
```html
|
|
576
|
+
<label for="email">Email</label>
|
|
577
|
+
<input
|
|
578
|
+
type="email"
|
|
579
|
+
id="email"
|
|
580
|
+
name="email"
|
|
581
|
+
aria-invalid="true"
|
|
582
|
+
aria-describedby="email-error"
|
|
583
|
+
/>
|
|
584
|
+
<span id="email-error" role="alert">Please enter a valid email address.</span>
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### Focus Indicators
|
|
588
|
+
|
|
589
|
+
Ensure visible focus indicators (automatic with `:focus-visible`):
|
|
590
|
+
|
|
591
|
+
```css
|
|
592
|
+
input:focus-visible {
|
|
593
|
+
outline: medium solid var(--input-border-color);
|
|
594
|
+
}
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
**Never remove focus outlines** without providing alternatives.
|
|
598
|
+
|
|
599
|
+
### Disabled Fields
|
|
600
|
+
|
|
601
|
+
Use proper disabled attributes:
|
|
602
|
+
|
|
603
|
+
```html
|
|
604
|
+
<!-- Native disabled (recommended) -->
|
|
605
|
+
<input type="text" disabled />
|
|
606
|
+
|
|
607
|
+
<!-- ARIA disabled (for custom behavior) -->
|
|
608
|
+
<input type="text" aria-disabled="true" />
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Keyboard Navigation
|
|
612
|
+
|
|
613
|
+
All form controls are keyboard-accessible by default:
|
|
614
|
+
|
|
615
|
+
- **Tab** - Move to next field
|
|
616
|
+
- **Shift+Tab** - Move to previous field
|
|
617
|
+
- **Enter** - Submit form
|
|
618
|
+
- **Space** - Toggle checkbox/radio
|
|
619
|
+
|
|
620
|
+
## Form Validation Styling
|
|
621
|
+
|
|
622
|
+
### Valid State
|
|
623
|
+
|
|
624
|
+
```html
|
|
625
|
+
<input
|
|
626
|
+
type="email"
|
|
627
|
+
value="user@example.com"
|
|
628
|
+
style="--input-border-color: #28a745"
|
|
629
|
+
/>
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Invalid State
|
|
633
|
+
|
|
634
|
+
```html
|
|
635
|
+
<input
|
|
636
|
+
type="email"
|
|
637
|
+
value="invalid-email"
|
|
638
|
+
aria-invalid="true"
|
|
639
|
+
style="--input-border-color: #dc3545"
|
|
640
|
+
/>
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Custom Validation Colors
|
|
644
|
+
|
|
645
|
+
```css
|
|
646
|
+
:root {
|
|
647
|
+
--input-valid-color: #28a745;
|
|
648
|
+
--input-invalid-color: #dc3545;
|
|
649
|
+
}
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
```html
|
|
653
|
+
<input type="text" style="--input-border-color: var(--input-valid-color)" />
|
|
654
|
+
<input
|
|
655
|
+
type="text"
|
|
656
|
+
aria-invalid="true"
|
|
657
|
+
style="--input-border-color: var(--input-invalid-color)"
|
|
658
|
+
/>
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
## CSS Variable Naming Convention
|
|
662
|
+
|
|
663
|
+
All form CSS variables follow specific patterns:
|
|
664
|
+
|
|
665
|
+
### Property Mapping
|
|
666
|
+
|
|
667
|
+
| Category | Variable Pattern | Example |
|
|
668
|
+
| ---------------- | ---------------------------- | ---------------------------------------------- |
|
|
669
|
+
| **Input Core** | `--input-{property}` | `--input-bg`, `--input-border` |
|
|
670
|
+
| **Input States** | `--input-{state}-{property}` | `--input-focus-outline`, `--input-disabled-bg` |
|
|
671
|
+
| **Placeholder** | `--placeholder-{property}` | `--placeholder-color`, `--placeholder-fs` |
|
|
672
|
+
| **Form Layout** | `--form-{property}` | `--form-direction` |
|
|
673
|
+
| **Select** | `--select-{property}` | `--select-arrow` |
|
|
674
|
+
|
|
675
|
+
### Common Variables Quick Reference
|
|
676
|
+
|
|
677
|
+
```css
|
|
678
|
+
/* Input Appearance */
|
|
679
|
+
--input-bg /* Background color */
|
|
680
|
+
--input-border /* Inner border */
|
|
681
|
+
--input-outline /* Outer outline */
|
|
682
|
+
--input-border-color /* Border/outline color */
|
|
683
|
+
--input-radius /* Border radius */
|
|
684
|
+
--input-appearance /* Browser appearance reset */
|
|
685
|
+
|
|
686
|
+
/* Input Spacing */
|
|
687
|
+
--input-padding-inline /* Horizontal padding */
|
|
688
|
+
--input-padding-block /* Vertical padding */
|
|
689
|
+
--input-width /* Input width */
|
|
690
|
+
|
|
691
|
+
/* Input Typography */
|
|
692
|
+
--input-fs /* Font size */
|
|
693
|
+
|
|
694
|
+
/* Focus State */
|
|
695
|
+
--input-focus-outline /* Focus outline style */
|
|
696
|
+
--input-focus-outline-offset /* Focus outline offset */
|
|
697
|
+
|
|
698
|
+
/* Disabled State */
|
|
699
|
+
--input-disabled-bg /* Disabled background */
|
|
700
|
+
--input-disabled-opacity /* Disabled opacity */
|
|
701
|
+
--input-disabled-cursor /* Disabled cursor */
|
|
702
|
+
|
|
703
|
+
/* Placeholder */
|
|
704
|
+
--placeholder-color /* Placeholder text color */
|
|
705
|
+
--placeholder-style /* Placeholder font style */
|
|
706
|
+
--placeholder-fs /* Placeholder font size */
|
|
707
|
+
|
|
708
|
+
/* Form Layout */
|
|
709
|
+
--form-direction /* Form flex direction */
|
|
710
|
+
|
|
711
|
+
/* Select */
|
|
712
|
+
--select-arrow /* Custom dropdown arrow */
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
## Browser Support
|
|
716
|
+
|
|
717
|
+
The form styles use modern CSS features:
|
|
718
|
+
|
|
719
|
+
- **CSS Custom Properties:** All modern browsers (IE11 not supported)
|
|
720
|
+
- **`:focus-visible`:** Chrome 86+, Firefox 85+, Safari 15.4+
|
|
721
|
+
- **`appearance: none`:** All modern browsers
|
|
722
|
+
- **`clamp()`:** Chrome 79+, Firefox 75+, Safari 13.1+
|
|
723
|
+
- **Logical properties** (`padding-inline`, `padding-block`): Chrome 87+,
|
|
724
|
+
Firefox 66+, Safari 14.1+
|
|
725
|
+
- **`::placeholder`:** All modern browsers
|
|
726
|
+
- **SVG data URLs:** All modern browsers
|
|
727
|
+
|
|
728
|
+
### Fallbacks
|
|
729
|
+
|
|
730
|
+
For older browsers without `clamp()`:
|
|
731
|
+
|
|
732
|
+
```css
|
|
733
|
+
/* Fallback */
|
|
734
|
+
--input-width: 100%;
|
|
735
|
+
max-width: 500px;
|
|
736
|
+
min-width: 200px;
|
|
737
|
+
|
|
738
|
+
/* Modern */
|
|
739
|
+
--input-width: clamp(200px, 100%, 500px);
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
## Performance Tips
|
|
743
|
+
|
|
744
|
+
### Avoid Over-Styling
|
|
745
|
+
|
|
746
|
+
Style only what's necessary:
|
|
747
|
+
|
|
748
|
+
```html
|
|
749
|
+
<!-- Good: Uses defaults -->
|
|
750
|
+
<input type="text" />
|
|
751
|
+
|
|
752
|
+
<!-- Avoid: Unnecessary customization -->
|
|
753
|
+
<input
|
|
754
|
+
type="text"
|
|
755
|
+
style="--input-bg: white; --input-outline: thin solid gray"
|
|
756
|
+
/>
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
### Use CSS Classes
|
|
760
|
+
|
|
761
|
+
Create reusable form classes:
|
|
762
|
+
|
|
763
|
+
```css
|
|
764
|
+
.form-control-lg {
|
|
765
|
+
--input-padding-inline: 1rem;
|
|
766
|
+
--input-padding-block: 0.75rem;
|
|
767
|
+
--input-fs: 1.125rem;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
.form-control-sm {
|
|
771
|
+
--input-padding-inline: 0.5rem;
|
|
772
|
+
--input-padding-block: 0.25rem;
|
|
773
|
+
--input-fs: 0.875rem;
|
|
774
|
+
}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
```html
|
|
778
|
+
<input type="text" class="form-control-lg" />
|
|
779
|
+
<input type="text" class="form-control-sm" />
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### Minimize Select Arrow Customization
|
|
783
|
+
|
|
784
|
+
The default select arrow works well for most cases. Only customize when
|
|
785
|
+
necessary:
|
|
786
|
+
|
|
787
|
+
```css
|
|
788
|
+
/* Custom arrow color (if needed) */
|
|
789
|
+
--select-arrow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><polyline points='6,9 10,13 14,9' stroke='%230066cc' stroke-width='1.5' fill='none' /></svg>");
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
## Migration from Other Systems
|
|
793
|
+
|
|
794
|
+
### From Tailwind CSS
|
|
795
|
+
|
|
796
|
+
| Tailwind | fpkit Form |
|
|
797
|
+
| -------------------------------------------------- | ------------------------------------ |
|
|
798
|
+
| `class="border border-gray-300 rounded px-3 py-2"` | Default `<input>` styles |
|
|
799
|
+
| `class="focus:ring focus:border-blue-500"` | `--input-focus-outline` |
|
|
800
|
+
| `class="disabled:bg-gray-100"` | `disabled` or `aria-disabled="true"` |
|
|
801
|
+
| `class="placeholder-gray-400"` | `--placeholder-color` |
|
|
802
|
+
| `class="w-full"` | `style="--input-width: 100%"` |
|
|
803
|
+
|
|
804
|
+
### From Bootstrap
|
|
805
|
+
|
|
806
|
+
| Bootstrap | fpkit Form |
|
|
807
|
+
| ------------------------------- | ------------------------------------ |
|
|
808
|
+
| `class="form-control"` | Default `<input>` styles |
|
|
809
|
+
| `class="form-control:focus"` | Automatic focus styles |
|
|
810
|
+
| `class="form-control:disabled"` | `disabled` or `aria-disabled="true"` |
|
|
811
|
+
| `class="form-select"` | Default `<select>` styles |
|
|
812
|
+
|
|
813
|
+
## Related Resources
|
|
814
|
+
|
|
815
|
+
- **React Component** - See form component README for React API
|
|
816
|
+
- **MDN: Forms** -
|
|
817
|
+
[https://developer.mozilla.org/en-US/docs/Learn/Forms](https://developer.mozilla.org/en-US/docs/Learn/Forms)
|
|
818
|
+
- **W3C: Form Accessibility** -
|
|
819
|
+
[https://www.w3.org/WAI/tutorials/forms/](https://www.w3.org/WAI/tutorials/forms/)
|
|
820
|
+
- **CSS Custom Properties** -
|
|
821
|
+
[https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
|