見出し画像

input[type="date"]について


みなさん、こんにちは🍀
Web制作勉強中のあいまるです🐻
input[type="date"]に貴重な時間とやる気をごっそり持っていかれたので記録用に残します。少しでも誰かの役に立てれば幸いです。

1.作成する「デザイン」

今回作成したデザインはこちらです👇

一見簡単そうでしたので、余裕ぶっこいてました。
まさか、ここから地獄がはじまろうとは… 大袈裟🙄

2.input[type="date"]を設定

まず、デザイン右側のカレンダーアイコンを見て、クリックしたらカレンダーが表示される仕様だと判断しました。

基本無知なので、とりあえずネット検索…
input[type="date"]たるものを使えば、カレンダーを表示できるらしい!
さっそく導入!

<div class="form__row">
    <dt class="form__label"><label for="your-date">希望日</label></dt>
    <dd class="form__input ">
        <time class="form__date js-is-blank"><input id="your-date" type="date" placeholder="年 / 月 / 日"></time>
        <time class="form__date js-is-blank"><input type="date" placeholder="年 / 月 / 日"></time>
        <time class="form__date js-is-blank"><input type="date" placeholder="年 / 月 / 日"></time>
    </dd>
</div>

結果がこちら👇(見た目のcssは適当に整えてあります)

んーーーーー🤔??? なんか違う。

どうやら「placeholder=""」指定していても、input[type=date]では適用されないらしいです。

自作画像の「年 /月/日」はchromeのブラウザ毎の表示設定が適用している。
【ブラウザ毎の表示設定例】
①chrome「年 /月/日」
②firefox「yyyy/mm/dd」
③safari「2023/10/1」(当日の日付)

3.解決案① テキストの透過

まず最初に試したのが、表示されているテキストを透明にすること。
未選択(空欄時)は透明にして、日付選択した際にjQuearyで色をつけようと考えました。

.form__date {
    position: relative;

    // 親要素の疑似要素で「年 / 月 / 日」設定
    &::before {
        content: "年 / 月 / 日";
        width: 82px;
        height: 22px;
        color: #C2C2C2;
        line-height: 22px;
        position: absolute;
        top: 50%;
        left: 16px;
        transform: translateY(-50%);
    }

    // 初期表示されているテキストを透過
    input[type="date"] { 
            color: transparent;
        }
}

結果がこちら👇

一見良さそうですが、問題がありました。

カレンダーで日付選択の際に、透過しているテキストがフォーカスされ浮き出てきてしまいました。

き、気持ち悪い…🙄

このフォーカス時のcssを解除できれば、綺麗になるのですが、私の力では解決できませんでした…
inputのfocusにcssを指定しても効果なしでした。
できる方ぜひ教えてください🙇

4.解決案② 初期表示テキストを削除

次に考えたのが、初期テキストを削除する方法です。
しかし、検証ツールで見ても、初期表示の部分は表示されてませんでした。

① ShadowDOM の表示

調べていくと、ShadowDOMというものがあり、開発者用にデフォルトでは隠されているコンテンツがあるとのこと。初期表示テキストもそこにありました。

【chrome】ShadowDOM の表示方法(safari,Edgeもほぼ同様)
1. 検証ツールを開く
2. 歯車マークから設定を開く
3 「設定」→「要素」→「ユーザーエージェント シャドウDOMを表示」をONにする

【firefox】ShadowDOM の表示方法
1. firefoxブラウザのアドレスバーに「about:config」を入力する
2. 検索欄に「devtools.inspector.showAllAnonymousContent」を入力する
3.「devtools.inspector.showAllAnonymousContent」を「true」に設定する

参考サイト(英語)

ShadowDOMを表示すると下のように表示されます。

② 初期表示部分の変更

ShadowDOMが表示できたら、セレクタ部分をコピーして、
cssを変更させました。
1. テキストを非表示
2. カレンダーアイコンを全体に表示し、どこをクリックしてもカレンダー を開く仕様に変更
併せて、デザインで指定されているアイコンも表示させました。

参考サイト

