defuss-shadcn / Website / Account & States / feedback-form
Built with: CSS
Feedback FormBLK
Collects a rating or written feedback about an experience - faces and topics on a card, a 0–10 recommendation scale, or "was this helpful?" inline. Part of the Account & States blocks.
On this page (4)
§Default
Five faces (radios named "Very bad" … "Great" - the emoji are never the only name; the choice gets color and a ring), topic chips (checkboxes) and a comment.
§NPS
data-variant='nps': a 0–10 radio scale with the meaning of both ends written out.
§Was this helpful?
data-variant='inline': Yes / No as radios - choosing one swaps the question for a thank-you (role="status") through :has(:checked), no script. Click one.
§CSS view file
/* -- Feedback Form (website · Account & States) --------------------------- Collects a rating or written feedback about an experience - faces and topics on a card, a 0–10 recommendation scale, or "was this helpful?" inline. */@layer components { /* every box in the block measures border-box - the same on any page */ :where(.mk-feedback-form, .mk-feedback-form *, .mk-feedback-form ::before, .mk-feedback-form ::after) { box-sizing: border-box; } .mk-feedback-form { display: grid; gap: 1.25rem; width: 100%; max-width: 30rem; padding: 1.5rem; border: 1px solid var(--border); border-radius: var(--radius-xl); background: var(--card); color: var(--card-foreground); & form { display: grid; gap: 1.25rem; } & h2 { margin: 0; font-size: 1.125rem; font-weight: 600; } & fieldset { display: grid; gap: 0.625rem; margin: 0; padding: 0; border: 0; min-width: 0; } & legend { margin-block-end: 0.625rem; padding: 0; font-size: 0.9375rem; font-weight: 500; } } .mk-feedback-form-faces { display: flex; justify-content: space-between; gap: 0.5rem; & label { position: relative; display: grid; place-items: center; width: 3rem; height: 3rem; border-radius: 50%; background: var(--muted); font-size: 1.5rem; cursor: pointer; filter: grayscale(1); opacity: 0.75; transition: scale 150ms ease, filter 150ms ease, opacity 150ms ease; } & input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; } & label:hover { filter: none; opacity: 1; } & label:has(:checked) { filter: none; opacity: 1; scale: 1.15; box-shadow: 0 0 0 2px var(--primary); } & label:has(:focus-visible) { outline: 2px solid var(--ring); outline-offset: 3px; } } .mk-feedback-form-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; & label { position: relative; padding: 0.375rem 0.875rem; border: 1px solid var(--border); border-radius: 999px; font-size: 0.875rem; cursor: pointer; } & input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; } & label:has(:checked) { border-color: var(--primary); background: var(--primary); color: var(--primary-foreground); } & label:has(:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; } } .mk-feedback-form[data-variant="nps"] { max-width: 40rem; } .mk-feedback-form-scale { display: grid; grid-template-columns: repeat(11, minmax(0, 1fr)); gap: 0.25rem; & label { position: relative; display: grid; place-items: center; height: 2.5rem; border: 1px solid var(--border); border-radius: var(--radius-md); font-size: 0.875rem; font-weight: 600; font-variant-numeric: tabular-nums; cursor: pointer; } & input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; } & label:hover { background: var(--accent); } & label:has(:checked) { border-color: var(--primary); background: var(--primary); color: var(--primary-foreground); } & label:has(:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; } } .mk-feedback-form-ends { display: flex; justify-content: space-between; color: var(--muted-foreground); font-size: 0.75rem; } .mk-feedback-form[data-variant="inline"] { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1rem; max-width: none; padding: 1rem 1.25rem; border-style: dashed; background: transparent; & fieldset { display: flex; align-items: center; gap: 0.75rem; } & legend { float: left; margin: 0; } & .mk-feedback-form-yesno { display: flex; gap: 0.5rem; } & .mk-feedback-form-yesno label { position: relative; display: inline-flex; align-items: center; gap: 0.375rem; height: 2rem; padding-inline: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius-md); font-size: 0.875rem; font-weight: 500; cursor: pointer; } & .mk-feedback-form-yesno input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; } & .mk-feedback-form-yesno svg { width: 0.875rem; height: 0.875rem; } & .mk-feedback-form-yesno label:hover { background: var(--accent); } & .mk-feedback-form-yesno label:has(:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; } & .mk-feedback-form-thanks { display: none; margin: 0; color: #15803d; font-size: 0.875rem; font-weight: 500; } &:has(.mk-feedback-form-yesno :checked) fieldset { display: none; } &:has(.mk-feedback-form-yesno :checked) .mk-feedback-form-thanks { display: block; } } /* -- Accessibility ------------------------------------------- */ @media (prefers-reduced-motion: reduce) { .mk-feedback-form-faces label { transition: none; } } @media (forced-colors: active) { .mk-feedback-form-faces label:has(:checked), .mk-feedback-form-scale label:has(:checked), .mk-feedback-form-chips label:has(:checked) { outline: 2px solid Highlight; } }}Comments, ideas or improvements? Edit this page's source on GitHub