20191115のCSSに関する記事は9件です。

CSSだけでアコーディオンメニューをつくる。

アコーディオンメニューとは

こんな感じのやつ。ドロップダウンとも言うのかな。

912cffc4f8233a40de97fff072232a33.png

やってみよう!

inputタグのcheckboxを利用します。

xxx.html.erb
<div class="accbox">
   <label for="label1">クリックして表示1</label>
   <input type="checkbox" id="label1" class="cssacc" />
   <div class="accshow">
      <!--ここに隠す中身-->
      <p>
        こんにちは1
      </p>
   </div>
</div>
xxx.scss
.accbox input {
  display: none;/*チェックボックスを隠す*/
}

.accbox .accshow {
    height: 0;/*高さを0に*/
    padding: 0;/*余白を0に*/
    overflow: hidden;/*非表示に*/
    opacity: 0;/*中身を透明に*/
    transition: 0.8s;/*クリック時の動きを滑らかに*/
}

.cssacc:checked + .accshow {
    height: auto;/*クリックで高さを加えて中身を表示*/
    padding: 5px;
    background: #eaeaea;
    opacity: 1;
}

基本の流れは、
①チェックボックスを隠す
②中身を隠す
③クリックしたら中身を表示させる
この3つです。

.cssacc:checked + .accshowは見慣れないと思います。
○ + △とすると
○のすぐ後の要素△のみにCSSをあてるというものです。
この場合、チェックが入ったinputタグのすぐ後のdivタグを表示します。





ではまた!

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

::before,::after 疑似要素の親�要素

<div class='wrapper'>
  <div class='aaa'>
  </div>
</div>

この場合aaaクラスに:before,:afterを付与した場合、疑似要素の親クラスはaaaクラスになる。

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

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

100日チャレンジ161日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

161日目は

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

年末まで毎日webサイトを作り続ける大学生 〜28日目 スライダーを自作する〜

はじめに

こんにちは!最近週末は温泉に通っている@70days_jsです!
今日はスライダーを自作しました。hover時に画像をうっすら白くするところ以外は、何も参考にせず0から作ってみました。
扱う技術レベルは低いですが、同じように悩んでる初心者の方を勇気付けられれば幸いです。
今日は28日目。(2019/11/15)
よろしくお願いします。

サイトURL

やったこと

スライダーを作ってみました。
矢印ボタンか、サムネイルをクリックすれば画像が変わります。
まずはgifでどうぞ↓
test.gif

やったことはだいたいこんな感じです。↓
1. 矢印ボタンのクリックで画像を変更する
2. サムネイルを表示する
3. サムネイルのクリックで画像を変更する
4. 画像hover時に色を変更する

では1から順に書いていきます。

1. 矢印ボタンのクリックで画像を変更する

矢印はfont awesomeを使いました。
htmlはこんな感じです。

    <div class="slider">
        <div id="left"><i class="fas fa-angle-left"></i></div>
        <img id="image" src="day24_image/photo1.jpg" alt="slider">
        <div id="right"><i class="fas fa-angle-right"></i></div>
    </div>

id="left"が左の矢印で、rightが右矢印です。
id="image"の部分で画像を表示しています。

次にjavascriptですが、スライダーに使う画像を配列に入れています。↓

let image = [
    'day24_image/photo1.jpg',
    'day24_image/photo2.jpg',
    'day24_image/photo3.jpg',
    'day24_image/photo4.jpg',
    'day24_image/photo5.jpg'
];

あとは要素を取得して、イベントリスナーをつけて、配列から表示する画像を選んでいます。↓

let img = document.getElementById('image');
let left = document.getElementById('left');
let right = document.getElementById('right');

let count = 0; //現在表示している画像の配列番号
let imageLength = image.length - 1; //4


left.addEventListener('click', imageLeftClick);
right.addEventListener('click', imageRightClick);

function imageLeftClick() {
    if (count === 0) {
        count += imageLength;
    } else {
        count--;
    }
    let src = img.getAttribute('src');
    img.setAttribute('src', image[count]);
}

function imageRightClick() {
    if (count === imageLength) {
        count = 0;
    } else {
        count++;
    }
    let src = img.getAttribute('src');
    img.setAttribute('src', image[count]);
}

