<input type="number">のstep属性が思った通りに動いてくれなかった話

## 概説
HTML5ではinputタグが随分と様変わりしてますね。
「type="number"」、「type="date"」、「type="email"」、「type="tel"」、「type="color"」など、ブラウザ毎の実装差異はまだまだあるものの便利な属性が増えました。
今回はその中でも「type="number"」の「step」属性の動作に着目してみます。
なお、今回の動作確認ブラウザはChrome、Safariです。（IEは「type="number"」の「step」属性に対応していません。）


## step属性を指定しない場合

```html:html
<form>
  <input type="number">
</form>
```

↓こんな感じに入力欄の右端に▲▼ボタンが表示され、クリックすると1ずつ数値が増減します。
step属性の初期値は1なので指定しない場合は1ずつ増減するようです。
![input_step1.PNG](https://qiita-image-store.s3.amazonaws.com/0/23093/40d2f5b2-e1ad-fd61-c6ea-079b72909a50.png)


## step属性を指定した場合

```html:html
<form>
  <input type="number" step="2">
</form>
```

stepを指定した状態で▲▼ボタンをクリックすると、当然2ずつ数値が増減します。
ただし、入力欄に奇数が入力されている場合、意図した動きとは異なりました。
例えば、入力欄に「11」が入力されている状態で▲ボタンを押すと、「11」→「13」→「15」とは増えず、まず「12」になり「14」と増えていきます。

![input_step2.PNG](https://qiita-image-store.s3.amazonaws.com/0/23093/991785a7-f966-1a8c-69ff-8a31bd5070e6.png) → ![input_step3.PNG](https://qiita-image-store.s3.amazonaws.com/0/23093/b858275e-0a23-186c-76e9-4125be556e39.png) → ![input_step4.PNG](https://qiita-image-store.s3.amazonaws.com/0/23093/a6e14907-cccd-1093-67ca-6beeec4f4a57.png)

▼ボタンも同様で「11」の状態だと、「11」→「10」→「8」と変化します。

## step属性とmin属性を指定した場合

```html:html
<form>
  <input type="number" step="2" min="2">
</form>
```

この場合、当然ですが▼ボタンを押し続けると「2」で減算が止まります。

```html:html
<form>
  <input type="number" step="2" min="1">
</form>
```

「min="1"」にすると、またちょっと変わった動きになります。
例えば、入力欄に「12」が入力されている状態で▲ボタンを押すと、「12」→「14」→「16」とは増えず、まず「13」になり「15」と増えていきます。

![input_step5.PNG](https://qiita-image-store.s3.amazonaws.com/0/23093/46240129-55a9-fe84-bba3-07c4a5a5c439.png) → ![input_step6.PNG](https://qiita-image-store.s3.amazonaws.com/0/23093/4046e8c5-54ba-996f-a6f8-c54cd8c40f32.png) → ![input_step7.PNG](https://qiita-image-store.s3.amazonaws.com/0/23093/b975758d-a872-f9a5-00a8-ddea18ddd722.png)

もう察しがついてると思いますが、▼ボタンも同様で「12」の状態だと、「12」→「11」→「9」と変化します。

## step属性とmin属性とmax属性を指定した場合

どうやら、min + stepが基準値になり増減の幅が決まっていることがなんとなく分かりました。（ホントか？）

```html:html
<form>
  <input type="number" step="2" min="1" max="14">
</form>
```
この例だと、▼ボタンを押し続けると「1」で減算が止まり、▲ボタンを押し続けると「14」ではなく「13」で加算が止まります。

```html:html
<form>
  <input type="number" step="3" min="2" max="15">
</form>
```
この例だと、▼ボタンを押し続けると「2」で減算が止まり、▲ボタンを押し続けると「15」ではなく「14」で加算が止まります。
で、入力欄に「4」が入力されている状態で▲ボタンを押すと、「4」→「7」→「10」とは増えず、まず「5」になり「8」と増えていきます。

「min + stepが基準値」と言った意味は、上の例の場合、minが「2」なので「2」→「5」→「8」と加算されていきます。つまり、入力値が「3」の場合でも「4」の場合でも次の加算値は「5」となり、入力値が「6」の場合、次の加算値は「9」ではなく「8」となるようです。

うーん、分かったような分からないような。

## step属性を指定した場合（再び登場）

```html:html
<form>
  <input type="number" step="2">
</form>
```

では、前述した「step属性に2のみ指定した場合」の動作を再度考えてみましょう。
「11」→「13」→「15」ではなく「11」→「12」→「14」と変化していました。
「min + stepが基準値」と考えると、この場合minは「0」なので「0」→「2」→「4」→「6」→「8」→「10」→「12」→「14」と増えていくはずです。
ということで、どうやら「min + stepが基準値」という仮説がそれとなく当たってる気がします。

## おまけ

ChromeとSafariで「type="number"」を指定することで、▲▼ボタンが表示されることは既に説明しましたが、入力欄にフォーカスが当たっている状態で上下キーを押すと、▲▼ボタンを押した時と同様の操作ができます。これは地味に便利。
でも、IEでは当然動作しないので、同様のUIを提供したい場合はIEだけ独自に実装する必要がありますね。

## 関連URL

 - [HTML5 の step 属性を使いつつも強制はさせない](http://qiita.com/shinichinomura/items/9e304e2de7e587b1cd2c)
 - [[HTML5] input要素まとめ【2014/2/14版勧告候補】](http://qiita.com/maccotsan/items/310e9ee4a170955a69ae)