CSS

Controls whether users can select text or images inside an element.

user-select

user-select は、UI部品や本文などで「テキストを範囲選択できる/できない」を切り替えるためのCSSです。

このページでできるようになること

まずは直感:user-select って何?

user-select は、要素の中身(主にテキストや画像)をユーザーが範囲選択できるかどうかを切り替える設定です。

よくある用途は「UI部品では選択させない」「コピーしてほしい文字列は選択しやすくする」の2つです。

見た目やレイアウト(幅・高さ・配置)は変わりません。クリックやタップの可否も変わりません。

最小デモ:まず動かす

まずは none(選択不可)と all(一発全選択)を体感します。

このテキストは普通に選択できます。

このテキストは選択できない設定になっています。

一度のクリックで、このテキスト全体を選択できます。

HTML

<p>このテキストは普通に選択できます。</p>
<p class="unselectable">このテキストは選択できない設定になっています。</p>
<p class="all">一度のクリックで、このテキスト全体を選択できます。</p>

CSS

.unselectable {
	user-select: none;
}

.all {
	user-select: all;
}

基本の書き方(最短の型)

実務では外部CSS(共通CSSやページCSS)に書くのが基本で、インラインやJavaScriptでの指定は例外として扱います。

CSS

/* UIの誤選択を防ぐ */
.button-like {
	user-select: none;
}

/* コピーさせたい文字列を一発で全選択 */
.copy-token {
	user-select: all;
}

正確な定義(仕様に沿った説明)

user-select は、ユーザー操作(ドラッグ、ダブルクリック、長押しなど)による「選択」のしやすさを制御します。

対象はすべての要素です。レイアウトや描画(表示/非表示)を変えるプロパティではありません。

user-select: none は“操作を抑制する”だけで、DevToolsやJavaScript、画面キャプチャなどによる取得まで防ぐものではありません。情報保護の仕組みではありません。

初期値
auto
適用対象
すべての要素
継承
なし
※継承はしないが、auto の計算値は親要素の値に影響される。
計算値
指定値
アニメーションの種類
離散(discrete)

指定できる値(まず覚える4つ)

none
対象要素とその子孫要素のテキストは範囲選択できません。
text
ユーザーはテキストを範囲選択できます。選択範囲は要素境界をまたいで拡張できます。
all
要素の内容が不可分に選択されます。部分的に選ぶと、その要素全体が選択されるイメージです。
auto
状況に応じて自動決定されます(次の章で“なぜそうなるか”を押さえます)。

contain は仕様上は存在しますが、主要ブラウザでほとんど実装されていないため実務で使える場面はほぼありません(試験では“存在する値”として知識整理だけしておくと安全です)。

仕様として押さえるポイント(ここで事故を防ぐ)

継承しない、でも auto は親の影響を受ける

user-select は継承しません。ただし auto の使用値は親の計算値を参照して決まるため、結果として“継承しているように見える”ことがあります。

HTML

<div class="parent">
	<p>親は選択不可(none)</p>
	<p class="child">子は指定なし(auto)でも、親の影響で選択不可になります</p>
	<p class="child text-select">この子だけ text に戻すと選択できます</p>
</div>

CSS

.parent {
	user-select: none;
}

.child {
	/* 指定なし(auto) */
}

.text-select {
	user-select: text;
}

親は選択不可(none)

子は指定なし(auto)でも、親の影響で選択不可になります

この子だけ text に戻すと選択できます

auto の使用値(ざっくり結論 → ルール)

結論としては「だいたい text だが、親が none/all なら引っ張られる」と覚えると実務で迷いにくいです。

離散アニメーション(パッと切り替わる)

user-select は途中の中間値がないため、値を変えると“段階的に”ではなく“切り替え”になります。

よくある勘違い・混同ポイント

user-select
テキストや画像を範囲選択できるかを制御します。クリック可否は変わりません。
pointer-events
クリックやタップなどポインター操作の当たり判定を制御します。テキスト選択の可否とは別です。
display / visibility
表示状態を制御します。user-select は表示を変えません。
-webkit-touch-callout
iOS Safari系で長押し時に出るメニュー(コールアウト)表示に関係します。user-select と併用されることがあります。
cursor
見た目のカーソルを変えるだけで、選択可否・クリック可否を保証しません。

実務でよくある使用例(制作会社の現場)

ボタン風UIでテキスト選択を防ぐ

CSS

.button-like {
	user-select: none;
}

タブ切り替えやカードUIなどで、ダブルクリックやドラッグ時に文字が選択状態になるのを防げます。

コピーしやすくする(注文番号・クーポン・コード)

ABCD-1234-EFGH

CSS

.all {
	user-select: all;
}

適用範囲を絞る(フォームは生かす)

CSS

.ui-area {
	user-select: none;
}

/* 入力欄や編集可能要素は選択できる状態に戻す */
.ui-area input,
.ui-area textarea,
.ui-area [contenteditable="true"] {
	user-select: text;
}