let count = 0;が画像表示の肝になっており、右矢印を押せば一つ下の数字の配列番号、左クリックなら一つ上の数字の配列番号を表せるようになっています。
もしcountが0なら配列の長さ分を足し、逆にcountの値が配列分の長さに達していたら0を代入することで画像がループするようにしています。

2. サムネイルを表示する

次にサムネイルの表示ですが、これはidがthumbnailの要素を取得して、javascriptでimg要素を作って、配列の画像をすべて入れて、idがthumnailの要素の下に加えるということをやっています。↓

let thumbnail = document.getElementById('thumbnail');

for (var i = 0; i < image.length; i++) {
    let imgElement = document.createElement('img');
    let src = image[i];
    imgElement.setAttribute('src', src);
    imgElement.setAttribute('class', "thumbnail");
    thumbnail.appendChild(imgElement);
}

途中でclassをセットしていますが、これは画像をリサイズするためのクラスです。

imgElement.setAttribute('class', "thumbnail");

classはあらかじめcssの方で書いておきます。↓

.thumbnail {
    display: inline-block;
    width: auto;
    height: 90px;
    max-width: 100%;
    max-height: 100%;
    border: .1px solid white;
}

以前やったやつですね。max-width: 100%;とmax-height: 100%;をつけると画像がボックス内にうまく収まってくれます。今回はheightの値は指定して、widthが可変になるようにしています。

3. サムネイルのクリックで画像を変更する

次はサムネイルをクリックすると、画像も変わる部分です。

let thumbnailList = document.getElementsByClassName('thumbnail');

for (var i = 0; i < thumbnailList.length; i++) {
    let thumbnail = thumbnailList[i];

    thumbnail.addEventListener('click', function displayImage(e) {
        let src = e.target.getAttribute('src');
        img.setAttribute('src', src);
    });
}

さっきサムネイル画像を生成するときにつけておいたclass(画像をリサイズするためのクラス、thumbnailクラス)を利用します。
全てのサムネイルにthumbnailクラスが付いているのでgetElementsByClassNameで一括取得して、そのあとにfor分でそれぞれのサムネイルにイベントリスナーをつけていきます。
引数にeを渡すことでクリックされた要素を特定し、その要素のsrcを取得し、そのsrcをimg変数(画像を表示させる部分)にセットすることでうまく画像を表示してくれます。

4. 画像hover時に色を変更する

最後に、いまいちスライダー感がなかったのでcssで画像にhoverしたらうっすら白くなる演出を加えてみました。とはいえここのやり方は思いつかなかったのでサイトの記事を参考にさせていただきました。
仕組みは簡単で、例えばこのhtml構造なら↓

    <div class="slider">
        <div id="left"><i class="fas fa-angle-left"></i></div>
        <img id="image" src="day24_image/photo1.jpg" alt="slider">
        <div id="right"><i class="fas fa-angle-right"></i></div>
    </div>

画像を表示させるid="image"の親要素であるclass="slider"の背景を白にします。

.slider {
    background-color: white;
}

その後、画像を表示させるid="image"がhover(擬似クラス)されたらopacityというプロパティで透明度を調整できるので、画像の透明度を少し下げます。↓

#image:hover {
    opacity: .7;
}

これだけで画像は透明になり背景の白が浮かんでくるので、hoverされたら画像がうっすら白くなったように見えます。

感想

やっとwebサイトっぽいもの(スライダー)を作れました。嬉しいです。ただスライダーを調べているうちにカルーセルというものに出くわしました。違いが全く分かりません・・・。という感じで一歩進んで二歩下がりながら頑張っております。この調子で年末にはきちんとしたwebサイトを作れるようになっていたら嬉しいな・・・。

最後までお読みいただきありがとうございます。明日も投稿しますのでよろしくお願い致します。

