20200714のHTMLに関する記事は8件です。

【初心者でもわかる】ファビコン(タブにあるアイコン)の簡単な作り方・設定方法

どうも、7noteです。今回はファビコン(favicon)の作り方を初心者でもわかりやすく説明します!

ファビコンって画像があればものの10分くらいで設定できるくらい簡単なんです!
この記事を読みながらでも15分くらいで簡単にできると思うのでやってみてください。

特に最近かな?wordpressで作成されているホームページでファビコンが設定されてないと、デフォルトでwordpressの青いファビコンが強制的につくようになったので、もし「wordpressつかって昔ホームページとかブログ作ったな」という人がいれば、見直してみてください!ファビコンが設定出来ていないかも?!

※ 画像編集ソフトがあると、画像のカスタマイズがしやすくスムーズなので何か用意するのをお勧めします。

ファビコン(favicon)って何?

そもそもファビコン(favicon)って何?と言う人もいると思うので簡単に説明を。

↓これです。
favicon_kore.png

ブラウザのタブに表示されるアイコンのことですね。
複数のタブを開いたりするとさっき見てたサイトどれだっけ?となったことはないですか?
有名なサイトは100%と言ってもいいくらいこのファビコンがついています。
またファビコンはスマホのショートカットのアイコンにも使われるので、世に公開するサイトなら必ず設定しておく方が良いですね。

ファビコンはいわばサイトのシンボルマークと行っても過言ではありません。
それくらい重要なものなので、サイトを作ることになれば必ず←入れてください!

ファビコン(favicon)作成の3ステップ

  1. アイコンにしたい画像を用意
  2. ファビコン作成サイトで、ファビコンを作成
  3. サイトにファビコンを登録

1. アイコンにしたい画像を用意

ファビコンにしたい正方形の画像を用意します。
画像を作成する時は最低でも(16px × 16px)の大きさを用意しましょう。
できればスマホのショートカットアイコン用に(180px × 180px)を用意するのががいいでしょう。

※qiitaのように背景が透明のものはpngかgifをで作成しましょう。
→理由はこちらの記事を参照[【初心者でもわかる】web制作で使われる画像3種類。[.gif]と[.jpg]と[.png]の違い。](https://qiita.com/7note/items/715e33ea8ce43f1c9301)

2. ファビコン作成サイトで、ファビコンを作成

・ Favicon ジェネレーター
https://favicon-generator.mintsu-dev.com/

上記URLにアクセスして作成した正方形の画像を登録すると、自動的に画像データが「favicon.ico」になり、ファビコンが作成されます。

3. サイトにファビコンを登録

ファビコンを設定するにはheadタグの中に以下のように書きます。

index.html
<head>
    <link rel="icon" href="/favicon.ico" /> <!-- ファビコンを設定 -->
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> <!-- アップルタッチアイコンも設定 -->
</head>

ファビコンジェネレータを使うと、一緒にapple-touch-icon.pngも出来たと思うので、こちらも合わせて設定しておきましょう。これを設定することで、iphoneとかでホーム画面にアイコンを保存したら作成した画像が登録されます、

完成・まとめ

いかがでしたか?ちょっと文章多くなったかもしれないので15分では出来なかったという方もいるかもしれませんが、やることは至極簡単なので、1回やって見れば2回目以降は10分くらいでできると思います!
ファビコンジェネレーターは今回紹介したサイト以外にもいろいろあるので、調べてみてください!

おそまつ!

(コメント・質問・ソースの指摘等なんでもウェルカムです!初心者の方でも気軽に質問ください!)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 370日目

100日チャレンジの370日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
370日目は

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】form_withに記述するlocal: trueについて

なぜlocal: trueを記述するのか

railsでフォームを送信する際にform_with以下にlocal: trueを記述するが、
最初は意味も分からずにそういうのなんだろうと深く考えもせずに真似てコードを記述していました。

form_with.png

しかし意味も分からずに学習を進めるのは気持ち悪いため改めて調べて見たところ、
rails5においてはlocal: trueを記述しないとajax通信によるフォームの送信という意味になってしまうためHTMLとしてフォーム送信をする場合はlocal: trueの記述が必要とのことです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Head要素内の記述

meta要素

文書のメタ要素を記述する。

メタ情報には、文書の説明、文字エンコーディングなどが含まる。
meta要素はhead要素内だけで使用される。

title要素

Webページのタイトルを記述する。
検索エンジンの結果ページに一覧表示されるところ。

link要素

スタイルシートなど、外部ファイルを参照する時に使う。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsの環境構築まとめ

Vue.jsというJavaScriptフレームワークを勉強しようと環境構築にちょっと時間がかかってしまったのでフロートしてのこしておきます[Windows]

Vue.jsにちょっと触れてみる

簡単なVue.jsを作成して雰囲気をつかんでみる

CDNで読み込むだけなので簡単に確認できる

<script src="https://unpkg.com/vue"></script>

</head>タグのすぐ上に挿入する

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue.jsサンプル</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <h1>Vue.js</h1>
  <div id="app">
    {{ message }}
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue'
      }
    });
  </script>