UI領域をまとめて none にしつつ、入力や編集は巻き込まないのが安全です。

一部のテキストだけ選択できるようにする

親(または文章全体)を none にしてから、選択したい部分だけ text で上書きします。

このテキストは「一部」だけ、範囲選択ができます。

HTML

<p class="unselectable">このテキストは「<span class="text-select">一部</span>」だけ、範囲選択ができます。</p>

CSS

.unselectable {
	user-select: none;
}

.text-select {
	user-select: text;
}

実務で起きがちな事故と回避策(効かないを最短で潰す)

まず DevTools の Computed で最終値を見る

よくある症状と原因候補

指定したのに選択できてしまう
別のCSSが後から上書きしている/詳細度が高いルールに負けている/JavaScriptでインライン指定されている可能性があります。Computedで最終値を確認します。
入力欄まで選択できなくなった
input / textarea / [contenteditable] まで巻き込んでいる可能性があります。適用範囲を絞るか、対象だけ text に戻します。
一部だけ選択したいのにうまくいかない
親に none を当てた上で、選択したい要素に text を明示して上書きします。
クリックも止めたい
user-select ではなく pointer-events を検討します(ただしキーボード操作やアクセシビリティにも影響が出やすいので用途限定)。

詳細度で負けるパターン(最小の注意)

同じ要素に複数の user-select が当たる場合、基本は「詳細度 → 後勝ち」の順で勝ち負けが決まります。UI全体に .ui-area * のような広域指定をすると、意図せずフォームまで巻き込みやすいので注意します。

モバイルでの挙動(長押し・メニュー)

スマートフォンでは長押しによる選択やコンテキストメニューの表示に影響します。特にiOS Safari系では -webkit-touch-callout と併用されることがあります。

CSS

.sample {
	user-select: none;
	-webkit-touch-callout: none;
}

アクセシビリティ/UX観点での注意

関連プロパティ・関連セレクタとの組み合わせ

pointer-events
クリック/タップの当たり判定を制御します。テキスト選択を止めたいだけならまず user-select を検討します。
-webkit-touch-callout
iOS Safari系で長押しメニュー表示に関係します。
[contenteditable="true"]
編集可能要素。auto の挙動にも関係します。
::before / ::after
auto の計算で none になる例外を持ちます。

試験(Webクリエイター能力認定試験)で得点できる整理

用語ミニ辞典(短く)

継承(inheritance)
親の値が子に自動で引き継がれる仕組み。user-select 自体は継承しません。
初期値(initial value)
指定しなかった場合の出発点。user-select の初期値は auto です。
計算値(computed value)
継承や単位換算などを反映した値。
使用値(used value)
実際の挙動に使われる最終値。auto は条件で使用値が変わります。
詳細度(specificity)
どのCSSが勝つかの強さ。基本は「詳細度 → 後勝ち」。

ひっかけポイント(短く)

ミニ確認(判断する形)

Q1. .ui-area { user-select: none; } の中にある input まで選択できなくなった。最短の修正は?
A. .ui-area input { user-select: text; } のように、入力系だけ text で上書きします。
Q2. 子要素に指定していないのに選択できない。親に user-select: none がある。子の user-select は継承している?
A. 継承ではありません。子が auto のままだと、使用値決定のルールで親の影響を受けます。
Q3. コピー禁止にしたいので user-select: none を付けた。これで情報保護になる?
A. なりません。通常操作での選択を抑制するだけで、DevToolsやJavaScript、キャプチャなどは別です。

よくある質問(FAQ)

user-select が効かないのはなぜ?
DevTools の Computed で user-select の最終値を確認し、上書き(詳細度/後勝ち)や親の none/all を疑います。
一部だけ選択できるようにしたい
親(または文章全体)を user-select: none にして、選択したい要素だけ user-select: text で上書きします。
スマホで長押しメニューを出したくない
user-select に加えて、iOS Safari系では -webkit-touch-callout の影響を受けることがあります。
コピーを完全に防げますか?
通常の選択操作は抑制できますが、情報保護の機能ではありません。コピー禁止を前提に設計しないのが安全です。
クリックも無効にしたい
user-select ではなく pointer-events を検討します。ただし操作性やアクセシビリティへの影響が大きいので用途限定です。

よくあるエラー/症状 早見表

症状:選択できない
原因候補:親が none/JSでインライン指定/広域セレクタで巻き込み。確認:Computedの最終値。解決:必要箇所だけ text へ上書き。
症状:選択できてしまう
原因候補:別ルールに負けている。確認:Stylesで宣言元。解決:詳細度を上げるか後勝ちにする。
症状:フォームが使いづらい
原因候補:input/textarea を巻き込んだ。確認:対象要素のComputed。解決:フォームだけ text に戻す。
症状:スマホで長押しメニューが出る/出ない
原因候補:-webkit-touch-callout。確認:iOS Safariで再現。解決:必要なら併用。

まとめ:迷ったときの判断軸