<form onsubmit="e => preventDefault()">
  <div class="form-groups">
    <div class="form-group">
      <label for="name" class="form-group__label">
        Name
      </label>
      <input required="" type="text" id="name" class="form-input" placeholder="Name" title="Name must be at least 2 characters" pattern=".{2,}" />
    </div>
    <div class="form-group">
      <label for="email" class="form-group__label">
        Email
      </label>
      <input required type="email" id="email" class="form-input" title="Enter valid email address" placeholder="Email" />
    </div>
    <div class="form-group">
      <label for="password" class="form-group__label">
        Password
      </label>
      <input required="" type="password" id="password" class="form-input" placeholder="Password" title="Password must be at least 8 characters" pattern=".{8,}" />
    </div>
  </div>
  <div class="form-actions">
    <label>Layout</label>
    <div class="radio-groups">
      <input type="radio" name=orientation checked id=vertical />
      <label for=vertical>Vertical</label>
      <input type="radio" name=orientation id=stagger />
      <label for=stagger>Staggered</label>
      <input type="radio" name=orientation id=horizontal />
      <label for=horizontal>Horizontal</label>
    </div>
  </div>
  <div class="form-actions">
    <label></label>
    <button type="submit">Sign up</button>
  </div>

</form>
<div class="form-indicator">👈</div>
@layer demo {
  :root:has(#vertical:checked) {
    --flow: row;
  }

  :root:has(#horizontal:checked) {
    --flow: column;
    --twist: 1;
  }

  :root:has(#stagger:checked) {
    --stagger: 1;
  }
  :root {
    --active-anchor: --name;
    --active-left: anchor(var(--active-anchor) right);
    --active-top: calc(
      anchor(var(--active-anchor) top) +
        (
          (
              anchor(var(--active-anchor) bottom) -
                anchor(var(--active-anchor) top)
            ) * 0.5
        )
    );
  }

  :root:has(.form-group:focus-within) {
    --anchor-scale: 1;
    --anchor-transition: top 0.2s, left 0.2s, transform 0.2s;
  }

  #email {
    anchor-name: --email;
  }
  #name {
    anchor-name: --name;
  }
  #password {
    anchor-name: --password;
  }

  :root:has(#email:focus) {
    --active-anchor: --email;
  }
  :root:has(#name:focus) {
    --active-anchor: --name;
  }
  :root:has(#password:focus) {
    --active-anchor: --password;
  }

  .form-indicator {
    left: var(--active-left);
    top: var(--active-top);
    transform: translate(
        var(--active-translate-x, 1rem),
        var(--active-translate-y, -50%)
      )
      scale(var(--anchor-scale, 0)) rotate(calc(var(--twist, 0) * -90deg));
    transition: var(
      --anchor-transition,
      top 0.2s 0.2s,
      left 0.2s 0.2s,
      transform 0.2s
    );
    font-size: 4rem;
    background: none;
    position: fixed;
  }

  :root:has(#horizontal:checked) {
    --active-translate-x: -50%;
    --active-translate-y: -150%;
    --active-left: calc(
      anchor(var(--active-anchor) left) +
        (
          (
              anchor(var(--active-anchor) right) -
                anchor(var(--active-anchor) left)
            ) * 0.5
        )
    );
    --active-top: calc(
      anchor(var(--active-anchor) top) +
        (
          (
              anchor(var(--active-anchor) bottom) -
                anchor(var(--active-anchor) top)
            ) * 0.5
        )
    );
  }
}

* {
  box-sizing: border-box;
}

:root {
  --red: hsl(18 100% 50%);
  --green: hsl(130 52% 46%);
  --yellow: hsl(44 83% 53%);
  --blue: hsl(215 100% 53%);
  --grey: hsl(0 0% 45%);
  --text: var(--gray-5);
  --transition: 0.2s;
  --valid: var(--green);
  --invalid: var(--red);
  --focus: var(--yellow);
  --blur: var(--gray-0);
  --disabled: var(--grey);
}

.whitespace {
  width: 0.5ch;
}

:where(html) {
  background-color: transparent;
  color-scheme: none;
}