.form__date {
    position: relative;

    &::before {
        content: "年 / 月 / 日";
        width: 82px;
        height: 22px;
        color: #C2C2C2;
        line-height: 22px;
        position: absolute;
        top: 50%;
        left: 16px;
        transform: translateY(-50%);
        }

   // カレンダーアイコンをinput全体に設定する
    input[type="date"]::-webkit-calendar-picker-indicator {
        width: 100%;
        height: 100%;
        position: absolute;
        opacity: 0;
        top: 0;
        left: 0;
    }

    // 空欄の時、初期表示値を非表示にする
    input[type=date]::-webkit-datetime-edit-fields-wrapper {
        display: none;
    }

    // デザインで指定されているカレンダーアイコンを表示する
    &::after {
        content: "";
        width: 20px;
        height: 20px;
        background: url(../img/08-お問い合わせ/icon-calendar.svg) no-repeat center center / contain;
        position: absolute;
        top: 50%;
        right: 12px;
        transform: translateY(-50%);
        pointer-events: none;
    }
}

結果がこちら👇

カレンダーを表示しても初期表示テキストは浮き出てこない!!
私は思いました… 完璧だ🤗

しかし、ご察しの通り、完璧ではありませんでした…
それがこちら…👇

なんじゃこりゃぁあああああ!!!!!!

Firefoxでは全く適用されていませんでした。
原因は、ShadowDOM内の構造がブラウザ毎で全く違うからです。
先ほどの処理は、chromeで対応したもの、-webkit-にしか適用されていませんでした。(Edge、safariは適用されてる。)

では、Firefoxも同様にセレクタ部分をコピーして、cssを指定すればよいのでは…🤔?と考え、試行錯誤しましたが、結論FirefoxのShadowDOM内を変更することはできませんでした。

どうやらShadowDOMには「open」設定と「closed」設定があり、基本「closed」設定は、内部構造に変更を加えることができないらしい。
少なくとも初心者には無理。

しかし、初期表示テキスト部分は<span>タグで、color: inherit;が指定されているので、<input>タグにcolorを指定すれば反映される。
解決案①の方法を使えば一見綺麗にはできます。

自分にできる限界はここまででした…。

5.解決案③ 最適解

どうしても自分の力では解決できませんでしたので、Twitter(X)で有識者の方に教えていただきました。

① 「placeholder=""」を表示

input[type="date"]の導入部分で、適用されてなかった「placeholder=""」を表示する方法があるようです。

   //  placeholderの値を表示(firefox以外)
    [type="date"] {
        &::before {
            content: attr(placeholder);
            width: 100%;
            color: #C2C2C2;
        }
    }

<input>タグに疑似要素で content: attr(placeholder);と指定すると、なんとplaceholderの値が表示されます。

教えていただいた参考サイト

<input>タグは、疑似要素が適用されないと思っていたので、別の使い方があることに驚きました。きっと自力ではたどり着けなかった知識です🙄

ちなみに、この方法もfirefoxでは適用されません。
もうみんな、chromeで見てよ…🙄

② firefox での表示

input[type="date"]では、ブラウザ毎の初期表示が違うので、デザインの「年 / 月 / 日」は親要素の疑似要素で表示しようと考えてました。そのため、消すことのできない「yyyy/mm/dd」と重複していました。

いろいろ試してみましたが、firefoxの初期表示「yyyy/mm/dd」を完全に消すことはできませんでした。
なので、その条件下で仕様がないデザインで妥協することにしました。

.form__date {
    
    // -webkit-以外のブラウザの場合、空欄の時、初期表示値の色を統一
    input[type="date"] { 
        color: #C2C2C2;
    }

    // デザインで指定されているカレンダーアイコンを表示する
    &::after {
        content: "";
        width: 20px;
        height: 20px;
        background: url(../img/08-お問い合わせ/icon-calendar.svg) no-repeat center center / contain;
        position: absolute;
        top: 50%;
        right: 12px;
        transform: translateY(-50%);
        pointer-events: none;
    }
    
}

/* Firefox用のスタイル設定 */
@-moz-document url-prefix() {
    // デザインで指定されているカレンダーアイコンを非表示にする
    .form__date::after {
        display: none;
    }
}

結果がこちら👇

これで問題はなくなりました。

1.chromeでは、デザイン通りになり、全体のどこをクリックしてもカレンダーが表示されます。
2.firefoxでは、デザイン通りではないですが、見た目に大きな問題はありません。カレンダーはカレンダーアイコンをクリックすれば表示されます。

完成したデザインを比較してみましょう。

・・・。 ・・・🤔
問題ないですよね?これでOKですよね…??

完成です!!!!!!

③ こだわり職人

改めまして、自称「こだわり職人」のあいまるです🐻
ここからは、こだわり職人の方だけ見てください。
②の段階で、十分完成だと思います。

