<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ToggleButton &#8211; Mach3.laBlog</title>
	<atom:link href="https://blog.mach3.jp/tag/togglebutton/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.mach3.jp</link>
	<description></description>
	<lastBuildDate>Tue, 04 Nov 2014 01:06:54 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>最近のトグルボタン実装を少し考えてみる</title>
		<link>https://blog.mach3.jp/2014/11/04/toggle-button.html</link>
		
		<dc:creator><![CDATA[mach3]]></dc:creator>
		<pubDate>Tue, 04 Nov 2014 01:06:54 +0000</pubDate>
				<category><![CDATA[Laboratory]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ToggleButton]]></category>
		<category><![CDATA[UI]]></category>
		<guid isPermaLink="false">http://blog.mach3.jp/?p=3885</guid>

					<description><![CDATA[最近ではIE6/7対応がほとんど無くなり、泥臭い手法を取る必要が少し減ってきました。 様々な場面で頻出するトグルボタンUIもまた、以前に比べて少しモダンな形での実装が可能になってきています。 隣接セレクタを使用したトグル [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>最近ではIE6/7対応がほとんど無くなり、泥臭い手法を取る必要が少し減ってきました。 様々な場面で頻出するトグルボタンUIもまた、以前に比べて少しモダンな形での実装が可能になってきています。</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh5.googleusercontent.com/-KAXV6MWKTPY/VFdvQDJppQI/AAAAAAAAClw/d7JI5o9Pa4M/s400/2014-1103-00.png" alt="最近のトグルボタン実装を少し考えてみる"/></figure>



<p></p>



<span id="more-3885"></span>



<h2 class="wp-block-heading">隣接セレクタを使用したトグルボタン</h2>



<p>IEはバージョン8から<strong>隣接セレクタ</strong>が使えるようになります。 ここでは、その隣接セレクタとラジオボタンを使ってトグルボタンを作ってみます。 ラジオボタンをチェックボックスに変更すれば複数選択可能なボタンが表現できます。</p>



<p><a class="jsbin-embed" href="http://jsbin.com/jucaha/1/embed?output">Toggle Button Demo</a><script src="http://static.jsbin.com/js/embed.js"></script></p>



<p>要点は、下記の通りです。</p>



<ul class="wp-block-list">
<li><strong>:checked</strong> 擬似クラスと隣接セレクタ（+）を使用</li>



<li>input要素は非表示にして、隣接する <strong>span.label</strong> 要素をボタンのように見せる</li>



<li><strong>label</strong> 要素でラップして選択出来るようにする</li>
</ul>



<p>ところが、このコードは次に挙げる問題によりIE8では正常に動作しません。</p>



<h3 class="wp-block-heading">非表示のラジオボタン/チェックボックスの選択が出来ない</h3>



<p>IE8以下では、<strong>display:none</strong> や <strong>visibility:hidden</strong> で非表示にしたinput要素を選択する事ができません。 これは関連付けられた label 要素をクリックしても同様です。 選択出来ないというのはつまり、checked 属性もつかなければ、changeイベントも発火しないという事です。</p>



<p>そこで、display/visibility を使わずに <strong>opacity</strong> を使用して非表示にします。</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-class">.toggle-button</span> <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">&#91;type=radio]</span> {
    <span class="hljs-attribute">position</span>: absolute;
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">filter</span>: <span class="hljs-built_in">alpha</span>(opacity=<span class="hljs-number">0</span>);
    <span class="hljs-attribute">outline</span>: none;
}
</code></span></pre>


<h3 class="wp-block-heading">:checked の使用</h3>



<p>IE8は隣接セレクタは使えますが、<strong>:checked</strong> 擬似クラスには対応していません。 その為、代替として選択状態の物に checked クラスを付与して使用します。</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-class">.toggle-button</span> <span class="hljs-selector-class">.checked</span> + <span class="hljs-selector-class">.label</span> {
    <span class="hljs-attribute">background-color</span>: magenta;
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}
</code></span></pre>


<p>そして、input要素の選択状態と checked クラスを同期する為に次のような処理を追加してやります。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">$(<span class="hljs-built_in">document</span>).on(<span class="hljs-string">"change"</span>, <span class="hljs-string">"input&#91;type=radio], input&#91;type=checkbox]"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
    $(<span class="hljs-built_in">document</span>.getElementsByName(<span class="hljs-keyword">this</span>.name)).each(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        $(<span class="hljs-keyword">this</span>).toggleClass(<span class="hljs-string">"checked"</span>, <span class="hljs-keyword">this</span>.checked);
    });
});
</code></span></pre>


<p>このコードは、input要素の選択状態が更新されるたびに、 同じnameを持ったinput要素の checked クラスの有無を、その選択状態によって更新します。</p>



<p>さらに注意が必要なのは、次のような書き方が出来ない点です。</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-class">.toggle-button</span> <span class="hljs-selector-pseudo">:checked</span> + <span class="hljs-selector-class">.label</span>,
<span class="hljs-selector-class">.toggle-button</span> <span class="hljs-selector-class">.checked</span> + <span class="hljs-selector-class">.label</span> {
    <span class="hljs-comment">/* ここの指定はIE8で無視される */</span>
}
</code></span></pre>


<p>一見問題なさそうですが、:checked 非対応のIE8ではこのセレクタ内のスタイル指定は無視されてしまいます。</p>



<p>.checked と :checked はJavaScriptで同期されているので .checked の指定だけで良しとするか、 どうしても :checked の指定も記述したい場合は分離して指定する必要があります。</p>


<pre class="wp-block-code"><span><code class="hljs">.toggle-button :checked + .label { ... }
.toggle-button .checked + .label { ... }
</code></span></pre>


<h2 class="wp-block-heading">最終的なコード</h2>



<p><a class="jsbin-embed" href="http://jsbin.com/dowopo/1/embed?output">Toggle Button Demo</a><script src="http://static.jsbin.com/js/embed.js"></script></p>



<h2 class="wp-block-heading">（おまけ）IE11のエミュレーションでの表示不具合</h2>



<p>IE11の開発ツールのエミュレーション機能でIE8を選択して上のコードを確認すると、 隣接セレクタまわりの表示更新が上手くされずに、少しおかしな挙動を見せます。</p>



<ul class="wp-block-list">
<li>ボタンをクリックしてもボタンのスタイルが更新されない</li>



<li>前に選択されていたボタンがきちんとトグルされない</li>
</ul>



<p>ちなみにマウスオーバーするとようやくボタンのスタイルが更新されたりします。</p>



<p>ネイティブのIE8はもちろん、IE10迄のブラウザモード切替でも正常に動作するのでさしたる問題ではないですが、 動作確認がちょっと捗らなくなるので、そういう事があるのだと知っておくと良いと思います。</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
