CSS3 filterでの画像加工
今までPhotoshopで行っていた、ぼかしやグレースケールなどの加工がcssだけで可能になりました。
それにより、フェルタ毎に複数の画像を用意する必要がなくなります。
cssのfilterプロパティで出来る事
- grayscale(グレースケール)
- saturate(彩度)
- sepia(セピア)
- hue-rotate(色相)
- invert(色の反転)
- blur(ぼかし)
- brightness(明るさ)
- contrast(コントラスト)
- drop-shadow(ドロップシャドウ)
grayscale(値)
値:0~100%
備考:値が大きいほど、画像の色が白黒に近づく
saturate(値)
値:0~上限なし
備考:値が大きいほど、色が鮮やかになる。値の上限が無く、例えば10000%という値も設定可能。
sepia(値)
値:0~100%
備考:値が大きいほど、色が黒褐色に近づく。
hue-rotate(値)
値:0deg~360deg(上限・下限なし)
備考:360deg(1周)で元の色に戻る(-360degでも同じ)
invert(値)
値:0~100%
備考:値が大きいほど、写真のネガっぽくなる。
blur(値)
値:0px~上限なし
備考:値が大きいほど、ぼかしの度合いが大きくなる。値の上限が無く、例えば1000pxという値も設定可能
brightness(値)
値:0~上限なし
備考:値が大きいほど、明るさが大きくなる。値を値の上限が無く、0.67といった少数での値を指定可能。ちなみに値を0にすると色は真っ黒になる。
drop-shadow(値1 値2 値3 rgba(値4,値5,値6,値7)
値1~3:下限上限なし
値4~6:0~255
値7:0~上限なし
備考:値1は横方向への影、値2は縦方向への影、値3は影のぼかし具合を表す
値4~6で色の指定する(色の三原色rgb)
値7で明るさを指定する
モバイルファーストでのコーディング
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>北欧家具のECサイトをモバイルファーストでトレース</title> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header> <div class="header-inner"> <h1><img src="img/logo.svg" alt="ロゴ"></h1> <p class="burgur" id="btn"><span></span></p> </div> <nav> </nav> </header> <div class="container"> <div class="main"> <div class="inner"> <div class="photo one"></div> <div class="txt one"></div> </div> <div class="inner reverse"> <div class="photo two"></div> <div class="txt two"></div> </div> <div class="inner"> <div class="photo three"></div> <div class="txt three"></div> </div> <div class="inner reverse"> <div class="photo four"></div> <div class="txt four"></div> </div> </div><!--/.main--> <div class="one-col"></div> <div class="three-col"> <div class="three-col-1"> <div class="three-col-photo"></div> <div class="three-col-txt"></div> </div> <div class="three-col-2"> <div class="three-col-photo"></div> <div class="three-col-txt"></div> </div> <div class="three-col-3"> <div class="three-col-photo"></div> <div class="three-col-txt"></div> </div> </div><!--/.three-col--> <footer></footer> </div><!--/.container--> </body> </html>
@charset "utf-8"; /* CSS Document */ :root { --bg_color: #f0ede7; } /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; box-sizing:border-box; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; } /*モバイルレイアウト*/ body { background:var(--bg_color); } header { height:55px; background:#e4dfd6; margin-bottom:10px; padding:5px; } .header-inner { display:flex; flex-direction:row-reverse; justify-content:space-between; } h1 { width:150px; margin-right:10px; } .burgur { width:60px; height:45px; background:#EB6062; position:relative; } .burgur span { display:block; width:20px; height:2px; background:#444; position:absolute; top:0; right:0; bottom:10px; left:0; margin:auto; } .burgur span:after { content:""; display:block; width:20px; height:2px; background:#444; position:absolute; top:20px; right:0; bottom:0; left:0; margin:auto; } .container { max-width:1366px; margin:0 auto; } .photo { height:30vh; background: url(../img/main01.jpg) no-repeat center center/cover; } div:nth-of-type(2) .photo { background: url(../img/main02.jpg) no-repeat center center/cover; } .photo.three { background: url(../img/main03.jpg) no-repeat center center/cover; } .photo.four { background: url(../img/main04.jpg) no-repeat center center/cover; } .txt { height:60vh; background:#c87f63; margin-bottom:10px; } .txt.two { background:#e1cfb9; } .txt.three { background:#dbdbdb; } .txt.four { background:#FFFFFF; } .one-col { height:80vh; background:#c7a96e; margin-bottom:10px; } .three-col-photo { height:25vh; background:url(../img/3col-01.jpg) no-repeat center center/cover; } .three-col-2>.three-col-photo { background:url(../img/3col-02.jpg) no-repeat center center/cover; } .three-col-3>.three-col-photo { background:url(../img/3col-03.jpg) no-repeat center center/cover; } .three-col-txt { height:50vh; background:#e4dfd6; margin-bottom:10px; } footer { height:80vh; background:#bed5db; } @media screen and (min-width:768px){ header { height:150px; } .container{ padding:0 10px 10px 10px; } .inner { display:flex; flex-wrap: wrap; } .photo { width:calc(66.66% - 5px); height:80vh; margin:0 10px 0 0; background:url(../img/aw18.png) no-repeat 20px 20px, url(../img/main01.jpg) no-repeat center center/cover; } div:nth-of-type(2) .photo { background: url(../img/main02.jpg) no-repeat center center/cover; } .photo.three { background: url(../img/main03.jpg) no-repeat center center/cover; } .photo.four { background: url(../img/main04.jpg) no-repeat center center/cover; } .txt { width:calc(33.33% - 5px); height:80vh; } .inner.reverse { flex-direction:row-reverse; } .inner.reverse .photo { margin:0 0 0 10px; } .three-col-1,.three-col-2,.three-col-3 { display:flex; } .three-col-photo { width:50%; height:60vh; } .three-col-txt { width:50%; height:60vh; } } @media screen and (min-width:901px){ .three-col { display:flex; } .three-col-1,.three-col-2,.three-col-3 { width:calc((100% - 20px) / 3); flex-direction:column; } .three-col-1,.three-col-2 { margin-right:10px; } .three-col-photo { width:100%; height:40vh; } .three-col-txt { width:100%; height:60vh; } }
高機能なフィルタリングjQueryプラグイン 「Shuffle.js」
デモページ
http://yachin29.com/school/shuffle/
$(function() { $('#btn li').on('click', function() { var $this = $(this), $grid = $('#animationList'); $('#btn .active').removeClass('active'); $this.addClass('active'); $grid.shuffle($this.data('group')); }); $('#animationList').shuffle({ group: 'all', speed: 700, easing: 'ease-in-out' }); });
htmlタグを参照文字で書く
<li><a href="img/04.jpg" data-lightbox="photo" data-title="<a href="https://www.kirin.co.jp/" target="_blank">サイトへ"><img src="img/03-thum.jpg" alt=""></a></li>
を参照文字に直すと
<li><a href="img/04.jpg" data-lightbox="photo" data-title="<a href="https://www.kirin.co.jp/" target="_blank">サイトへ</a>">テキスト</a></li>
index.html
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>フィルタリングとモーダルの組み合わせ</title> <style> html,body,h1,ul,li { margin:0; padding:0; } ul { list-style:none; } a { text-decoration:none; color:#222; } img { vertical-align:bottom; } .container { width:840px; margin: 0 auto; } h1 { padding:20px 0; margin-bottom:60px; } .g-nav ul { display:flex; margin-bottom:60px; } .g-nav li { margin-right:20px; } .g-nav li a { display:block; padding:10px; font-size:18px; } .g-nav li a:hover { background:#DDD; } .g-nav li.active { background:#DDD; } .grid li { width:200px; float:left; margin:5px; } </style> <link rel="stylesheet" href="css/lightbox.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="js/jquery.shuffle.min.js"></script> <script src="js/lightbox.js"></script> <script> $(function() { $('#btn li').on('click', function() { var $this = $(this), $grid = $('#animationList'); $('#btn .active').removeClass('active'); $this.addClass('active'); $grid.shuffle($this.data('group')); }); $('#animationList').shuffle({ group: 'all', speed: 700, easing: 'ease-in-out' }); }); </script> </head> <body> <div class="container"> <header> <h1>Shuffle.js</h1> <nav class="g-nav"> <ul id="btn"> <li class="active" data-group="all"><a href="#">all</a></li> <li data-group="html"><a href="#">HTML&CSS</a></li> <li data-group="js"><a href="#">JavaScript</a></li> <li data-group="php"><a href="#">PHP</a></li> <li data-group="banner"><a href="#">バナー</a></li> </ul> </nav> </header> <div class="content"> <ul class="grid" id="animationList"> <li data-groups='["html"]'><a href="img/model1.jpg" data-lightbox="image-1" data-title="<a href=" " target="_blank">サイトへ</a>"><img src="img/00.jpg" alt=""></a></li> <li data-groups='["js"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/02.jpg" alt=""></a></li> <li data-groups='["php"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/03.jpg" alt=""></a></li> <li data-groups='["banner"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/04.jpg" alt=""></a></li> <li data-groups='["php"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/03.jpg" alt=""></a></li> <li data-groups='["js"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/02.jpg" alt=""></a></li> <li data-groups='["html"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/01.jpg" alt=""></a></li> <li data-groups='["html"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/01.jpg" alt=""></a></li> <li data-groups='["banner"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/04.jpg" alt=""></a></li> <li data-groups='["banner"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/04.jpg" alt=""></a></li> <li data-groups='["js"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/02.jpg" alt=""></a></li> <li data-groups='["js"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/02.jpg" alt=""></a></li> <li data-groups='["banner"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/04.jpg" alt=""></a></li> <li data-groups='["php"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/03.jpg" alt=""></a></li> <li data-groups='["html"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/01.jpg" alt=""></a></li> <li data-groups='["js"]'><a href="img/model.jpg" data-lightbox="image-1"><img src="img/02.jpg" alt=""></a></li> </ul> </div> </div> </body> </html>
SEOに適した無限スクロールの制作
SEOに適した無限スクロールの導入
FacebookやTwitter、Pinterestなどのソーシャルメディアサイトが使っている事で一躍有名になった無限スクロール(英: Infinite Scrolling)ですが、今でもシングルページを利用したウェブサイト、特にコンテンツの量が豊富なギャラリー的なサイトではよく見かけます。
しかし、よく見られるjQueryを使ったシンプルな無限スクロールはコンテンツをすべて1つのHTMLファイル上に記述しておいて、スクロールするたびに「display:block」と「display:none」を使って表示させていく、というものです。人が見る分にはこの形でも良いでしょうが、Googlebot に対してとなると話が変わってきます。
ご自身のサイトのニュース フィードやピンボードで、ユーザーの利便性を考えて無限スクロール(英語)を使用している方もいらっしゃるでしょう。しかし、Googlebot に対してとなると話が変わってきます。無限スクロールでは、クローラーがユーザーの行動(スクロールやボタンを押してさらにアイテムを読み込むなど)を常にエミュレートできるとは限らないため、フィードやギャラリー内のすべてのアイテムにアクセスできないことがあります。クローラーがアクセスできないコンテンツは、検索結果に表示されることもないでしょう。
無限スクロール ページからリンクされている個別のアイテムを検索エンジンがクロールできるようにするには、無限スクロールを分割した一連のページ群を生成するようにしましょう。
Google ウェブマスター向け公式ブログ: 検索エンジンとの相性を考慮した無限スクロールのベストプラクティス
pushStateによるブラウザの履歴の更新
pushStateとは?
pushStateとは、HTML5でサポートされるAPIです。
ページを遷移せずHTML(の一部)を変えた場合でもブラウザに履歴を残し、また一意のURLを割り当てることが可能です。HTMLの中身が変わってもAjaxはページを遷移しないのでURLが同じままです(#以下が入れ替わるだけで一意のURLとして処理しない)。
ブラウザの戻るボタンを押しても前のコンテンツを再び表示させることはできません。
本当に前のページに戻ってしまいます。なのでGoogleは、クロール・インデックスできるように特殊な仕様をサポートしてくれたわけです。
しかしpushStateを使えば、Ajaxで変化させたそれぞれのコンテンツに対してユニークなURLを割り当てられるのです。
つまり検索エンジンにとってクロール・インデックスしやすくなります。
Googleの記事では、無限スクロールは次々にページを捲っていく事と同じとしている。そのため、無限スクロールで新しいコンテンツが表示される度にブラウザの履歴(URL)を更新しなければいけない。さらにスクロールでページを進んだり戻ったりする度にURLを更新させる必要があります。
さらにJavaScriptが切れている状態でも手動でページ遷移出来るような設定も取り入れ、検索エンジンとの相性を考慮した無限スクロールにカスタマイズしましょう。
前回の内容を踏まえて、今回は検索エンジンが処理しやすい無限スクロールを作っていきましょう。
ポイント
・無限スクロールページを、JavaScript が無効でもアクセス可能な形にする。
・ページのタイトル・サイトURLの最適化
・コンテンツを細分化する事で表示スピードの向上
特にページのタイトルの最適化は非常に大事です。通常の無限スクロールは1枚のhtmlファイルに無数のコンテンツが記述されていますが、今回のようにhtmlファイルを細分化する事で、コンテンツに応じたより細かいタイトルやURLの設定が可能になります。
デモページ
http://yachin29.html.xdomain.jp/infini-scroll/
<!DOCTYPE HTML> <html lang="ja"> <head> <meta charset="utf-8"> <title>jScroll</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div id="container"> <h1>無限スクロール</h1> <div class="wrapper"> <div class="pic"> <p><img src="img/01b.jpg"></p> </div> <div class="text"> <h3>新・平家物語</h3> <p>『新・平家物語』は、吉川英治の歴史小説の大作。1950年から1957年まで「週刊朝日」に連載された。現行版は吉川英治歴史時代文庫全16巻。<br> 題材は『平家物語』だけでなく、『保元物語』『平治物語』『義経記』『玉葉』など複数の古典をベースにしながら、より一貫した長いスパンで源平両氏や奥州藤原氏、公家などの盛衰を描いた長編作品。</p> </div> </div><!--/.wrapper--> <a href="http://yachin29.webcrow.jp/infini-scroll/book2/" id="next">next</a> </div><!--/#container--> <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script src="js/jquery.clever-infinite-scroll.js"></script> <script> $('#container').cleverInfiniteScroll({ contentsWrapperSelector: '#container', contentSelector: '.wrapper', nextSelector: '#next', }); </script> </body> </html>
Fetch API を使ってみる
フェッチ 【 fetch 】とは
ソフトウェアやネットワーク通信の分野では、データなどの受信側・需要側が(送信側・供給側から送られてくるのを待つのではなく)能動的に読み出しに行く、相手に送信するよう要求する、といった意味合いでフェッチという用語が用いられる。特に、送信側が能動的に送り出す「プッシュ」(push)方式と対比して、一定時間ごとに受信すべきデータの有無を繰り返し確認する受信側の動作を指す場合があり、「ポーリング」(polling)とも呼ばれる。
マイクロプロセッサ(CPU/MPU)では、命令を実行する最初の段階で、命令コード(インストラクション)をメインメモリ(またはキャッシュメモリ)から読み出し、プロセッサ内部のレジスタに転送する動作のことをフェッチという。フェッチされた命令デコード(解析)されて実行に移される。フェッチにかかる時間を「フェッチサイクル」(fetch cycle)あるいは「命令サイクル」(instruction cycle)という。
また、CPUやソフトウェアが将来必要になる(かもしれない)データなどを先取りして読み出しておくことで読み込み動作にかかる待ち時間を削減する手法が様々な分野で幅広く利用されており、そのような「先読み」方式のことを「プリフェッチ」(prefetch)という。
svgデータを外部化するためにsvgファイルをFetchAPIを使って呼び出します。
var box = document.getElementById("box") fetch("logo2.svg") .then(function(response) { return response.text(); }).then(function(svg) { box.innerHTML = svg })
css3を使ったドロワーメニュー
右端から出てくるドロワーメニュー
index.html
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>ドロワーメニュー</title> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="style.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script> $(function(){ $('#btn').on('click',function(){ $('#g-nav').toggleClass('slide'); $(this).toggleClass('click'); }); }); </script> </head> <body> <header> <div class="header-inner"> <h1>タイトル</h1> <p id="btn"><span></span></p> <nav id="g-nav"> <ul> <li><a href="#">ボタン1</a></li> <li><a href="#">ボタン2</a></li> <li><a href="#">ボタン3</a></li> </ul> </nav> </div> </header> <main> </main> </body> </html>
@charset "utf-8"; /* CSS Document */ html,body,h1,p,ul,li { margin:0; padding:0; line-height:1.0; } ul { list-style:none; } a { text-decoration:none; } header { background:#4B4949; width:100%; height:80px; padding:10px 0; box-sizing:border-box; } .header-inner { max-width:1200px; margin:0 auto; display:flex; justify-content:space-between; } h1 { color:#FFFFFF; line-height:60px; padding-left:20px; } #g-nav { width:50%; background:#C71215; } #g-nav ul { display:flex; } #g-nav li { width:33.33%; height:60px; } #g-nav li a { display:block; line-height:60px; text-align:center; color:#FFF; } main { width:100%; height:calc(100vh - 80px); background:url(img/01.png) no-repeat center center/cover; } #btn { display:none; } @media screen and (max-width:767px){ body { overflow-x:hidden; } #g-nav { width:100%; height:calc(100vh - 80px); background:rgba(191,27,30,0.40); position: fixed; top:80px; left:100%; transition:0.3s; } #g-nav.slide { left:0; } #btn { display:block; width:60px; height:60px; margin-right:10px; position:relative; } #btn span { display:block; width:40px; height:2px; background:#FFF; position:absolute; top:0; right:0; bottom:18px; left:0; margin:auto; transition:0.1s; } #btn span:after { display:block; content:""; width:40px; height:2px; background:#FFF; position:absolute; top:36px; right:0; bottom:0; left:0; margin:auto; transition:0.1s; } #btn.click span { bottom:0; transform:rotate(-45deg); } #btn.click span:after { top:0; transform:rotate(-270deg); } #g-nav ul { display:flex; flex-direction:column; margin-left:30%; width:70%; box-sizing:border-box; height:calc(100vh - 80px); background:rgba(0,0,0,0.60); } #g-nav li { width:100%; height:60px; border-bottom:1px solid #FFF; } #g-nav li a { display:block; line-height:60px; padding-left:20px; box-sizing:border-box; text-align:left; color:#FFF; } }