</body>
</html>

Hello表示を確認するのに一般的なコードですね

{{ message }}の部分が Hello Vue になって表示されます

なるほどつかいやすそうな気がする

ということで導入していきます

プログラミングの世界には便利なものはまとめて管理しようとする流れがあります

【Vue.js】も【npm】とうパッケージ管理ツールで利用できます

【npm】は【Node.js】というプログラグに組み込まれています

  • 【Node.js】の中の【npm】をつかって【Vue.js】を管理する流れです

まずはNode.jsをダウンロード、インストールしましょう

Node.jsのダウンロード

インストールしたらコマンドプロンプトから【Vue CLI】とインストールしましょう

ディレクトリを移動して下記を入力

npm install -g @vue/cli

ちょっと時間かかります

次に【cli-service-global】ファイルも必要になるのでインストール

npm install -g @vue/cli-service-global

これでVue CLIを使用できます
Vue.jsのコマンドツールなので後々役立つので入れていきましょう

まとめ

構築は比較的簡単な方だったとおもいますがディレクトリの移動や、コマンドを忘れてしまったりと細かいところでつまづきやすいです

メモとして残っていると安心です

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScript カレンダー

前回作成した祝日クラスを使って、サンプルとしてカレンダーを作ってみました。
飾りっ気は無いです。

HTML

index.html
<!DOCTYPE html>
<html lang='ja'>
    <head>
        <meta charset='utf-8'>
        <meta name="viewport" content="user-scalable=no,width=device-width,initial-scale=1">
        <title>Calendar</title>
        <script src='./calendar.js'></script>
        <script src='./holiday_class.js'></script>
        <link rel="stylesheet" href="./calendar.css">
    </head>

    <body>

        <div class='input'>
            <input id='year' type='text' value='' onchange='calendar(this.value)'><input id='prev' type='button' value='-' onclick='prev()'>
            <input id='reset' type='button' value='Reset' onclick='reset()'>
            <input id='next' type='button' value='+' onclick='next()'>
        </div>

        <div class='year'></div>

        <div class='month jan'></div>
        <div class='month feb'></div>
        <div class='month mar'></div>
        <div class='month apr'></div>
        <div class='month may'></div>
        <div class='month jun'></div>
        <div class='month jul'></div>
        <div class='month aug'></div>
        <div class='month sep'></div>
        <div class='month oct'></div>
        <div class='month nov'></div>
        <div class='month dec'></div>

        <div id='m'></div>
    </body>
</html>

JavaScript

calendar.js
const d = new Date();

const today = {
    year: d.getFullYear(),
    month: d.getMonth() + 1,
    day: d.getDate(),
};