どうでしょう、みなさんは思いましたか…?
「firefoxのカレンダーアイコンの色薄いの、なんか気持ち悪くない?」と。

しかし、firefoxのカレンダーアイコンは、closed設定のShadowDOM内なので、個別で色を変えることも、サイズも位置も変更できません。

実装する方法はこちら👇

/* Firefox用のスタイル設定 */
@-moz-document url-prefix() {
    // カレンダーアイコンを疑似要素で作り、重ねて表示する。
    .form__date::after {
        // display: none;
        width: 16px;
        height: 16px;
        background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.5 2H13V1c0-.6-.4-1-1-1s-1 .4-1 1v1H5V1c0-.6-.4-1-1-1S3 .4 3 1v1h-.5C1.1 2 0 3.1 0 4.5v9C0 14.9 1.1 16 2.5 16h11c1.4 0 2.5-1.1 2.5-2.5v-9C16 3.1 14.9 2 13.5 2zm0 12.5h-11c-.6 0-1-.4-1-1V6h13v7.5c0 .6-.4 1-1 1z"></path></svg>') 
        no-repeat center center / contain;
        top: 50%;
        right: 20px;
        transform: translateY(-55%);
    }
}

先ほどFirefoxでは重複するから不要だと、削除したデザインカレンダー画像をFirefoxのカレンダーアイコンに置き換えるとできます。

Firefoxのカレンダーアイコンは検証ツールで確認したところ、<svg>タグでしたので、コピーしてくれば無事表示されました。
検証ツールで、サイズ、位置を調整した結果が上のコードです。

firefoxのカレンダーアイコンも同様の色合いにする方法
① firefoxの初期表示マークの<svg>をコピー
② firefoxの場合のみ疑似要素の画像を①に変更
③ 検証ツールでサイズと位置を調整してぴったり重ねる

結果がこちら👇

カレンダーアイコンだけ色が濃くなりました。
これで、今度こそ完璧です🤗!お疲れ様でした!!

まとめ

最終的に実装したcssは下記のとおりです。

.form__date {
    position: relative;

    //  placeholderの値を表示(firefox以外)
    [type="date"] {
        &::before {
            content: attr(placeholder);
            width: 100%;
            color: #C2C2C2;
        }
    }

    // カレンダーアイコンをinput全体に設定する
    input[type="date"]::-webkit-calendar-picker-indicator {
        width: 100%;
        height: 100%;
        position: absolute;
        opacity: 0;
        top: 0;
        left: 0;
    }

    // デザインで指定されているカレンダーアイコンを表示する
    &::after {
        content: "";
        width: 20px;
        height: 20px;
        background: url(../img/08-お問い合わせ/icon-calendar.svg) no-repeat center center / contain;
        position: absolute;
        top: 50%;
        right: 12px;
        transform: translateY(-50%);
        pointer-events: none;
    }
    
    &.is-blank {

        // 空欄の時、初期表示値を非表示にする
        input[type=date]::-webkit-datetime-edit-fields-wrapper {
            display: none;
        }

        // -webkit-以外のブラウザの場合、空欄の時、初期表示値の色を統一
        input[type="date"] { 
            color: #C2C2C2;
        }
        
    }

}

/* Firefox用のスタイル設定 */
@-moz-document url-prefix() {
    // カレンダーアイコンを疑似要素で作り、重ねて表示する。
    .form__date::after {
        // display: none;
        width: 16px;
        height: 16px;
        background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.5 2H13V1c0-.6-.4-1-1-1s-1 .4-1 1v1H5V1c0-.6-.4-1-1-1S3 .4 3 1v1h-.5C1.1 2 0 3.1 0 4.5v9C0 14.9 1.1 16 2.5 16h11c1.4 0 2.5-1.1 2.5-2.5v-9C16 3.1 14.9 2 13.5 2zm0 12.5h-11c-.6 0-1-.4-1-1V6h13v7.5c0 .6-.4 1-1 1z"></path></svg>') 
        no-repeat center center / contain;
        top: 50%;
        right: 20px;
        transform: translateY(-55%);
    }
}

カレンダー選択時の動きについては、記載しませんでしたが、上記cssの「.is-blank」をJQuearyで、付け外しして変化させました。

以上が、input[type="date"]についての記録です。
学習中のWeb制作初心者の勉強過程での記録ですので、必要な情報だけ知識として活かしてください。
不明な点、間違っている点あればぜひ教えてください😌

ご閲覧ありがとうございました🍀!


この記事が気に入ったらサポートをしてみませんか?