参考

  1. マウスが載ったときだけ画像を半透明にするCSSの書き方 - スタイルシートTipsふぁくとりー (https://www.nishishi.com/css/translucent-image-opacity.html)

hover時の挙動を参考にさせていただきました。ありがとうございます!

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

スマホ用のJavascript/CSSコンソールを作ったお話

スマホ版ブラウザでPC版Chromeコンソールのようなものが(即座に!)使えればいいのになと思ったので、非常に簡易的なものではありますが、作りました。

ブックマークレットのコード

bookmarklet
javascript:window.outerJsConsole%3D%7Be%3A function(v%2Cf)%7Bvar a%3Ddocument.createElement(v)%3Bif(v%3D%3D"script")%7Ba.setAttribute("type"%2C"text%2Fjavascript")%3Bif(!f)%7Ba.setAttribute("id"%2C"newScriptTag")%3B%7Da.classList.add("OJCscript")%3B%7Delse if(v%3D%3D"style")%7Ba.setAttribute("type"%2C"text%2Fcss")%3Bf %3F a.setAttribute("id"%2C"baseStyleTag")%3A a.classList.add("OJCstyle")%3B%7Delse%7Ba.classList.add("OJCelm")%3B%7Dreturn a%3B%7D%2Calert%3A function(v%2Ccaution)%7Bvar a%3Dnew Date()%2Cah%3Da.getHours()< 10 %3F "0" %2B a.getHours()%3A a.getHours()%2Cam%3Da.getMinutes()< 10 %3F "0" %2B a.getMinutes()%3A a.getMinutes()%2Cas%3Da.getSeconds()< 10 %3F "0" %2B a.getSeconds()%3A a.getSeconds()%2Cb%3Dthis.now %3F "(JS)" %3A "(CSS)"%2Cc%3Dcaution %3F %60 class%3D"OJCcaution"%60 %3A ""%2Cd%3D%60<table%60 %2B c %2B %60><tbody><tr><td style%3D"font-style%3A italic%3Bwidth%3A 6em">%60 %2B ah %2B "%3A" %2B am %2B "%3A" %2B as %2B %60<br><b style%3D"color%3A %23aaa">%60 %2B b %2B %60<%2Fb><%2Ftd><td><pre style%3D"background%3A transparent%3Bborder%3A none%3Bborder-radius%3A 0%3Bfont-family%3A sans-serif">%60 %2B v %2B %60<%2Fpre><%2Ftd><%2Ftr><%2Ftbody><%2Ftable>%60%2Ce%3Ddocument.getElementById("OJCalert")%3Be.innerHTML%3Dd %2B e.innerHTML%3B%7D%2Carea%3A function()%7Bvar a%3Dthis.e("style"%2Ctrue)%2Cb%3Dthis.e("div")%3Ba.innerHTML%3D%60%23OJCconsole %23OJCalert%7Bfont-family%3A sans-serif%3B%7D%23OJCconsole %23OJCalert%7Bposition%3A fixed%3Bbackground%3A %23f0f0f0%3Bborder%3A 1px solid %23aaa%3Bbottom%3A 30vh%3Bfont-size%3A 0.9em%3Bleft%3A 0%3Bpadding%3A 0.75em%3Bheight%3A 5rem%3Bwidth%3A 100%25%3Boverflow-y%3A scroll%3B-webkit-overflow-scrolling%3A touch%3B%7D%23OJCconsole %23OJCalert table%7Bborder-bottom%3A 1px solid %23aaa%3Bdisplay%3A block%3Bpadding%3A 0.5em 0%3B%7D%23OJCconsole %23OJCalert table.OJCcaution%7Bbackground%3A %23fff0f0%3B%7D%23OJCconsole .OJCwrap%7Bposition%3A fixed%3Bbottom%3A 0%3Bleft%3A 0%3Bheight%3A 30vh%3Bwidth%3A 100%25%3B%7D%23OJCconsole .OJCwrap *%7Bposition%3A relative%3Bappearance%3A none%3B-webkit-appearance%3A none%3B-moz-appearance%3A none%3B%7D%23OJCconsole .OJCwrap textarea%7Bborder%3A 1px solid %23aaa%3Bborder-radius%3A 0%3Bfont-size%3A 16px%3Btransform%3A scale(0.8)%3Btransform-origin%3A top left%3Bheight%3A calc((100%25 - 4em)%2F 0.8)%3Bpadding%3A 0.75em%3Bwidth%3A calc(100%25 %2F 0.8)%3B-webkit-overflow-scrolling%3A touch%3B%7D%23OJCconsole .OJCwrap div%7Bdisplay%3A flex%3Bheight%3A 3em%3Bjustify-content%3A center%3B%7D%23OJCconsole .OJCwrap div button%7Bbackground%3A %23b01%3Bborder%3A 1px solid %23fff%3Bcolor%3A %23fff%3Bdisplay%3A block%3Bflex-grow%3A 1%3Bfont-family%3A sans-serif%3Bfont-size%3A 15px%3Bfont-weight%3A bold%3Bpadding%3A 0.5em%3Bwidth%3A 15%25%3B%7D%60%3Bb.setAttribute("id"%2C"OJCconsole")%3Bb.innerHTML%3D%60<div id%3D"OJCalert"><%2Fdiv><div class%3D"OJCwrap"><div><button onclick%3D"outerJsConsole.change(this)%3B" style%3D"background%3A %23065fd4%3B">JS<%2Fbutton><button onclick%3D"outerJsConsole.apply()%3B">apply<%2Fbutton><button onclick%3D"outerJsConsole.code()%3B">code<%2Fbutton><button onclick%3D"outerJsConsole.close()%3B">close<%2Fbutton><%2Fdiv><textarea id%3D"outerJsTgt"><%2Ftextarea><%2Fdiv>%60%3Bdocument.head.appendChild(a)%3Bdocument.body.appendChild(b)%3B%7D%2Cnow%3A true%2Cchange%3A function(v)%7Bvar a%3D(b%2Cc)%3D>%7Bthis.now%3Db%3Bv.innerHTML%3Dc%3B%7D%3Bthis.now %3F a(false%2C"CSS")%3A a(true%2C"JS")%3B%7D%2Capply%3A function()%7Bvar x%3Ddocument.querySelectorAll(".OJCscript%2C.OJCstyle").length%2Ca%3Ddocument.getElementById("outerJsTgt")%3Btry%7Bvar b%3Ddocument.getElementById("newScriptTag")%3Bb.removeAttribute("id")%3B%7Dcatch(e)%7B%7Dvar c%3Dthis.now %3F this.e("script")%3A this.e("style")%2Cd%3Da.value.replace(%2F%5E%5Cn%2B%7C%5Cn%2B%24%2Fg%2C"")%3Bc.innerHTML%3Dd%3Bdocument.head.appendChild(c)%3Bvar y%3Ddocument.querySelectorAll(".OJCscript%2C.OJCstyle").length%3Bif(x !%3D%3Dy)%7Bthis.alert(d)%3B%7D%7D%2Ccode%3A function()%7Bvar a%3Dthis.now %3F document.querySelectorAll(".OJCscript")%3A document.querySelectorAll(".OJCstyle")%3Bif(a.length%3D%3D0)%7Breturn this.alert("No code.")%3B%7Dvar b%3D""%3Bfor(var i%3D0%3Bi < a.length%3Bi%2B%2B)%7Bb %2B%3Da%5Bi%5D.innerHTML %2B "%5Cn"%3B%7Dreturn this.alert(b)%3B%7D%2Cclose%3A function()%7Bwindow.onerror%3D""%3Bvar a%3Ddocument.querySelectorAll(".OJCelm%2C%23baseStyleTag")%3Bfor(var i%3D0%3Bi < a.length%3Bi%2B%2B)%7Ba%5Bi%5D.parentNode.removeChild(a%5Bi%5D)%3B%7Dwindow.outerJsConsole%3D%7B%7D%3B%7D%2Cinit%3A function()%7Bwindow.onerror%3Dfunction(msg%2Curl%2Clinenumber)%7BouterJsConsole.alert(msg %2B "(at%3A " %2B linenumber %2B ")."%2Ctrue)%3Bvar a%3Ddocument.getElementById("newScriptTag")%3Ba.parentNode.removeChild(a)%3Breturn true%3B%7D%3Bthis.area()%3Bthis.now%3Dtrue%3B%7D%7D%3BouterJsConsole.init()%3Bvoid(0);

以上のコードをコピペして登録してください。コピペの際には周りの文章ごと選択してメモ帳などで余分な部分を消すと楽です。iPhoneから見るとコードが全部表示されてしまうようですね…。なんてこった…。

q-1-1.png

ブックマークレットの登録方法は以下のページが詳しいですので、参考までに。

ブックマークレットの登録方法:
https://qiita.com/aqril_1132/items/b5f9040ccb8cbc705d04

見た目/できること

q-1-2.pngq-1-3.png
寿司

ブックマークレットを起動すると、上記のようなコンソールが現れます。

各ボタンの概要:

  • 青いボタン
    • 「JS(JavaScript)」モードと「CSS」モードを切り替えます。
  • apply
    • テキストエリア内のコードを適用します。
  • code
    • これまでに適用したコードを全てリザルトに表示します。
  • close
    • コンソールを閉じます。

JS(JavaScript)モード

特に説明することは無いです。PC版Chromeコンソールのようにオブジェクトの中身を覗いたりといったことは出来ず、ただスクリプトをそのページに追加するだけです。

ただしそのスクリプトに問題があったときは、以下のような警告をリザルトに表示します。

q-1-3.png

この時、そのスクリプトの適用はされません。

Tips: オブジェクトの中身を見たい場合は、alertやJSON.stringify()などを駆使すると良いです。

JavaScript
alert(JSON.stringify(<Object>));

CSSモード

CSSを変更できます。シンプルですね。例えばqiita(このサイト)で使用する場合、

CSS
.it-MdContent {
    color: red;
}

このCSSを適用することで、記事の本文を真っ赤に染め上げることができます。

最後に

ブックマークレットに加工する前のコードを以下に載せます。

JavaScript
window.outerJsConsole = {
    e: function(v, f) {
        var a = document.createElement(v);
        if(v == "script") {
            a.setAttribute("type", "text/javascript");
            if(!f) {
                a.setAttribute("id", "newScriptTag");
            }
            a.classList.add("OJCscript");
        }else if(v == "style") {
            a.setAttribute("type", "text/css");
            f ? a.setAttribute("id", "baseStyleTag") : a.classList.add("OJCstyle");
        }else {
            a.classList.add("OJCelm");
        }
        return a;
    },
    alert: function(v, caution) {
        var a = new Date(),
            ah = a.getHours() < 10 ? "0" + a.getHours() : a.getHours(),
            am = a.getMinutes() < 10 ? "0" + a.getMinutes() : a.getMinutes(),
            as = a.getSeconds() < 10 ? "0" + a.getSeconds() : a.getSeconds(),
        b = this.now ? "(JS)" : "(CSS)",
        c = caution ? ` class="OJCcaution"` : "",
        d = `<table` + c + `><tbody><tr><td style="font-style: italic; width: 6em">` + ah + ":" + am + ":" + as + `<br><b style="color: #aaa">` + b + `</b></td><td><pre style="background: transparent;border: none;border-radius: 0;font-family: sans-serif">` + v + `</pre></td></tr></tbody></table>`,
        e = document.getElementById("OJCalert");
        e.innerHTML = d + e.innerHTML;
    },
    area: function() {
        var a = this.e("style", true),
        b = this.e("div");
        a.innerHTML = `
        #OJCconsole #OJCalert {
            font-family: sans-serif;
        }
        #OJCconsole #OJCalert {
            position: fixed;
            background: #f0f0f0;
            border: 1px solid #aaa;
            bottom: 30vh;
            font-size: 0.9em;
            left: 0;
            padding: 0.75em;
            height: 5rem;
            width: 100%;
            overflow-y: scroll;
                -webkit-overflow-scrolling: touch;
        }
        #OJCconsole #OJCalert table {
            border-bottom: 1px solid #aaa;
            display: block;
            padding: 0.5em 0;
        }
        #OJCconsole #OJCalert table.OJCcaution {
            background: #fff0f0;
        }
        #OJCconsole .OJCwrap {
            position: fixed;
            bottom: 0;
            left: 0;
            height: 30vh;
            width: 100%;
        }
        #OJCconsole .OJCwrap * {
            position: relative;
            appearance: none;
                -webkit-appearance: none;
                -moz-appearance: none;
        }
        #OJCconsole .OJCwrap textarea {
            border: 1px solid #aaa;
            border-radius: 0;
            font-size: 16px;
            transform: scale(0.8);
            transform-origin: top left;
            height: calc((100% - 4em) / 0.8);
            padding: 0.75em;
            width: calc(100% / 0.8);
                -webkit-overflow-scrolling: touch;
        }
        #OJCconsole .OJCwrap div {
            display: flex;
            height: 3em;
            justify-content: center;
        }
        #OJCconsole .OJCwrap div button {
            background: #b01;
            border: 1px solid #fff;
            color: #fff;
            display: block;
            flex-grow: 1;
            font-family: sans-serif;
            font-size: 15px;
            font-weight: bold;
            padding: 0.5em;
            width: 15%;
        }`;
        b.setAttribute("id", "OJCconsole");
        b.innerHTML = `<div id="OJCalert"></div><div class="OJCwrap"><div><button onclick="outerJsConsole.change(this);" style="background: #065fd4;">JS</button><button onclick="outerJsConsole.apply();">apply</button><button onclick="outerJsConsole.code();">code</button><button onclick="outerJsConsole.close();">close</button></div><textarea id="outerJsTgt"></textarea></div>`;
        document.head.appendChild(a);
        document.body.appendChild(b);
    },
    now: true,
    change: function(v) {
        var a = (b,c) => {this.now = b;v.innerHTML = c;};
        this.now ? a(false,"CSS") : a(true,"JS");
    },
    apply: function() {
        var x = document.querySelectorAll(".OJCscript, .OJCstyle").length,
        a = document.getElementById("outerJsTgt");
        try {
            var b = document.getElementById("newScriptTag");
            b.removeAttribute("id");
        }catch(e) {}
        var c = this.now ? this.e("script") : this.e("style"),
        d = a.value.replace(/^\n+|\n+$/g, "");
        c.innerHTML = d;
        document.head.appendChild(c);
        var y = document.querySelectorAll(".OJCscript, .OJCstyle").length;
        if(x !== y) {
            this.alert(d);
        }
    },
    code: function() {
        var a = this.now ? document.querySelectorAll(".OJCscript") : document.querySelectorAll(".OJCstyle");
        if(a.length == 0) {
            return this.alert("No code.");
        }
        var b = "";
        for(var i = 0; i < a.length; i++) {
            b += a[i].innerHTML + "\n";
        }
        return this.alert(b);
    },
    close: function() {
        window.onerror = "";
        var a = document.querySelectorAll(".OJCelm,#baseStyleTag");
        for(var i = 0; i < a.length; i++) {
            a[i].parentNode.removeChild(a[i]);
        }
        window.outerJsConsole = {};
    },
    init: function() {
        window.onerror = function(msg, url, linenumber) {
            outerJsConsole.alert(msg + " (at: " + linenumber + ").", true);
            var a = document.getElementById("newScriptTag");
            a.parentNode.removeChild(a);
            return true;
        };
        this.area();
        this.now = true;
    }
};
outerJsConsole.init();

リザルト用のtableに直接styleを付けたりしていて汚いですが、各サイト毎のCSSに対応する&文字数削減のためのものですので、ご了承ください。

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

checkboxをカスタマイズしたい

html

<div class="checkBox">
    <input type="checkbox" id="hoge">
    <label for="hoge">
        ラベル
    </label>
</div>

SCSS

.checkbox {

    & input[type='checkbox'] {
        display: inline-block;
        vertical-align: middle;
        text-align: center;
        position: relative;
        cursor: pointer;

        appearance: none;
        outline: none;

        width: 20px;
        height: 20px;
        margin: 0;

    }

    // チェックボックスのデザイン
    & input[type='checkbox']::before {
        display: inline-block;
        content: '';
        width: 20px;
        height: 20px;
        background: #fff;
        border: solid 1px $gray-400;
        border-radius: 3px;
        margin: 0;
    }

    // チェックマークのデザイン
    & input[type='checkbox']::after {
        display: inline-block;
        content: '';
        position: absolute;
        left: 7px;
        top: 0px;

        width: 8px;
        height: 16px;
        border-right: 3px solid $main;
        border-bottom: 3px solid $main;
        transform: rotate(45deg);

        // チェックしてないときは隠す
        opacity: 0;
    }

    // チェックするとチェックマークの透明化を解除
    & input[type='checkbox']:checked::after {
        opacity: 1;
    }

    & label {
        display: inline-block;
        vertical-align: middle;
        cursor: pointer;

        line-height: 20px;
        height: 20px;
        margin: 0;
        // margin-left: 4px;
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VScodeを使って簡単にローカルサーバーを立てる

vscode-live-server

VSCodeからボタンひとつでローカルサーバーが立てられる拡張機能です。
https://github.com/ritwickdey/vscode-live-server

良いところ

  1. ボタン一つでお手軽簡単。
  2. hot reloadが有効。

インストール

  1. VSCodeExtensionsからLive Serverで検索
  2. installを押す

使い方

  1. 右下にGo Liveのボタンが増えるので、立ち上げたいhtmlVSCodeで開いてGo Liveを押す
  2. ローカルサーバーが立ち上がる

設定

  • liveServer.settings.root
    • デフォルトは/
    • index.htmlがルートにない場合(例:/src/index.html)デフォルトのままだとjsファイルやcssファイルの参照が404になってしまうので、よしなに設定(例:./src)してあげる。
  • liveServer.settings.port
    • デフォルトは5500
    • よしなに設定
  • liveServer.settings.https
    • デフォルトはfalse
    • httpsの設定も可能

詳細はこちら
https://github.com/ritwickdey/vscode-live-server/blob/master/docs/settings.md

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

ionicのgridで楽々reverse

はじめに

どうも!
今回はionic4で開発をしていてこれはちょっといいなと思った機能をご紹介します
ion-wrap-reverseってご存知ですか?
こいつ痒いところに手が届く機能なんです。

ion-wrap-reverseとは

使い方としてはこう

<ion-content>
  <ion-grid>
    <ion-row class="ion-wrap-reverse">
      <ion-col size="12" size-sm>
        <ion-button color="primary">上だったのに</ion-button>
      </ion-col>
      <ion-col size="12" size-sm>
        <ion-button color="danger">下だったのに</ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

ion-gridclass="ion-wrap-reverse"を追加すると
設定したsizeに合わせてレスポンシブ対応をするんですが、
上下逆になってくれるんです!
cssでも flex-wrap: wrap-reverse;を使えばいけますが
class="ion-wrap-reverse"の方が楽チンで好きですw

デモloxhn-ew1t5.gif

終わりに

ion-wrap-reverseの様なionic特有のクラスっていっぱい有りそうなので
次の記事でまとめやりたいなぁと思います。

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

【実用】CSSでボタンアニメーション

この記事のターゲット

  • CSSはある程度わかる
  • アニメーションはよくわかんない
  • ボタンにちょっとアニメーション乗せてリッチにしたい

最終成果物

これです。
ボタンを押したらちょっと沈んで実際に押してる感じがしますね。

button-anime.gif

実装

大きく分けて以下の手順で進めます。
1. 土台になるhtmlの用意
2. 背景の設定
3. ボタンの配置
4. アニメーション実装

1. 土台になるhtmlの用意

さっくりと。

index.html
<!DOCTYPE html>
<html lang ="ja">
<head>
    <link rel="stylesheet" href="../css/btn.css">
</head>
<body>
    <main class="stage">
        <a class="btn">押すなよ?絶対押すなよ?</a>
    </main>
</body>
</html>

2. 背景の設定

おしゃれにするだけです。
なくてもいいです。

btn.css
* {
  margin: 0;
  padding: 0;
}

/**
* stage
*/
.stage {
  position: absolute;
  width: 100%; height: 100%;
  background-color: rgb(228, 217, 210);
  display: flex;
  justify-content: center;
  align-items: center;
}
.stage:before,
.stage:after { position: absolute; content: ""; display: block; }
.stage:before {
  top: 20px; left: 20px;
  width: calc(100% - 40px); height: calc(100% - 40px);
  border: solid 5px #6e5c60;
  border-radius: 30px;
  box-sizing: border-box;
  opacity: 0.3;
}

スクリーンショット 2019-11-13 9.02.41.png

  1. ボタンの配置 htmlの要素に用意しておいたbtnクラスにボタンっぽいcssを当てましょう。
btn.css
...

/**
* stage
*/

...

/**
* btn
*/

.btn {
  position: absolute;
  cursor: pointer;
  background: #20b2aa;
  margin: 1em auto;
  padding: 20px;
  border-radius: 4px;
  box-sizing: border-box;
  color: #fff;
  text-align: center;
  text-decoration: inherit;
  box-shadow: 0 6px 0 #047c71, 0 12px 0 rgba(0,0,0,.2);
  transition: color .3s, background .3s, box-shadow .3s, transform 0.3s;
}

ここまででこんな感じ。
すでにだいぶそれっぽいですね。

スクリーンショット 2019-11-13 9.04.41.png

4. アニメーション実装

当然ですがこの状態では何をしてもボタンが変化しません。
ここから実際にアニメーションを実装していきます。

btn.css
...

/**
* stage
*/

...

/**
* btn
*/

.btn {
...
}

.btn:hover {
    background: #3cc4bd;
    box-shadow: 0 3px 0 #12978d, 0 6px 0 rgba(0,0,0,.2);
    transform: translateY(3px);
}

.btn:active {
    color: #ddd;
    background: #12978d;
    box-shadow: 0 0 0 #047c71, 0 0 0 rgba(0,0,0,.2);
    transform: translateY(6px);
    transition-duration: .1s;
}

これでhover時とactive時の状態を決め、3つの状態を遷移させることで実現します。

主に利用するのはtransitionというプロパティとtransformというプロパティです。
詳しくみていきましょう。

transition

まずはtransitionについてですが,これはcssの各classやidに付与するプロパティで、そのclassやidが要素に適用された時にどのように適用させるかを設定することができます。
この「どのように」という部分がアニメーションになっていて、ざっくり言えば「パッと切り替える」「じんわり切り替える」といった内容です。

ところで、すでにbtnクラスにはtransitionプロパティが付いていますね。
内容をみてみましょう。

  transition: color .3s, background .3s, box-shadow .3s, transform 0.3s;

ざっくり解説すると、左のプロパティを右の秒数かけて変化させる、という内容です。
ですのでcolor,backgroud,box-shadow,transformが0.3秒かけて変化することになります。
例えば、colorだけ0.3秒ではなく3秒にしてみるとどうでしょうか?
このクラスが適用されるタイミングは今の所リロードのタイミングしかないのでリロードしてみてください。
挙動が変わって文字色だけじんわり変わるようになったと思います。

さて、変化にかける時間しか指定できないのかというとそんなわけもなく、他にも指定できる設定があります。
もともと、transitionに関するプロパティはには以下の4種類があります。
一つずつみていきましょう。

transition-delay

名前の通り、delayを設定します。
1sと指定すればアニメーション開始が1秒後になります。

transition-duration

このプロパティがtransitionプロパティで指定したもので、アニメーションに何秒かけるかという設定です.

transition-property

transition-propetryにはtransitionを適用するプロパティを指定します。
今回で言えばcolorやbackgroundがこれにあたります。
ここで指定したプロパティに対して他の3つのtransitionが適用されることになります。

transition-timing-function

アニメーションの動き方です。
ease, linear, ease-in, ease-out, ease-in-outがあります。

ここまでわかった上でもう一度transitionプロパティをみると、transition-propertyとtransition-durationの組み合わせで指定していることがわかります。

transitionプロパティはこれら4つのプロパティを一度に指定できるもので、引数の順番は以下のようになります。

transition: [transition-property] [transition-duration] [transition-timing-function] [transition-delay]

transform

次にtransformプロパティです。
これはそのclassが適用されている要素を変形させるプロパティです。
一口に変形と言ってもできることはある程度決まっていて、主に使うのは以下のあたりかと思います。
(他にもあるので気になったら調べてみてください。)

  • rotateX()
  • rotateY()
  • rotateZ()
  • translateX()
  • translateY()
  • translateZ()
  • scaleX()
  • scaleY()
  • scaleZ()

今回ではbtn:hoverとbtn:activeでtransformを利用しています。
具体的には以下ですね。

    transform: translateY(3px);

translateY、ということでY軸方向に3px動かすという指定です。
ボタンを押している様子はtranslateYでボタンそのものを動かし、box-shadowの影を相対的に小さくしていくことで実現しているわけです。

まとめ

今回はtransitionとtransformを使ったボタンアニメーションの実装について紹介しました。
サイズや配置場所を直せばすぐにでも使える形になっているかと思われます。
とはいえコピペで配置してしまうとちょっとした変更すらできなくて四苦八苦してしまうので多少なりとも理屈がわかっていると違うのではないかと思います。

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