function calendar(year = 0) {

    if(isNaN(year) || year < 1 || year > 9999 || year != Math.floor(year))
        year = today.year;

    const holiday = new Holiday(year).getHolidayOfYear();

    // 年
    document.querySelector('.year').innerHTML = `<div class='yearName'>${year}年</div>`;
    document.querySelector('#year').value = year;

    for(let month = 1; month <= 12; month++) {
        d.setFullYear(year, month - 1, 1);
        // 月ラベル
        let monthBlock = '';
        const monthName = d.toDateString().split(' ')[1].toLowerCase();
        monthBlock += `<div class='monthName'>${month}月</div>`;

        // 当月最終日
        d.setFullYear(year, month, 0);
        const lastDay = d.getDate();

        // 当月1日の曜日
        d.setFullYear(year, month -1, 1);
        const firstDayWeek = d.getDay();

        // 曜日ラベル
        monthBlock += "<div class='weekTop'>";
        for(let w = 0; w < 7; w++) {
            const weekName = ['', '', '', '', '', '', ''][w];
            const weekClass = w === 0 ? 'sun' : w === 6 ? 'sat' : '';
            monthBlock += `<div class='d ${weekClass}'><div class='t'>${weekName}</div></div>`;
        }
        monthBlock += "</div>";

        // 月初余白
        if(firstDayWeek) {
            monthBlock += "<div class='weekTop'>" + "<div class='d'></div>".repeat(firstDayWeek);
        }

        // 日付
        for(let day = 1; day <= lastDay; day++) {
            d.setFullYear(year, month - 1, day);
            const w = d.getDay();

            // 土日クラス名
            let weekClass = w === 0 ? 'sun' : w === 6 ? 'sat' : '';
            // 祝日クラス名
            if(holiday[month][day] !== undefined) weekClass += ' holiday';

            // 週初め
            if(w === 0) monthBlock += "<div class='weekTop'>";

            // 祝日名表示用
            const holidayTag = (holiday[month][day] !== undefined) ?
                `<a class='holiday' href='javascript:;' ` +
                    `onmousemove='p1("${holiday[month][day]}")' onmouseout='p0()'>` :
                '';
            monthBlock += holidayTag;

            // 当日クラス名
            const todayClass =
                (today.year === year && today.month === month && today.day === day) ?
                'today' : '';

            monthBlock += `<div class='d ${todayClass} ${weekClass}'><div class='t'>${day}</div></div>`;

            // 祝日閉じ
            monthBlock += (holidayTag !== '') ? '</a>' : '';

            // weekTopの閉じ
            if(w === 6 || day === lastDay) monthBlock += '</div>';
        }

        // DOM更新
        document.querySelector(`.month.${monthName}`).innerHTML = monthBlock;
    }
}

function p1 (str){
    const d = document.querySelector('#m');
    d.textContent = str;
    d.style.top = y + "px";
    d.style.left = x + "px";
    d.style.display = "block";
}

function p0 (){
    const d = document.querySelector('#m');
    d.style.display = "none";
}

let x, y;
onload = function() {
    calendar();
    document.onmousemove = function(e) {
        x = e.pageX - 20;
        y = e.pageY - 40;
    }
    document.ontouchstart = function(e) {
    var to = e.changedTouches[0];
        x = to.pageX - 20;
        y = to.pageY - 64;
    }
}

function prev() {
    calendar(Number(document.querySelector('#year').value) - 1);
}
function next() {
    calendar(Number(document.querySelector('#year').value) + 1);
}
function reset() {
    calendar(today.year);
}

CSS

calendar.css
input[type="text"] {
    width: 48px;
}
input[type="button"] {
    width: 25px;
}
input[type="button"]#reset {
    width: 52px;
}
.input {
    padding-bottom: 10px;
}
a.holiday {
    text-decoration: none;
}
.year {
    padding-bottom: 16px;
}
.yearName {
    margin: 0 auto 0 auto;
}
.month {
    line-height: 150%;
    padding-bottom: 16px;
    display: inline-grid;
    padding-right: 16px;
}
.monthName {
    margin: 0 auto 0 auto;
}
div.d {
    display: inline-grid;
    width: 26px;
}
.t {
    margin: 0 auto 0 auto;
    font-size: 14px;
}
.d.sat {
    color: #4444ff;
}
.d.sun {
    color: #ff4444;
}
.d.holiday {
    color: #ff4444;
    font-weight: bold;
}
.d.today {
    background: #ddddff;
}
#m {
    position: absolute;
    top: 0px;
    left: 0px;
    display: none;
    padding: 4px 12px 4px 12px;
    background-color: #ffffff;
    color: #882222;
    font-size: 14px;
    font-weight: bold;
    border: 1px #884444 solid;
}

