入力欄を選んだら色が変わる、CSSのフォーカスの見た目|:focusと:focus-within、コピペ4種類

入力欄を選んだら色が変わる。見本とコード

フォームの入力欄をクリックしたとき、枠の色がふっと変わる。小さな変化ですが、「いま、ここに入力している」が目で分かるので、迷わず入力を進められます。CSSの :focus(選ばれている間)を使うと、この見た目を数行で作れます。

使いどころ

入力欄があるなら、必ず「選ばれたときの見た目」を付ける。ブラウザの線を消すなら、それより分かりやすい見た目に置きかえるときだけ。見出しを動かすような演出は、項目が多いフォームに限る。

今回は、枠の色が変わる基本の入力欄、下線が伸びる入力欄、見出しが上に動く入力欄、虫めがねごと色が変わる検索欄の4種類を、コピペ用のコードつきで紹介します。枠線の濃さや高さの目安、キーボード操作や強制カラーモードへの配慮もまとめました。

トミー

連載「WEBの技術」の29回目です。
前回のチェックボックスに続いて、フォームの部品。今回は文字を打ちこむ入力欄です。

完成見本:選ばれると色が変わる4種類

下の4つは、どれも本物の <input>(入力の部品)です。動きが分かるように、見本では「選ぶ → 文字が入る → 選ぶのをやめる」を自動でくり返します。

FOCUS RING1. 枠の色が変わる、いちばん基本の入力欄お問い合わせフォームなど、ほとんどの入力欄に
UNDERLINE2. 下線が左右に伸びる入力欄すっきり見せたい、項目の少ないフォームに
FLOATING LABEL3. 見出しが上に小さく動く入力欄入力欄の数が多く、高さを詰めたいフォームに
SEARCH BOX4. 虫めがねごと色が変わる検索欄ヘッダーやサイドバーの、サイト内検索に

※ 見本は、本当に入力欄を選ぶと読んでいる画面が見本の位置へ動いてしまうため、「選ばれた見た目」を目印のクラスで再現しています。CSSの中身はコピペ用のコードと同じです。読み上げソフトでは読まれず、キーボードでも止まりません。端末で動きを減らす設定にしている場合は、入力済みの状態で止まります。

コピペ用のコード

CSSは、サイトのCSSファイルや、WordPressならテーマの「追加CSS」などに入れます。クラス名の頭の kd-in は、サイトのほかのデザインと名前がぶつからないようにするための目印です。

1. 枠の色が変わる、いちばん基本の入力欄

ふだんは灰色の枠線、選ばれている間(:focus)は青い枠線と、外側にうすい青の輪を出します。輪は box-shadow(影の指定)を、ぼかし0で外へ4px広げたものです。下のCSSの前半(kd-in-label と kd-in-text)は、3でも使います。

HTML
<label class="kd-in-label" for="kd-name">お名前</label>
<input class="kd-in-text" id="kd-name" type="text" name="name" autocomplete="name">
CSS
/* 3でも使う:見出しと入力欄 */
.kd-in-label {
  display: block;
  margin-bottom: 6px;
  font-size: 14px;
  font-weight: 700;
  color: #10283A;
}
.kd-in-text {
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 48px;
  padding: 0 14px;
  border: 2px solid #7B8A97;
  border-radius: 8px;
  background: #FFFFFF;
  font-size: 16px;
  color: #10283A;
  transition: border-color .15s ease, box-shadow .15s ease;
}
/* 選ばれている間:青い枠線+うすい青の輪 */
.kd-in-text:focus {
  border-color: #0284C7;
  outline: none;
  box-shadow: 0 0 0 4px rgba(2, 132, 199, .25);
}
/* 強制カラーモードでは影が消えるので、線で示す */
@media (forced-colors: active) {
  .kd-in-text:focus {
    outline: 3px solid Highlight;
    outline-offset: 1px;
  }
}

2. 下線が左右に伸びる入力欄

枠線は下だけにして、その上に、幅0の青い線を重ねておきます。選ばれると、線の幅が中央から100%まで伸びます。青い線は画像ではなく、linear-gradient(グラデーションを作る指定)で同じ色を2つ並べて作った、1色の帯です。帯の幅を background-size で 0% から 100% に変えています。