body {
  display: grid;
  min-height: 100vh;
  place-items: center;
  overflow: hidden;
  margin: 0;
  background-color: var(--gray-9);
  font-size: 1rem;
}

form {
  display: grid;
  grid-gap: 1rem;
  place-items: center;
}

.form-groups {
  display: grid;
  grid-gap: 1rem;
  grid-auto-flow: var(--flow);
}

.form-actions {
  width: 100%;
}

.radio-groups {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.radio-groups label {
  font-weight: 300;
  font-size: 1rem;
}

.radio-groups * {
  display: inline-block;
}

.form-group,
.form-actions {
  --color: var(--blur);
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  justify-content: flex-end;
}

.form-group {
  position: relative;
  left: calc((var(--stagger, 0) * var(--index)) * 4rem);
}

.form-group:nth-of-type(1) {
  --index: 0;
}

.form-group:nth-of-type(2) {
  --index: 1;
}

.form-group:nth-of-type(3) {
  --index: 2;
}

label {
  font-family: sans-serif;
  display: flex;
  font-weight: bold;
  padding-right: 1rem;
  transform-style: preserve-3d;
  transition: color var(--transition);
  color: var(--color);
  font-size: 1.25rem;
}

.form-group label {
  grid-row: 1;
}
input:not([type="radio"]) {
  grid-row: 1;
  border: 4px solid var(--blur);
  background: var(--blur);
  border-radius: 4px;
  padding: 1rem 2rem;
  font-weight: 400;
  transition: border-color var(--transition);
  outline: transparent;
}

input:focus-visible {
  outline-color: var(--color);
}

input::placeholder {
  color: transparent;
}

button {
  padding: 1rem 2rem;
  border-radius: 4px;
  border: 0;
  cursor: pointer;
  background: var(--disabled);
  font-weight: bold;
  font-size: 1.25rem;
  color: var(--gray-5);
  transition: color var(--transition), background var(--transition);
}

input:not([type="radio"]),
button,
.radio-groups {
  width: 250px;
}

.form-group:has(:invalid) {
  --color: var(--invalid);
}

.form-group:has(:focus) {
  --color: var(--focus);
}

.form-group:has(:valid) {
  --color: var(--valid);
}

@media (prefers-reduced-motion: no-preference) {
  .form-group:has(:valid) label span {
    display: inline-block;
    animation: jump 0.25s calc(var(--char-index) * 0.05s);
  }
  @keyframes jump {
    50% {
      transform: translateY(-50%);
    }
  }
  .form-group:has(:invalid:not(:focus):not(:placeholder-shown)) {
    animation: shake 0.2s;
  }
  @keyframes shake {
    0%,
    100% {
      transform: translateX(0);
    }
    20%,
    40%,
    60%,
    80% {
      transform: translateX(-2%);
    }
    10%,
    30%,
    50%,
    70%,
    90% {
      transform: translateX(2%);
    }
  }
}

.form-group:has(:placeholder-shown:not(:focus)) label span {
  animation: none;
}

.form-group:has(:placeholder-shown) {
  --color: var(--blur);
}

.form-group:has(:invalid:not(:focus):not(:placeholder-shown))
  .form-group__error {
  display: block;
}

.form-group__input {
  position: relative;
}

.form-group__error {
  display: none;
  white-space: nowrap;
  color: var(--red);
  font-size: var(--font-size-0);
  grid-row: 2;
  grid-column: 2;
  padding: var(--size-2);
  text-align: center;
}

label span {
  display: inline-block;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

/*.form-group:has(:valid) ~ .form-group:has(:valid) ~ [type="submit"] {
  background: var(--valid);
  color: var(--gray-1);
}*/

form:valid [type="submit"] {
  background: var(--valid);
  color: var(--gray-1);
}

External CSS

  1. https://codepen.io/web-dot-dev/pen/XWqWYgB.css
  2. https://codepen.io/web-dot-dev/pen/ZExZWBQ.css

External JavaScript

  1. https://codepen.io/web-dot-dev/pen/XWqWYgB.js
  2. https://codepen.io/web-dot-dev/pen/ZExZWBQ.js