他に前回の祝日クラスをholiday_class.jsとして保存したファイルを使います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

作成中の静的ファイルをターミナルからChromeですぐに確認する

何を書いた記事か

HTMLやJavaScriptのファイルを作成していて、それをブラウザ(Chrome)で確認したいとき、ターミナルから一発で確認する方法です。

Vueの勉強をしていて、新規に作成したファイルをわざわざChromeで開くのにFinder操作とかいろいろするのが面倒だったのでターミナルからワンライナーで開けるようにしました。

※MacOSでの操作方法を記載します。

こうなります。
open_in_chrome.gif

どうやるか

そもそも、ターミナルで指定ファイルをChromeで開くのは下記コマンドで実行可能です。

open -a '/Applications/Google Chrome.app' path/to/file

ただ、これをいちいち打っていくのは非常に面倒なので、 ~/.zshrc~/.bashrc などにaliasを定義しておきます。

alias chrome="open -a '/Applications/Google Chrome.app'"

これで、 chrome と打って対象のファイルを指定するだけで、そのファイルをChromeで開くことができるようになります。

chrome path/to/file

まとめ

ちょっとでも楽になる操作はどんどんaliasに突っ込んで行きましょう

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「(HTML) + CSS」のみを使って、今「リアルな電卓」を作ってみた

完成品

まずは、CodePenで完成品を紹介します。ボタンを押して計算を試してみてください。
※ スマホだと反応が悪い場合があります。

See the Pen qiita_calc_last by j5c8k6m8 (@j5c8k6m8) on CodePen.

はじめに

はじめて、CSS カウンター の存在をはじめて知ったときは驚きました。
テーブルの行番号は (必要であればJavaScriptで動的に) HTMLに記載するしか方法がない と思っていたからです。

Qiitaにも、CSSカウンターのサンプルを載せた良記事があります。

ふと、CSSカウンターはどこまでできるのだろうか?という疑問が浮かびました。

インクリメント(≒演算)ができるのであれば、電卓も作れるのか?
ついでに、CSSの記事だからタピオカのようにリアルに作るべきだろう1

という軽い気持ちから、 Qiita夏祭り2020 イベントに乗っかって、
〇〇(言語)のみを使って、今△△(アプリ)を作るとしたら のテーマ記事として作成しました。

解説

以下のステップで電卓を実装していきました。
興味のある部分だけでも読んでください。

  1. 実現方式検討
  2. Pug/SCSSの利用
  3. 演算部分の作成
  4. 表示/非表示の制御
  5. スケルトンの作成
  6. リアルなスタイルの作成
  7. デジタル表示の作成
  8. アニメーションの追加
  9. 最終調整

1. 実現方式検討

CSSカウンターを用いて、足し算引き算 を実現します。

CSSカウンターを用いることで、
 - counter-incrementプロパティ を使用し、HTML中の該当要素数を 数える
 - counter関数 を使用し、(そこまでの)HTML中の該当要素を 表示する
ことができます。

一桁の足し算であれば、実装は簡単です。

ラジオボタンで入力値を作成し、:checked 疑似クラス一般兄弟結合子 を使用し、
チェックされた後続のinputタグの要素数を数える CSSカウンターで実現できます。

See the Pen qiita_calc_1 by j5c8k6m8 (@j5c8k6m8) on CodePen.

複数桁の足し算や引き算 の実現はどうすればよいでしょうか?

CSSカウンターの counter-incrementプロパティ には、
単純に個数を数えるだけでなく、 カウンタに加える値を指定 できます。

カウンターを10増加させる場合の指定
counter-increment: example-counter 10;

これを使えば、複数桁の足し算と引き算も、簡単に実現できます。