HTML
<label class="kd-in-label" for="kd-addr">ご住所</label>
<input class="kd-in-line" id="kd-addr" type="text" name="address" autocomplete="street-address">
CSS
.kd-in-line {
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 48px;
  padding: 0 4px;
  border: 0;
  border-bottom: 2px solid #7B8A97;
  border-radius: 0;
  /* 青い帯:はじめは幅0。下の枠線に重ねる */
  background: #FFFFFF linear-gradient(#0284C7, #0284C7)
    no-repeat center bottom / 0% 3px;
  background-origin: border-box;
  font-size: 16px;
  color: #10283A;
  transition: background-size .25s ease;
}
.kd-in-line:focus {
  outline: none;
  background-size: 100% 3px;
}
@media (forced-colors: active) {
  .kd-in-line:focus {
    outline: 3px solid Highlight;
    outline-offset: 1px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .kd-in-line {
    transition: none;
  }
}

3. 見出しが上に小さく動く入力欄

見出しの <label> を入力欄の中に重ねておき、選ばれたとき、または文字が入っているときに、上へ小さく動かします。「文字が入っているか」は :placeholder-shown(見本の文字=プレースホルダーが表示されているとき)の否定で見分けます。そのために placeholder=" "(空白1文字)を入れています。入力欄そのものは1のCSSを使います。

HTML
<div class="kd-in-float">
  <input class="kd-in-text" id="kd-mail" type="email" name="email" placeholder=" " autocomplete="email">
  <label for="kd-mail">メールアドレス</label>
</div>
CSS
.kd-in-float {
  position: relative;
}
.kd-in-float .kd-in-text {
  height: 56px;
  padding-top: 18px;
}
/* 見出し:入力欄の中に重ねる */
.kd-in-float label {
  position: absolute;
  top: 16px;
  left: 16px;
  font-size: 16px;
  line-height: 1.5;
  color: #5A6E7E;
  pointer-events: none;
  transform-origin: left top;
  transition: transform .2s ease, color .2s ease;
}
/* 選ばれたとき、または文字が入っているとき:上へ小さく */
.kd-in-float .kd-in-text:focus + label,
.kd-in-float .kd-in-text:not(:placeholder-shown) + label {
  transform: translateY(-10px) scale(.75);
  color: #33495B;
}
.kd-in-float .kd-in-text:focus + label {
  color: #0369A1;
}
@media (prefers-reduced-motion: reduce) {
  .kd-in-float label {
    transition: none;
  }
}

4. 虫めがねごと色が変わる検索欄

入力欄と虫めがねのアイコンを、1つの箱で包んでいます。箱に付けた :focus-within(中のどれかが選ばれているとき)で、枠線とアイコンの色をまとめて変えます。アイコンの線は currentColor(その場所の文字の色)にしてあるので、箱の color を変えるだけで色が変わります。

HTML
<div class="kd-in-search">
  <svg aria-hidden="true" viewBox="0 0 24 24" width="20" height="20">
    <circle cx="11" cy="11" r="7"/>
    <path d="M20 20l-4-4"/>
  </svg>
  <input type="search" name="s" aria-label="サイト内を検索" placeholder="キーワードで検索">
</div>
CSS
.kd-in-search {
  display: flex;
  align-items: center;
  gap: 8px;
  box-sizing: border-box;
  height: 48px;
  padding: 0 16px;
  border: 2px solid #7B8A97;
  border-radius: 999px;
  background: #FFFFFF;
  color: #5A6E7E;
  transition: border-color .15s ease, box-shadow .15s ease, color .15s ease;
}
.kd-in-search svg {
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
}
.kd-in-search input {
  flex: 1;
  min-width: 0;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  outline: none;
  background: none;
  font-size: 16px;
  color: #10283A;
}
.kd-in-search input::placeholder {
  color: #5A6E7E;
  opacity: 1;
}
/* 中の入力欄が選ばれている間:箱ごと青く */
.kd-in-search:focus-within {
  border-color: #0284C7;
  box-shadow: 0 0 0 4px rgba(2, 132, 199, .25);
  color: #0284C7;
}
@media (forced-colors: active) {
  .kd-in-search:focus-within {
    outline: 3px solid Highlight;
    outline-offset: 1px;
  }
}

仕組み:「選ばれている間」だけ見た目を変える

:focus と :focus-visible の違い

MDNでは、:focus は、マウスで押したとき、指でタップしたとき、キーボードのTabキーで選んだときに当てはまると説明されています。一方の :focus-visible は、ブラウザが「線を見せたほうがよい」と判断したときだけ当てはまる指定です。ボタンでは、マウスで押したときに線が出ないように :focus-visible を使うことが多いですが、文字を打ちこむ入力欄は、どの操作で選んでも「いまここに入力している」を見せたいので、今回は :focus を使っています。

輪は box-shadow、下線は background

1の外側のうすい輪は、box-shadow: 0 0 0 4px です。数字は順に「横のずれ・縦のずれ・ぼかし・広がり」で、ずれもぼかしも0にして、広がりだけを4pxにすると、枠のまわりにくっきりした輪ができます。輪は枠線と違って、まわりの文字の位置を押し出さないので、選んだ瞬間に入力欄の大きさが変わって見えることがありません。

2の下線は、背景に置いた1色の帯です。background-size で帯の幅を 0% から 100% に変え、center bottom(中央の下)を基準にしているので、中央から左右へ伸びます。background-origin: border-box は、帯を下の枠線の上に重ねるための指定です。

文字が入っているかを CSS で見分ける

3の見出しは、選ばれている間だけでなく、文字が入っている間も上に残しておく必要があります。そうしないと、ほかの欄へ移ったときに、見出しと入力した文字が重なってしまいます。CSSには「文字が入っているとき」という指定がないため、プレースホルダーが表示されているときに当てはまる :placeholder-shown を使い、その否定(:not())で見分けます。プレースホルダーが空だと当てはまらないので、空白1文字を入れておくのがコツです。

外側の箱を変える :focus-within

4の検索欄では、色を変えたいのは入力欄ではなく、虫めがねを含めた外側の箱です。:focus-within は、中のどれかが選ばれているときに、外側の要素に当てはまる指定です。MDNによると、:focus-within と :placeholder-shown は、どちらも2020年1月から主要なブラウザで使えます。

数値を変えるとどうなるか

選んだときの輪の大きさ

1の入力欄を、選ばれた状態で並べました。輪の広がりだけを変えています。

枠の色だけ:変化が小さい
輪 4px:目安
輪 10px:大げさ

枠の色だけを変える方法は、変化が小さく、灰色から青への違いに気づきにくいことがあります。輪を4px足すと、入力欄の大きさは変わらないまま、選ばれていることがはっきりします。10pxまで広げると、となりの入力欄に輪がかかるほど目立ち、フォーム全体がにぎやかに見えます。

ふだんの枠線の濃さ

選ばれていないときの、枠線の色を変えました。

#C9D3DB:1.5対1・見えにくい
#A9B6C1:2.1対1・まだうすい
#7B8A97:3.5対1

うすい灰色の枠線はすっきり見えますが、白い背景との明るさの差が小さく、どこに入力欄があるのかが分かりにくくなります。W3Cのアクセシビリティの基準(WCAG 2.2)では、部品を見分けるのに必要な線は、となりの色と3対1以上が目安です。今回は #7B8A97(白に対して約3.5対1)にしています。

入力欄の高さ

36px:小さく押しにくい
48px:目安の高さ
60px:ゆったり

36pxは見た目が軽くなる一方、スマホでは指で押しにくくなります。48pxあれば、指でも押しやすく、文字の上下にも余白が取れます。60pxはゆったりしますが、項目が多いフォームでは縦に長くなります。

変えるところ小さく・うすくすると大きく・濃くすると
選んだときの輪(1の 4px)選ばれたことに気づきにくい大げさに見え、となりの欄にかかる
ふだんの枠線(1の #7B8A97)入力欄の場所が分かりにくいくっきりして、少しかたい印象になる
高さ(1の 48px)スマホで押しにくいゆったりするが、フォームが縦に長くなる
切りかわりの時間(1の .15s)ぱっと変わるもたついて見え、すばやく移ると遅れて感じる

スマホと、見る人への配慮

選んだことを示す線を、消しっぱなしにしない

今回のコードには outline: none(ブラウザが描く線を消す指定)が入っていますが、そのかわりに青い枠線と輪を出しています。MDNでも、選ばれたことを示す見た目を消すと、キーボードで操作する人が、いまどこにいるのか分からなくなると注意されています。AIや古いテンプレートのコードでは、outline: none だけが書かれていることがあるので、代わりの見た目があるかを必ず確かめます。

強制カラーモードでは、影と背景の帯が消える

Windowsの「コントラスト テーマ」のような強制カラーモードでは、MDNの説明どおり、box-shadow は消え、画像でない background-image も消えます。つまり、1の輪も2の青い帯も見えなくなります。そこで @media (forced-colors: active)(強制カラーモードのときだけ)の中で、outline を Highlight(その人の設定で「選ばれた色」として決められている色)で出しています。

見出しは、プレースホルダーで代用しない

入力欄の中に「お名前」と薄く書くだけで、見出しを置かないフォームを見かけます。MDNでは、プレースホルダーは入力例を示すためのもので、<label> の代わりにしないよう書かれています。文字を打ちはじめると消えてしまい、読み上げソフトもふつうは読まないためです。3の入力欄は見た目こそ中に入っていますが、中身は本物の <label> で、文字が入っても上に残ります。4の検索欄は見出しを置かないかわりに、aria-label(読み上げ用の名前)で「サイト内を検索」と伝えています。

色だけに頼らない

エラーのときに枠を赤くするなら、「メールアドレスの形で入力してください」のような文字もいっしょに出します。色の見分けがつきにくい人にも、何を直せばよいかが伝わるようにするためです。

やりすぎ注意

選んだ瞬間に入力欄が大きく弾む、色が何度も点滅する、といった演出は、入力している人の気を散らします。動きを付けるのは、下線や見出しのように「どこが選ばれたか」を伝えるものだけにし、時間も0.2秒前後にとどめています。2と3の動きは、端末で動きを減らす設定にしている人には止まるようにしています。

トミー

入力欄は、フォームの中でいちばん長く見られる場所です。
目立たせるより、「いまここ」が自然に分かることを優先しています。

AIに頼むなら

入力欄の見た目も、Claudeなどの生成AIに頼むとすぐ作ってもらえます。色だけでなく、選ばれたときの見せ方と配慮まで、まとめて伝えると手直しが少なく済みます。

お問い合わせフォームの入力欄を、高さ48px・角丸8px・枠線2px #7B8A97 にして。
選ばれたら枠を #0284C7 にし、外側に box-shadow で4pxのうすい青の輪を出して。
label は入力欄の上に置き、forced-colors のときは outline で示して。

AIが出したコードは、そのまま使う前に、次の3つを確かめます。

  • outline: none の代わりがあるか。線を消しただけで、選ばれたときの見た目が何も変わらないコードがよく出てきます。Tabキーで入力欄を順に移って、いまどこにいるかが分かるかを試します
  • 見出しがプレースホルダーだけになっていないか。すっきり見せるために label が省かれがちです。文字を打ったあとも、何の欄か分かるかを確かめます
  • ふだんの枠線がうすすぎないか。白い背景に明るい灰色の枠線が選ばれがちです。白との差が3対1以上あるかを確かめます

KAKERUならこう使う/使わない

最後に、作り手としての判断です。

使う場面

  • ほとんどのフォームは、1の基本の入力欄。枠の色と輪が変わるだけで十分伝わります。見た目に迷いがなく、あとからサイトを直す人にも分かりやすい形です
  • サイト内検索は、4の検索欄。ヘッダーの小さな検索欄は、選んだときに箱ごと色が変わると、入力できる状態になったことが分かります
  • 項目が多い申し込みフォームで、高さを詰めたいときは3。見出しが中に入る分、縦の長さを抑えられます

使わない場面

  • 入力欄が2〜3個しかない、短いフォームに3。見出しを外に置いても長さはほとんど変わらないので、動きを足す意味がありません
  • はじめての人が多く使うフォームに2。下線だけの形は、すっきりする反面、入力できる場所であることを形で示す力が弱くなります。KAKERUでは、こうしたフォームには枠で囲った1を選んでいます
  • WordPressのフォームのプラグインが、独自の見た目を持っているとき。プラグインのCSSと重なって、枠が二重に出ることがあります。まずはプラグインの設定で色を変えられないかを見ます
トミー

フォームで大事なのは、入力を最後まで終えてもらうこと。
なので、KAKERUでは「派手さ」より「迷わなさ」で選んでいます。基本は1、検索だけ4、です。

まとめ

  • 入力欄には、必ず「選ばれたときの見た目」を付ける。outline: none だけにしない
  • 1の基本形は、:focus で枠の色を変え、box-shadow で外側に輪を足す
  • 下線は background-size、見出しを動かすのは :not(:placeholder-shown)、箱ごと変えるのは :focus-within
  • 強制カラーモードでは影と背景の帯が消えるので、outline で補う
  • ふだんの枠線は背景と3対1以上、高さは48px前後。見出しは label で置く

まずは、自分のサイトのお問い合わせフォームで、入力欄をクリックしてみてください。色が変わらなければ、1のCSSを入れるだけで、ぐっと入力しやすくなります。

参考にした資料

いずれも2026年10月28日に確認しました。ブラウザの対応状況は変わることがあります。最新の情報は各ページでご確認ください。

ふだんの制作の話や、作ったものの裏側は Instagram と X でも出しています。

関連記事

チェックボックスの見た目をCSSで変える。見本とコード
影の付け方をCSSで覚える。box-shadowの見本とコード
マウスを乗せると動くボタンをCSSだけで コピペで使える5種類と、スマホ・キーボードへの配慮
ハンバーガーメニューをCSSで×に変える。見本とコード
入力欄を選んだら色が変わる。見本とコード

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA