20190318のCSSに関する記事は8件です。

CSSだけで、一方向に無限に流れるスライドショーを作る

作りたいもの

こういうやつ。画像が一方向にずっと流れるアニメーション(下はGIF画像なのでカクカクしているけども)。CodePenにも投稿しています(こちら)。これを、JavaScriptやjQueryのプラグインを使わずに。CSSのみで作ります。
1552899979999.gif

*CodePenを開くと画像がすべて読み込まれておらず、ところどころ空欄になってしまっているときがあるかもしれません。その時は、どこかのコードをコメントアウトにし、表示を更新させてから、そのコメントアウトを外して再度表示を更新させると、画像がすべて表示されるようになるかもしれません。

まずは全部のコード

このスライドショーは、作るのに若干テクニックがいるものです。コードを見ただけで仕組みが分かる人のために、まずは全てのコードを載せておきます。

HTML
<div class="container">
  <div class="slider-container">
    <img src="imgA.jpg" class="slider-img">
    <img src="imgB.jpg" class="slider-img">
    <img src="imgC.jpg" class="slider-img">
    <img src="imgD.jpg" class="slider-img">
    <img src="imgE.jpg" class="slider-img">
    <img src="imgA.jpg" class="slider-img">
    <img src="imgB.jpg" class="slider-img">
    <img src="imgC.jpg" class="slider-img">
    <img src="imgD.jpg" class="slider-img">
    <img src="imgE.jpg" class="slider-img">
  </div>
</div>

同じ画像を2回含めていますが、記述ミスではありません。こうする必要があるのです。

CSS
.container {overflow: hidden;}
:root {
  --numOfListA: 5;
  --imgW: 140px;
  --imgH: var(--imgW);
  --mBetweenImg: 50px;
}
.slider-container {
  display: flex;
  font-size: 0;
  animation: slideshow 15s linear infinite;
}
.slider-img {
  width: var(--imgW);
  height:  var(--imgH);
}
.slider-img + .slider-img {margin-left: var(--mBetweenImg);}
@keyframes slideshow {100% {transform: translateX(calc((var(--numOfListA) * var(--imgW) + var(--mBetweenImg) * var(--numOfListA)) * -1));}}

カスタムプロパティを使用していますが、使用しなくても作れます。修正が楽なので使っているだけです。
では仕組みを解説していきます。

仕組み

文章で説明するよりも実際に動いているのを見た方が分かりやすいでしょう。

下のGIFは、画像3枚を無限スライドショーにした際の動きを簡易的に表したものです。本来ならdiv.containeroverflow: hidden;が指定されていますが、それを指定しないとこういう動きになります。
1552913772314.gif
imgA・imgB・imgCはdiv.slider-containerの中のimgタグ(img.slider-img)を表しています。画像と画像の間はvar(--mBetweenImg)ですね。

ここで、div.containeroverflow: hidden;を指定してやると次のようになります。
1552914354142.gif
これを見ていただければ、なぜ同じ画像を含めているのかが分かっていただけるのではないでしょうか。文章で説明するとややこしくなりそうなので、文章での説明は省略させていただきます。

コードの説明

HTML

HTML
<div class="container">
  <div class="slider-container">
    <!-- リストA -->
    <img src="imgA.jpg" class="slider-img">
    <img src="imgB.jpg" class="slider-img">
    <img src="imgC.jpg" class="slider-img">
    <img src="imgD.jpg" class="slider-img">
    <img src="imgE.jpg" class="slider-img">

    <!-- リストB -->
    <img src="imgA.jpg" class="slider-img">
    <img src="imgB.jpg" class="slider-img">
    <img src="imgC.jpg" class="slider-img">
    <img src="imgD.jpg" class="slider-img">
    <img src="imgE.jpg" class="slider-img">
  </div>
</div>

リストAには、スライドショーで流したい画像を入れてください。
リストBには、リストAの画像を上から同じ順番適当な数だけ含めてください。なぜそうする必要があるのかは、言葉で説明するとややこしくなりそうなので、これもGIF画像を置くだけにとどめておきます。

●もし上から同じ順番にしなかったら
1552915568974.gif

●もしリストBのimgタグの数が不十分だったら
1552915660029.gif

CSS

CSS
.container {overflow: hidden;} /* はみ出す部分を見えなくする */
:root {
  --numOfListA: 5; /* リストAのimgタグの数 */
  --imgW: 140px; /* ここで画像の横幅を指定、px指定を推奨 */
  --imgH: var(--imgW); /* ここで画像の縦幅を指定、px指定を推奨 */
  --mBetweenImg: 50px; /* ここで画像間の余白を指定。px指定を推奨 */
}
.slider-container {
  display: flex; /* 画像を横並びにする */
  font-size: 0; /* 余計な余白を削除 */
  animation: slideshow 15s linear infinite;
}
.slider-img {
  width: var(--imgW);
  height:  var(--imgH);
}
.slider-img + .slider-img {margin-left: var(--mBetweenImg);}
@keyframes slideshow {100% {transform: translateX(calc((var(--numOfListA) * var(--imgW) + var(--mBetweenImg) * var(--numOfListA)) * -1));}} /* 下で説明 */

アニメーションでのtranslateXの値について説明します。

アニメーションでは、div.slider-containerを、0%ではこの状態で・・・
155081659966.jpg
100%ではこの状態に持っていきたい。
155081659966.jpg
ということは、移動量は、リストAの画像の枚数(var(--numOfListA))とimg.slider-imgの横幅(var(--imgW))のと、画像間の余白(var(--mBetweenImg))とリストAの画像の枚数(var(--numOfListA))のの分だけ左に移動すればよい。左に移動するということはX軸の負の方向に移動するということだから、-1をかけてやればよい。

応用

例えば、パソコンサイズの画面では画像をもっと大きく表示させたいという場合は、メディアクエリを使えばいいです。例えばこういう風に。

CSS
@media screen and (min-width: 900px) {:root {--imgW: 180px;}}

下の完成形では、実際にメディアクエリを使用して、画面幅によって画像の大きさを変えています。

完成形

こちらのCodePenに載せています。
下のCSSを追記することで、このスライドショーの仕組みが理解しやすくなるかもしれません。

CSS
body {transform: scale(0.5);}
.container {
  overflow: none;
  border: 5px solid black;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

独自データ属性(カスタムデータ属性)を使ってみた

独自データ属性(カスタムデータ属性)とは

html5で追加されたオリジナルの属性をつくれる仕組み。
data-〇〇=”値”  の形で記述する。〇〇の部分は自分で決められる。
・その値は全角もOK
・先頭に#や.をつけてもOK
・数値もOK
(idやclassでは先頭に数字、もしくは数字だけはNG)

CSS擬似要素のcontentをhtmlからattr()で取得してみた

attr()を使うと、擬似要素に同じスタイリングをしたい場合にコーディングが少なくて済む。
例のごとく下記にコーディング例を示す。

コーディング例

今回はブラウザ表示から。こんな感じの表示にしたい。
芸人のキャッチコピー的なテキストに擬似要素を使い、attr()も使ってみた。
qiitaGeininn.jpg

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>geininn</title>
    <link rel="stylesheet" href="../css/index.css">
</head>
<body>
    <div class="box">
        <div class="img"><img src="./img/kyozin.jpg" alt="オール巨人" width="159" height="212"></div>
        <div class="geininn" data-subtitle="~相方はオール阪神~">オール巨人</div>
    </div>
    <div class="box">
        <div class="img"><img src="./img/hitoshi.jpg" alt="松本人志" width="159" height="212"></div>
        <div class="geininn" data-subtitle="~浜田にしばかれる~">松本人志</div>
    </div>
    <div class="box">
        <div class="img"><img src="./img/emiko.jpg" alt="上沼恵美子" width="159" height="212"></div>
        <div class="geininn" data-subtitle="~えみちゃんねるでお馴染み~">上沼恵美子</div>
    </div>
</body>
</html>
index.css
.box{
    display: inline-block;
}
.geininn{
    font-size: 20px;
    font-weight: bold;
}
.geininn::after{
    content: attr(data-subtitle)"";
    display: block;
    color: #AAA;
    font-size: 15px;
}

参考

css擬似要素のcontentをhtmlからattr()で取得する
HTML5 【data-】 独自データ属性を使おう!

終わりに

結局divで囲んで同じクラス名つけてスタイリングすれば似たような事なのかなとも思いましたが、他の言語も使うようになってくるともっとメリットを感じれるのだろうと予想されるので、このやり方も覚えてこうと思います。

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

jQueryを使わずにHTML+JavaSccipt+CSSでドラックアンドドロップを遊んでみる

jQueryを使わずにHTML + Javascript + CSS でドラックアンドドロップ(dnd)を使った、
画面上でのアイテム編集、追加のサンプルを作ってみました。

アイテム削除機能や表示済みアイテム名編集機能はエラーが発生する箇所があります。

Githubのここに置いています。

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

HTMLとCSSの基礎

1. はじめに

今回はHTML,CSSの基礎を記載する.

タグとは

タグという用語が登場するので簡単に説明します.

<br>

これがタグです.
タグには上のように開始タグのみのものと

<p> これはテストです </p>

のように開始タグ< >と終了タグ</ >をセットで用いるものがあります.
タグによって機能が異なるので,調べて使ってください.

2. 内容

2.1. HTML5の基本構造

base.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Webページタイトル</title>
</head>
<body>
    ここがWebブラウザに表示される部分
</body>
</html>

2.2. 表(テーブル)

table.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Webページタイトル</title>
</head>
<body>
    2019年3月のカレンダー<br><br>
    <table>
        <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
        <tr><td></td><td></td><td></td><td></td><td></td><td>1</td><td>2</td></tr>
        <tr><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td></tr>
        <tr><td>10</td><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td></tr>
        <tr><td>17</td><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td><td>23</td></tr>
        <tr><td>24</td><td>25</td><td>26</td><td>27</td><td>28</td><td>29</td><td>30</td></tr>
        <tr><td>31</td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
    </table>
</body>
</html>

2.3. リンク

link.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Webページタイトル</title>
</head>
<body>
    <h2>そのまま開く場合</h2>
    <a href="http://www.google.com">Google</a><br>
    <a href="http://www.yahoo.co.jp">YAHOO! JAPAN</a><br>

    <h2>新規タブで開く場合</h2>
    <a href="http://www.google.com" target="_blank">Google</a><br>
    <a href="http://www.yahoo.co.jp" target="_blank">YAHOO! JAPAN</a><br>
</body>
</html>

2.4. 画像と動画の表示

同じディレクトリに保存されている画像と動画を表示する.

media.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Webページタイトル</title>
</head>
<body>
    <!-- 動画, 画像のオプション一覧
        src="ファイル名"
        大きさ変更
            width(幅)×height(高さ)
            画面の大きさ(1080×720の場合):width="1080" height="720"
            動画の大きさ(100%×80%の場合):width="100%" height="80%"    ・・・%はウィンドウに対する大きさである
     -->
    <h2>動画一覧</h2>
    <!-- videoタグのオプション一覧
        コントロールインタフェース表示:controls
        自動再生:autoplay
        動画再生不可の画像表示例:poster="test.jpg"
    -->
    <video controls width="50%" height="50%"><source src="sample1.mp4"></video><br>
    <video controls width="720" height="480"><source src="sample2.mp4"></video><br>
    <h2>画像一覧</h2>
    <!-- imgタグのオプション一覧
        画像表示不可のテキスト表示例:alt="これはtest.jpgの画像です"
        表示位置調整:align=""
            alignの値:left,right,top,middle,bottom
     -->
    <img src="sample1.jpg" width="50%" height="50%"><br>
    <img src="sample2.jpg" width="500" height="500"><br>

    <h2>ファイルへのリンク</h2>
    <!--
        文字をリンクにする場合はimgタグを外してテキストにすればよい
        指定ファイル名で保存するリンク例:download="test.jpg"
        downloadはHTML5より実装
    -->
    <a href="sample1.jpg" download><img src="sample1.jpg" width="50%" height="50%"></a>
</body>
</html>

2.5. CSS

スタイルシートの指定には
(1) styleタグ内に指定する方法
(2) タグに直接記述する方法
(3) CSSファイルを別に作成する方法
が存在する.

2.5.1. HTMLに直接埋め込む

上の(1)と(2)の方法で,2.2. に記述したtable.htmlにスタイルシートを指定する.

style.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Webページタイトル</title>
    <style>
        td{
            font-family:ヒラギノ丸ゴ ProN,HG丸ゴシックM-PRO;
            color:red;
            text-align:right;
            font-size:20px;
            border-right:1px solid black;
            border-bottom:1px solid black;
            padding:10px;
        }
    </style>
</head>
<body>
    <p><font size="8" color="blue" face="ヒラギノ丸ゴ ProN W4">2019年3月のカレンダー<br><br></font></p>
    <table>
        <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
        <tr><td></td><td></td><td></td><td></td><td></td><td>1</td><td>2</td></tr>
        <tr><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td></tr>
        <tr><td>10</td><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td></tr>
        <tr><td>17</td><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td><td>23</td></tr>
        <tr><td>24</td><td>25</td><td>26</td><td>27</td><td>28</td><td>29</td><td>30</td></tr>
        <tr><td>31</td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
    </table>
</body>
</html>

2.5.2. CSSファイルを作成する

(3)のように,cssファイルを別に作成する際はHTMLファイルと連携させる必要がある.
連携する際は,HTMLファイルheadタグ内に次のように記述する.ただし,cssファイル名はtest.cssとする.

<link rel="stylesheet" type="text/css" href="test.css">

css ファイルの中身はHTMLファイルの<style></style>の中身の内容をそのまま記述する.

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

Webの仕事をしていない人が個人Webサービスを作ってみて得られた知見

自己紹介

Akahoriと申します。普段はIT業界と関係ない仕事をしていますが、今の仕事があまり面白くなく、
Webサービスを作ることにしました。Webサービスには無限の可能性があるように感じたためです。
最近の世の中のイケイケな会社は大体クラウドとかサービスやっています。
昔、数年SIerでWindows向け業務パッケージソフトを作っていたので基本的なIT知識はあります。

2018年夏ぐらいから書籍を買って勉強をしていましたが、2019年1月にconnpassにて3monthsServiceという
三ヶ月でサービスを開発しようというイベント見つけて参加させてもらったのが開発のきっかけです。感謝!
本記事は、私のようにWebに詳しくない人に向けた内容で、Webエンジニアの皆様には一般的なことかと思われます。
間違っている内容やもっと良い取り組み方があれば教えてもらえると大変助かります。

作ったサービス

EVENT MAP!という、connpassのイベントを地図検索できるサービスを作りました。
技術力の問題でいきなりマネタイズは難しいと考え、自分で使えるサービスであれば良いと考えたためです。
connpass公式サイトだと「東京都」までしか地域が絞れないため、行けないイベントが多いんですよね。
スタートアップの有名な人も、自分か、かなり親しい人が欲しいサービスは作るのに良いと言っています。

初期表示場所は設定ボタンにて東京、大阪、愛知、福岡、座標未登録から選べるようにしました。
検索ワードなども時間短縮のため記録できるようにしています。

https://event-map.info
map.png

動作環境・利用言語

フロントで多く使われており、サーバーサイドも書けるということでJavascriptをまず覚えたいと考えました。
その中で、新しめで書籍なども出ているライブラリとしてReactメインで開発することにしました。
Vue.jsなども迷いましたが、ReactはJavascriptを多く書くとのことで学習として応用が効きやすいと考えたためです。
Reactの勉強自体は開発時に始めたわけではなく、昨年に入門書を2冊読み、少し機能があるTODOアプリが作れるぐらいのレベルでした。
(当然のように、あまり理解していなかったことが後に判明します)

クライアント側言語:React+Redux, Material-UI
サーバー側言語:Node.js (Expressフレームワーク)
サーバー(PaaS):heroku (+mongoDB)
エディタ:Visual Studio Code

得られた知見

スムーズにいく部分でなく、やはり詰まったところから学べることが多いです。

デザイン調整はめちゃくちゃ難しい。最初にHTML/CSSを体系的に学んでおくべき。

CSSといえばmargin padding font-sizeなどの超基礎しか知らないレベルでした。displayによる違いも理解していませんでした。
さらにいきなりReactでMaterial-UIというCSSフレームワークを使ったことと、ReactのJSX記法による混乱もあり、
ページ数が極端に少ないサービスであるにも関わらず、体感上、総開発時間の3-4割の時間をデザイン調整に使ってしまっています。

PC版がようやく出来たと思っても、IEで崩れたり、スマホ対応があったり、さらにスマホ毎に画面サイズは違います。
Chrome、IE11、iPhone XS、iPhone SE、iPadなど、それぞれまともに表示できるようになると別のが崩れたりしていました。
ブラウザの表示倍率が100%でない場合に起こる問題などもありました。これは見なかったことにして難を逃れました。

またデザイン調整に入るのが早すぎたことも時間を取られた原因でした。作っていく内に使い勝手の悪さに自分で気づいたり、
予定していた機能が実は実装できなく削除するなどにより、途中からボタンが増えたり無くなったり移動したりしました。
中盤までは大まかな配置などの段階で留めておき、IEでパーツが別の所にお邪魔していても無視し機能が固まってから調整すべきでした。

CSSは要素同士が影響し合うため、おまじないコピペで解決しないのが難しいところです。
最初に、浅くても体系的にHTML/CSSを学んでいれば開発時間を短縮できたかと思います。

技術的な問題は英語で検索する方が早い

単純に英語と日本語での利用者数の問題もあり、日本語で結果が見つかっても古いバージョンでの解決方法、などということもしばしば。
広く一般的な問題や地域特有の問題以外は、最初から英語で検索した方が早いように感じました。
Chromeの翻訳で雰囲気を掴んで、崩れたところだけ原文を読みました。重要なのはコードなのでこれで十分でした。
日本語の記事で良いのがある場合は、コードの部分は英語であるため検索で引っかかるということもあります。

面倒な作業は評価、利用者の多いライブラリで。しかし実現が難しいこともある

最初はGoogleで適当にライブラリを検索していましたが、適当に選んだものやはり使い勝手が良くないことが多かったです。
試すのにも時間はかかるため、人気のものから試すべきと学びました。

また、日付を取り扱う定番ライブラリとしてMoment.jsというのがあり、とても便利なのですが、
これを知らなかったためJavascriptのDateオブジェクトで直接日付の取扱いを頑張ってしまっていました。
使い勝手悪いなと思う所はみんなが思っており、使いやすいライブラリが存在するかを早めに調べるべきでした。

一方、react-google-mapsというReactのライブラリ経由にてGoogle Maps Javascript APIを利用しマップ部分を
描画していたのですが、最終的にはライブラリを用いずに直接APIを利用し実装しました。
理由としては、納得のいかない挙動や、ライブラリ経由では利用できないAPIがあったことです。
また、利用者もライブラリでは直接のAPIほど多くないために技術的な問題の解決もスムーズにはいきません。
用語で検索しても何も出てこない場合、私のような技術の理解が浅い人は厳しいです。
今回のAPIのような、そのものの利用者が非常に多く使い勝手が良いAPIであれば、直接叩くことを早めに検討すべきでした。

デザインや機能改善以外にもやることは結構ある

想定以上にありました。私が気づいていないこともまだまだありそうです。教えて下さい!

SEO

Google Search Consoleの登録
Google Analyticsの登録
meta description、titleタグ等の設定
Lighthouseなどのツールによるチェック

マーケティング

Twitterカード、OGPの設定
独自ドメイン取得

法律の問題の検討

利用規約、プライバシーポリシーの整備
著作権の問題が生じる可能性のある箇所を再点検

利便性向上

問合せフォームの設置(googleフォーム便利でした)
PWA対応
DBに対する適切なインデックスの設定
DB等のデータ量増加が今後問題になることは無いか検討
適切なコメントを入れておくなどソースコードの保守性向上
SSL対応
CDNの利用検討(無料範囲でも便利でした)

セキュリティ

APIやサーバー、DB、サービスのアクセス許可、制限、保存手法などを見直す
Chromeのデベロッパーツールなどで不要なネットアクセスやコンソールログが無いか見直す
XSSなど広く知られたセキュリティの問題が無いか見直す

サービスをどう見てもらうのかを考える必要がある

なんとなく100人ぐらいに見てもらえて20人ぐらいにたまに使ってもらえるのかと考えていました。
私がTwitterなどのSNSを今更始めたばかりで繋がりが少ないということもありますが、
まず、アクセスしてもらえませんでした。
作っても、見てすらもらえないのでは始まりません。上の方に貼ったURLをスルーしたそこのあなた、作ったのはこれです(涙)

私のようにSNSをあまりやっていなかった場合、学習定着と、繋がりを広げることを兼ねてQiitaに記事を書く、LT登壇するなどアウトプットを増やすことも並行してやるべきだったと感じました。
友人が多い人でも、サービスの潜在顧客と層が異なるのであれば同一の問題を抱えるかもしれないので、早めに考えるべきかもしれません。
ツイートなどで広める場合、リリース時の見せ方も重要かと思いました。個人開発者のサービスリリース時のツイートを50人分集め分析した結果、私の中ではURLと同時に動いてる動画を貼るのがバズりやすいという結論に至りましたが、私はリリース後でしたので時既に遅しでした。ここは一つ、最初のリリースは無かったことに!

この段落は公開2日後の時点で書いていますが、多くの人に見ていただいて感無量です。
「サービス/アプリを作ったらQiitaに記事を書く」ことの重要性はかなり高いと学びました。
今後も積極的に書かせてもらいます。

コミュニティに参加すると開発が捗る

私が参加させてもらっている3monthsServiceのような、
サービス開発のイベント・コミュニティに参加したことで非常に開発が捗ったと感じています。

  1. 開発仲間ができます。
  2. 定期的に進捗を報告しなければということが、開発に対する後押しになります。
  3. どうしても解決できない問題を詳しい人に聞けるかもしれません。(何かお返ししましょう)
  4. 開発で得た知見などを共有できます。
  5. 定期的にお互いレビューを行うことで、UI/UX改善やセキュリティの問題など事前に解決できる可能性があります。

サービス開発はめちゃくちゃ楽しい!

最後になりますが、サービス開発はめちゃくちゃ楽しいです。想定より熱中できます。
特に中盤の、プログラムが動くようになってきたところが最高です。
勉強したい人、稼ぎたい人、就職や転職に役立てたい人、よければ開発しましょう!

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

Clipkitでギャラリーアイテムをカルーセルにする

はじめに

ギャラリーアイテムをカルーセルとして記事詳細ページに実装したいという要望にお応えすることがあったため、本記事でその手法をご紹介します。カルーセルのライブラリーは多数存在しますが、ここでは代表的なSlickを使用した実装方法をご紹介します。サンプルデザインについては、適宜調整してご利用ください。

サンプルデザイン

以下のような感じになります。「>」をクリックすると、次のスライドに進み、「<」をクリックすると、前のスライドに戻ります。それぞれタイトルとコメントが入力できるようになっています。PCでは画像背景をグレーでくり抜き、SPでは上下が画像によって可変になっています。

PCサンプルデザイン

Screenshot 2019-03-14 at 18.28.29.png

SPサンプルデザイン

Screenshot 2019-03-18 at 11.47.59.png

実装例

PCとSP共通準備

layout.html
    <!--SlickのCSSとJSを読み込む-->
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css"/>
    <script type="text/javascript" src="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>

    <!--object-fit(IE対策→PCのみ!)-->
    <script src="{{ site.files | filename: "/theme/default/ofi.min.js" }}"></script>
    <script>$(function () { objectFitImages('.slick-slide .slide-img img') });</script>

<head>...</head>の中に以上のような実装を行います。また、jQueryを読み込んでいることが前提です。SlickにてCSSとJSのファイルをダウンロードしても良いですが、ここでは手っ取り早くCDNを読み込んでいます。PCでは画像のサイズ比率を保持するため、CSSにてobject-fitプロパティを使用しています。IEはobject-fitはに対応しておらず、画像の表示崩を起こすためofi.min.jsというファイルをダウンロードしています。objectFitImages()では該当クラス・IDをDOMで指定しています。全ての画像に適応したい場合は空欄にします。

PC

desktop.html
<div class="slider-container">
    <div class="slider">
        {% assign galleries = item.galleries %}
        {% for gallery in galleries reversed %}
        <div class="slick-slide">
            <div class="slide-img">
                {% if gallery.source_url == empty %}
                    <img data-lazy="{{ gallery.image_medium_path }}" alt="{{ gallery.title }}">
          {% else %}
                    <a href="{{ gallery.source_url }}">
                        <img data-lazy="{{ gallery.image_medium_path }}" alt="{{ gallery.title }}">
                    </a>
                {% endif %}
            </div>
            <div class="page-num"></div>
            <p class="slide-ttl">{{ gallery.title }}</p>
            <p class="slide-cmt">{{ gallery.comment | unescape | auto_link }}</p>
        </div>
        {% endfor %}
    </div>
</div>

<div class="page-num"></div>は空ですが、後に紹介するJSの実装でスライド番号を挿入します。不要でしたら削除してください。{% if gallery.source_url == empty %}...{% endif %}では、出典URLが入力されているならば、<a>タグを表示する仕組みです。

desktop.css
.slider-container {
  position: relative;
}
.slider {
  display: none;
  margin: 0 24px;
  overflow: hidden;
}
.slider.slick-initialized {
  display: block;
}
.slider-arrow {
  position: absolute;
  top: 50%;
  height: 36px;
  margin-top: -18px;  /* 高さの半分だけネガティブマージン */
  margin-left: -15px;
  margin-right: -15px;
  color: #000;
  line-height: 36px;
  font-size: 50px;
  cursor: pointer;
  z-index: 10;  /* 重要 */
}
.slider-prev {
  left: 0;
}
.slider-next {
  right: 0;
}
.slider-arrow.slider-next.fa.fa-angle-right.slick-disabled {
  visibility: hidden;
}
.slider-arrow.slider-prev.fa.fa-angle-left.slick-disabled {
  visibility: hidden;
}
.slick-slide {
  padding: 1.5em 0;
  color: #000;
  text-align: center;
  font-size: 1.1em;
  outline: 0;
  background-color: #fff;
  direction: ltr;
}
.slick-slide p {
  font-size: 12px;
  margin-bottom: 1px;
}
.slide-ttl {
  font-weight: bold;
  color: #000;
}
.slide-cmt {
  text-align: left;
}
.slider-counter {
  font-weight: bold;
  font-style: italic;
  font-size: 18px;
  text-align: center;
  color: #000;
}
.slick-slide .slide-img img {
  max-width: 100%;
  max-height: 100%;
  height: 500px;
  width: auto;
  margin: 0 auto;
  object-fit: contain;
  font-family: 'object-fit: contain;'; /*IE対策*/
}
.slide-img {
  background-color: whitesmoke;
}
desktop.js
var $slider_container = $('.slider-container');

$slider_container.each(function() {

  var $slider = $(this).find('.slider');

  $slider.on('init', function(event, slick) {
    $(this).find('.page-num').append('<div class="slider-counter"><span class="current"></span> / <span class="total"></span></div>');
    $(this).find('.current').text(slick.currentSlide + 1);
    $(this).find('.total').text(slick.slideCount);
  })
  .slick({
    appendArrows: $(this),
    // FontAwesomeのクラスを追加
    prevArrow: '<div class="slider-arrow slider-prev fa fa-angle-left"></div>',
    nextArrow: '<div class="slider-arrow slider-next fa fa-angle-right"></div>',
    infinite: true,
    speed: 300,
    slidesToShow: 1,
    lazyLoad: 'progressive'
  })
  .on('beforeChange', function(event, slick, currentSlide, nextSlide) {
    $(this).find('.current').text(nextSlide + 1);
  })
  .on('afterChange',function(event, slick, currentSlide, nextSlide){
    var slideNum = currentSlide + 1;
  });
});

関数には.eachメソッドを利用し、1記事に複数のギャラリーアイテムが存在しても、お互いの動作に干渉しないようにしています。スライド速度はミリ秒設定です。ここでは、speed: 300(0.3秒)で設定してます。infinite: trueでスライドが無限ループします。falseにすると、有限になります。lazyLoad: 'progressive'でHTMLのdata-lazy属性の箇所で画像遅延読み込み行います。

SP

smartphone.html
<div class="slider-container">
    <div class="slider">
        {% assign galleries = item.galleries %}
        {% for gallery in galleries reversed %}
        <div class="slick-slide">
            <div class="slide-img">
                {% if gallery.source_url == empty %}
                    <img data-lazy="{{ gallery.image_medium_path }}" alt="{{ gallery.title }}">
          {% else %}
                    <a href="{{ gallery.source_url }}">
                        <img data-lazy="{{ gallery.image_medium_path }}" alt="{{ gallery.title }}">
                    </a>
                {% endif %}
            </div>
            <p class="slide-ttl">{{ gallery.title }}</p>
            <p class="slide-cmt">{{ gallery.comment | unescape | auto_link }}</p>
        </div>
        {% endfor %}
    </div>
</div>

特にスマートフォンではデバイスによって、画像の読み込みに非常に時間がかかります。ロード時間短縮のために、画像遅延読み込みdata-lazy属性をsrc属性の代わりに使用します。

smartphone.css
.slider-container {
  position: relative;
  width: 100%;
}
.slider {
  display: none;
  overflow: hidden;
}
.slider.slick-initialized {
  display: block;
}
.slider-arrow {
  position: absolute;
  top: 50%;
  height: 36px;
  margin-top: -18px;  /* 高さの半分だけネガティブマージン */
  margin-left: 5px;
  margin-right: 5px;
  color: #fff;
  line-height: 36px;
  font-size: 40px;
  cursor: pointer;
  z-index: 10;  /* 重要 */
}
.slider-prev {
  left: 0;
}
.slider-next {
  right: 0;
}
.slider-arrow.slider-next.fa.fa-angle-right.slick-disabled {
  visibility: hidden;
}
.slider-arrow.slider-prev.fa.fa-angle-left.slick-disabled {
  visibility: hidden;
}
.slick-slide {
  padding: 1.5em 0;
  color: #000;
  text-align: center;
  font-size: 1.1em;
  outline: 0;
  background-color: #fff;
  direction: ltr;
}
.slick-slide p {
  font-size: 12px;
  margin-bottom: 1px;
}
.slide-ttl {
  font-weight: bold;
  color:#000;
}
.slide-cmt {
  text-align: left;
}
.slider-counter {
  font-weight: bold;
  font-size: 14px;
  text-align: right;
  color: #000;
}
smartphone.js
var $slider_container = $('.slider-container');

$slider_container.each(function() {
  var $slider = $(this).find('.slider');

  $slider.on('init', function(event, slick) {
    $(this).find('.slide-img').append('<div class="slider-counter">【<span class="current"></span> / <span class="total"></span>】</div>');
    $(this).find('.current').text(slick.currentSlide + 1);
    $(this).find('.total').text(slick.slideCount);
  })
  .slick({
    appendArrows: $(this),
    // FontAwesomeのクラスを追加
    prevArrow: '<div class="slider-arrow slider-prev fa fa-angle-left"></div>',
    nextArrow: '<div class="slider-arrow slider-next fa fa-angle-right"></div>',
    infinite: true,
    speed: 50,
    slidesToShow: 1,
    adaptiveHeight: true,
    lazyLoad: 'progressive'
  })
  .on('beforeChange', function(event, slick, currentSlide, nextSlide) {
    $(this).find('.current').text(nextSlide + 1);
  })
  .on('afterChange',function(event, slick, currentSlide, nextSlide){
    var slideNum = currentSlide + 1;

    $(this).find('.current').text(currentSlide + 1);
  });
});

スマホの場合、スライド速度はspeed: 50と設定しています。スマホのデバイスによってはスワイプの感度が非常に悪い機種があるため、推奨設定秒数は100ミリ秒(0.1秒)以下となります。adaptiveHeight: trueで画像の縦幅に応じて、ギャラリーの高さをを変更しています。SPもPCと同様にlazyLoad: 'progressive'でHTMLのdata-lazy属性の箇所で画像遅延読み込み行います。

参考

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

ページジャンプの際fixedされたheaderのズレを修正するcss

GOAL

ページジャンプの際fixedされたheaderのズレを修正するためのcssを追加

how to

step1.ジャンプ先のaタグに"anchor"クラスを追加する

test.html
<a name="#box" class="anchor"></a>

step2.ズレを修正するcssを追加する

test.css
.anchor{
    display: block !important;
    padding-top: 85px !important;
    margin-top: -85px !important;
}

参考サイト

ページ内リンクのジャンプ先の位置を複雑なタグは無しでCSSだけで調整する方法

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

CSS animation で遊び倒す - Conic Gradient Loader -

CSS animation day 55 となりました。
本日は、conic-gradient を使ったアニメーションを作成します。

1. 完成版

See the Pen Conic Glowing Loader by hiroya iizuka (@hiroyaiizuka) on CodePen.

2. 参考文献

1 element rainbow spinner 2017
CSS animation で遊び倒す - Glowing Loading -

3. 分解してみる

❶.
マークアップしましょう。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="css/styles.css" />
  </head>
  <body>
    <div class="container">
      <div class="image">
        <div class="text">Loading...</div>
      </div>
    </div>
  </body>
</html>
styles.scss
body {
  margin: 0;
  padding: 0;
  background: radial-gradient(circle, #333, #111);
}

.container {
  position: relative;
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.image {
  width: 300px;
  height: 300px;
  border-radius: 50%;
  background: #333;
}

.text {
  color: #fffccc;
  text-align: center;
  line-height: 300px;
  font-size: 28px;
  letter-spacing: 3px;
  text-transform: uppercase;
}

スクリーンショット 2019-03-18 7.14.46.png

細かいことですが
body のbackgroundに、radial-gradient を設定すると面白いです。
中心から放射状に同心円を作ることができ、内側を明るく、外側を暗くできます。
表現物が光を発する時に、この効果を使えば、明かりで照らされている様を表現することができます。


❷.
では、conic-gradient を使いましょう。
イメージとしては、前回の記事のように、before クラスと、calc メソッドを使います。

styles.scss
.image {
  position: relative;  //追加
}


.image:before {
  content: "";
  position: absolute;
  top: -4px;
  left: -4px;
  border-radius: 50%;
  z-index: -1;
  background: conic-gradient(orange, yellow, green, cyan, blue, violet, orange);
  width: calc(100% + 8px);
  height: calc(100% + 8px);
}

スクリーンショット 2019-03-18 7.41.41.png

いい感じです。
z-index を外すとこうなってます。

スクリーンショット 2019-03-18 8.39.02.png

円周のグラデーションは、この conic- gradient が最適ですね。


❸.
では、アニメーションとblurテクニックを使いましょう。
また、せっかくなので、img クラスのbackground に、conic-gradient を使いましょう。

styles.scss
.img{
        ・・・
  background: conic-gradient(#333,#222, #111, #222, #333);
}

.image:before,
.image:after {
  content: "";
  position: absolute;
  border-radius: 50%;
  z-index: -1;
  background: conic-gradient(orange, yellow, green, cyan, blue, violet, orange);
  animation: round 2s linear infinite;
}

.image:before {
  top: -1px;
  left: -1px;
  width: calc(100% + 2px);
  height: calc(100% + 2px);

}

.image:after {
  top: -4px;
  left: -4px;
  width: calc(100% + 8px);
  height: calc(100% + 8px);
  filter: blur(10px);
}

@keyframes round {
  100% {
    transform: rotate(360deg);
  }
}

See the Pen Conic Glowing Loader by hiroya iizuka (@hiroyaiizuka) on CodePen.

完成しました。
conic-gradient を使えば、簡単にこういう円周のグラデーションができますね。それでは、また明日〜

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