See the Pen qiita_calc_2 by j5c8k6m8 (@j5c8k6m8) on CodePen.

電卓を作るうえでは、上記に加えて下記のような工夫が必要ですが、
基本的にはこの応用で作成ができそうです。

  • 桁数や入力数を増やすと、HTMLやCSSの記述が膨大となる
  • 電卓は入力された数字の数に応じて、桁数が変わる
  • 入力状態に合わせた、表示の制御が必要
  • リアルな電卓にするためのCSS作成

2. Pug/SCSSの利用

桁数や入力数を増やすと、HTMLやCSSの記述が膨大となる課題の解決のため、
ループが使用できるPugとSCSSを利用します。
(Code PenでもPugとSCSSが利用できます。)

PugとSCSSはコンパイルすることでHTMLとCSSに変換されます。
なので、PugとSCSSを使ってもタイトルは嘘ではありません。

では早速、PugとSCSSの変数定義/ループ/分岐を利用して、
先ほどの足し算と引き算の例を、0~9文字の9桁で、10個まで演算可能に修正します。
(実際のPugやSCSSの書き方はコードを参照してください。)

See the Pen qiita_calc_3 by j5c8k6m8 (@j5c8k6m8) on CodePen.

なんということでしょう。
HTML: 1,122行 / CSS: 80行 のコードを
Pug: 14行 / SCSS: 18行記載量が約1/40 となりました。

これで、電卓の演算部分のロジックやレイアウトに注力しやすくなりました。

3. 演算部分の作成

では、実際に電卓の演算部分を作成しましょう。

先ほどまでの例では、入力された値(ラジオボタン)に対して、桁を固定していました。

SCSS抜粋
$pow: 1;
@for $digit from 1 through $DIGIT {
  .digit#{$digit}:checked ~ input.digit#{$digit} {
    counter-increment: total #{$pow};
  }
  $pow: $pow * 10;
}

電卓では、先頭桁から入力されるため、以下のように入力された値に応じて、
セレクタを上書きし、桁を変えます。

SCSS抜粋
@for $digit from 1 through $DIGIT {
  $pow: 1;
  @for $digit2 from $digit through $DIGIT {
    @if $digit == $digit2 {
      .digit#{$digit}:checked ~ input.digit#{$digit} {
        counter-increment: total $pow;
      }
    } @else {
      .digit#{$digit2}:checked ~ .digit#{$digit}:checked ~ input.digit#{$digit} {
        counter-increment: total $pow;
      }
    }
    $pow: $pow * 10;
  }
}

また、ディスプレイには合計値だけではなく、入力途中の値も入れる必要があります。

入力途中のカウンタを、入力値別に持つことはできますが、
カウンターはcounter-resetを使わなければ、兄弟要素に対して働くため、
bodyに対して、counter-resetを設定した全体用のカウンターと、
counter-resetを設定しない個別用のカウンターの2つを用意すれば実現できます。

また、カウンターを別に定義すると、counter-incrementのプロパティ自体を、
上書きしてしまい、期待通りに動作しないことに注意して下さい。

これは期待通りに動作しない
body {
  counter-reset: total;
}

省略

.digit#{$digit}:checked ~ input.digit#{$digit} {
    counter-increment: total $pow;
    counter-increment: value $pow;
}
プロパティの値に複数のカウンタの設定を入れること
body {
  counter-reset: total;
}

省略

.digit#{$digit}:checked ~ input.digit#{$digit} {
    counter-increment: total $pow value $pow;
}

先頭桁からの入力と、入力途中の値を表示させると、以下のようになります。

See the Pen qiita_calc_4 by j5c8k6m8 (@j5c8k6m8) on CodePen.

4. 表示/非表示の制御

電卓とするときには、入力されている状態に応じて表示/非表示を切り替える必要があります。

上記の例、入力値毎にdivで区切って親子構造を作成していました。
しかし、CSSセレクタでは親や前の要素の指定がむつかしいため、表示/非表示の制御を考えると、
親子構造ではなく、最上位に入力状態を表すinputを並べ、演算のinputも先頭に移動して
タグの構造を見直し、カウンタも入力値ごとに保持するように修正します。

input群の後ろに、inputと紐づけた入力用のlabel群を用意し、
状態に応じてラベルを非表示にするようなセレクタを記載します。

電卓の C (クリア)は、全体をformタグで囲い、 <input type="reset"/> で実現できます。
電卓の = は、以降の操作を C 以外不可とするため、labelを非表示にする必要がありますが、
既にセレクタが複雑となっているため、CSSの !important 規則を使うことで記載量を減らします。

電卓のボタンに相当する、ラベル、および C には cursor: pointer; プロパティを付与します。

CSSが少し複雑にはなりましたが、表示/非表示を含めると、以下のようになります。

See the Pen qiita_calc_5 by j5c8k6m8 (@j5c8k6m8) on CodePen.

5. スケルトンの作成

さて、演算、表示/非表示制御の部分ができたので、電卓の見た目の作成に入ります。

今回作成するものは、レスポンシブである必要もないため、絶対位置指定とします。
つまり、position: absolute;で各オフセットを指定します。

レイアウトを細かく調整できるように、必要なサイズに関わる情報をSCSSの変数で指定します。

displayで表示する数字は、background-color を指定して、
入力途中の数値を表示するときは、合計の上にかぶせるようにします。

input属性を display: none で隠してしまうと、
CSSカウンターでカウントされなくなってしまうため、ラジオボタンは裏に隠れるように配置します。

入力できていないボタンは、表示されない状態ですが、
次の「リアルなレイアウトの作成」で、表示されるようにします。

See the Pen qiita_calc_6 by j5c8k6m8 (@j5c8k6m8) on CodePen.

6. リアルなスタイルの作成

まずは、色、および、丸みから追加していきます。
携帯やスマホなど、実際の端末は、面取り加工等がされているため、
角々しさをとることで、リアルにしていきます。

イメージとしては、キーボードのような丸みですが、
まずは、定番のCSSで三角を作る方法1 のように、シンプルに単一のタグで、
borderの border-color, border-width, border-radiusを変えることで、
下記のように疑似的に表現します。

border-radius は各角個別に楕円で指定できること、
border-width との差分が内側の radius になるところがポイントです。

See the Pen qiita_calc_part_1 by j5c8k6m8 (@j5c8k6m8) on CodePen.

なお、SCSSの変数を用いて、border-radius の個別指定を行う際は、
以下のように記載すると、 / が変数の割り算になるので注意が必要です。

これは誤り(真ん中が割り算になってしまう)
border-radius: $LEFT $RIGHT $RIGHT $LEFT / $TOP $TOP $BOTTOM $BOTTOM;
こっちが正しい
border-radius: #{$LEFT} #{$RIGHT} #{$RIGHT} #{$LEFT} / #{$TOP} #{$TOP} #{$BOTTOM} #{$BOTTOM};

これを先ほどの、スケルトンに適用すると、下記のようになります。

See the Pen qiita_calc_7 by j5c8k6m8 (@j5c8k6m8) on CodePen.

懐かしい感じになりました。

それではここから、shadowなどを利用して、リアルさを出します。

box-shadowを1つだけ利用すると浮いている感じになってしまうので、
外側と合わせて、内側(inside)も指定することで、ボヤかすような感じにします。

ニューモーフィズム2 を作成するときのように、明るい影と、暗い影を使います。
box-shadow にカンマ区切りで4つ(暗い外側 / 暗い外側 / 明るい外側 / 明るい内側)のスタイルを指定します。

box-shadowは、border内には効果を作らないため、
borderの存在しないbox-shadow用の透明な要素を重ねて効果を付けます。

See the Pen qiita_calc_part_2 by j5c8k6m8 (@j5c8k6m8) on CodePen.

shadowのオプションは、感覚で 調整して、電卓に適用してみましょう。

shadowは別要素で作成するため、直接labelにスタイルを付けていましたが、
labelは透明にして、背景をボタンにするように修正します。

<input type="reset"></input> に対しても、
クリックしてもアウトラインが消えるようなスタイルも追加します。

input[type="reset"] {
    background-color: Transparent;
    border: none;
    outline:none;
}

また、背景色も 白 #fff だと、明るいshadowの効果が表れないため、
背景(bodyのbackground)に薄く色を付けるのに加えます。

光源が左上の想定のため、最前面にも右下に向かって濃くなるよう、
linear-gradient プロパティを使用して半透明のdivも加えます。

See the Pen qiita_calc_8 by j5c8k6m8 (@j5c8k6m8) on CodePen.

リアルにはなってきましたが、ただ、ぼやけているようにも見えるので、
光源の反射のような効果を入れてみます。

詳細は省きますが、borderに沿った要素を重ね、
linear-gradientradial-gradient で反射を重ねます。

radial-gradient に 指定する位置(%) は $ \frac{1}{\sqrt{2}} $ (約0.7) を掛ければつながります。

以下は、重なっている要素がわかりやすいように、borderの色を付けた例です。

See the Pen qiita_calc_part_3 by j5c8k6m8 (@j5c8k6m8) on CodePen.

では、電卓に適用しましょう。

See the Pen qiita_calc_9 by j5c8k6m8 (@j5c8k6m8) on CodePen.

目線が、反射にむかうため、ぼやけている印象が少なくなったと思います。

7. デジタル表示の作成

液晶部分は、デジタル表示にしたいため、 けしかん様の 「DSEG」フォント を幅を
transform プロパティを使用して、電卓風に細くして、使用させていただきました。

「DSEG」フォントの使用
@font-face {
  font-family: "dseg7-classic-mini-bold-italic";
  src: url("https://cdn.jsdelivr.net/npm/dseg@0.45.1/fonts/DSEG7-Classic-MINI/DSEG7ClassicMini-BoldItalic.woff2")
    format("woff2");
}
.dseg {
  font-family: "dseg7-classic-mini-bold-italic";
  transform: scale(0.46, 1);
}

液晶部分の背景は、linear-gradient を少しずらして繰り返すことで、
ざらざら感を出します。

以下は、電卓の液晶背景色を5倍にした例です。

See the Pen qiita_calc_part_4 by j5c8k6m8 (@j5c8k6m8) on CodePen.

液晶部分を追加後は、下記の通りになります。

See the Pen qiita_calc_10 by j5c8k6m8 (@j5c8k6m8) on CodePen.

8. アニメーション追加

ボタンのアニメーションは、凹む動作のため、リアルなスタイルの作成で作成したエフェクトを、
0.2秒かけて、透明化させることで実現します。
押しても意味がないボタンは、カーソルホバー時に禁止カーソルとするため、
ダミーのラベルを一番下に配置し、マウス操作で違和感がないようにします。

See the Pen qiita_calc_11 by j5c8k6m8 (@j5c8k6m8) on CodePen.

9. 最終調整

さて、最終調整です。

電卓として、以下3点の挙動を追加します。

  • 入力中の +- の表示、 = を押した後の表示がディスプレイ上わかるようにする。
  • 桁あふれ時の動作。ブラウザにもよるかもしれないが、CSSカウンターの最大値は 2,147,483,647 と想定される。CSSで数値の判定はできないため、8桁 * 10回の操作を最大とする。
  • 同時押しはブラウザで再現できないが 1, 3, 7, 9, C が順に押された時の挙動を追加する。

See the Pen qiita_calc_12 by j5c8k6m8 (@j5c8k6m8) on CodePen.

冒頭のCodePenは、上記のコンパイル済みの HTML / CSS にしたものになります。

さいごに

「(HTML) + CSS」のみを使って、今「リアルな電卓」を作ってみた

というタイトルの割には、今(新しい技術)は使わなかった。(IE動作未確認だが、IEでも動きそう)

新しい技術を使えば、掛け算や割り算を実現する方法も見つかるかもしれない。

途中、心が折れそうになったが、イベントのおかげで、記事を書ききり、勢いで投稿する。
後半のソースが汚いのと、記事の文章がおかしいのは、今後見直すかもしれない。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む