20210101のCSSに関する記事は3件です。

迎春なので鏡餅をCSSで作った

どうも7noteです。お正月にふさわしいアレをCSSで作りました。

sample.png

ソース

index.html
<div class="kagamimochi">
  <div class="mikan"></div>
  <div class="mochi1"></div>
  <div class="mochi2"></div>
  <div class="kami"></div>
</div>
style.css
.kagamimochi {
  width: 100px;
  text-align: center;
}
.mikan {
  width: 50px;
  height: 40px;
  background: #e88522;
  border-radius: 50%;
  position: relative;
  z-index: 10;
  display: inline-block;
}
.mikan::after {
  content: "";
  width: 15px;
  height: 5px;
  background: linear-gradient(#4f9c5d 50%, #6cb576 50%);
  border-radius: 50%;
  display: inline-block;
  position: absolute;
  top: 0;
  right: 10px;
  transform: rotate(-20deg);
  display: inline-block;
}
.mochi1 {
  width: 80px;
  height: 40px;
  background: #fff;
  border: 1px solid #000;
  border-radius: 50%;
  display: inline-block;
  margin-top: -15px;
  position: relative;
  z-index: 5;
}
.mochi2 {
  width: 100px;
  height: 50px;
  background: #fff;
  border: 1px solid #000;
  border-radius: 50%;
  display: inline-block;
  margin-top: -20px;
  position: relative;
  z-index: 4;
}
.kami {
  width: 92px;
  height: 92px;
  background: #fff;
  border: 5px solid #f00;
  transform: rotateX(45deg) rotateZ(45deg);
  display: inline-block;
  margin-top: -75px;
  position: relative;
  z-index: 1;
}

まとめ

かんたんなイラストならCSSでなんでもできそうな気がしてきますね。
まぁ流行りはSVGのような気もします。。。
また思いついたら他のものも作ってみたいと思います。

おそまつ!

~ Qiitaで毎日投稿中!! ~
【初心者向け】WEB制作のちょいテク詰め合わせ

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

打倒レンダリングブロック!(JavaScript編)

はじめに

CSSやJavaScriptなどの読み込み方法(記述)によってはレンダリングを妨げることとなります。
本記事ではJavaScriptの読み込み(記述)に焦点を当てて、レンダリングブロックの対策について説明します。

レンダリングブロック対策の基本はHTMLをとにかく速く出力することです。
この前提をもとに、対策方法について説明できればと思います。

レンダリングの基本

ブラウザにおけるレンダリングの流れは大まかに以下のようになります。

render01.png

  1. HTMLをパース。
    • DOMツリーを構築する。
    • CSSのマークアップからCSSOMツリーを構築する。
    • JavaScriptを実行する。
  2. DOMとCSSOMを組み合わせてレンダリングツリーを構成する。
  3. 各ノードのビューポート内での正確な位置とサイズをレイアウトする。
  4. 各ノードを画面に描画する。

ページにアクセスしてからデータを読み込んで描画するまでの処理手順をクリティカルレンダリングパスといいます。このフローを最適化することがレンダリングブロックへの対策となり、JavaScriptの読み込み方ひとつで最適化できます。

では具体的にどういったことに気をつければ良いのか、3つに分けて紹介します。

  • 推奨パターン
  • アンチパターン
  • ケースバイケース

推奨パターン

async・defer属性で読み込み

記述に属性がない場合、途中でリソースを見つけるとパースを中断しリソースの読み込み・実行を行います。(これが所謂レンダリングブロックです。)
async・defer属性を付けることで非同期で(HTMLのパース/DOM構築を阻害することなく)読み込めます。
ただし非同期で行われるのは読み込みのみで、リソースの実行はパースが中断されます。

render02.png

async・deferの違いはJavaScriptの実行タイミングにあります。

async:リソースが読み込まれた直後に実行されます。
defer:HTMLパース完了後(DOMContentLoadedの直前)に実行されます。

async属性の特徴

<head>
  <script src="foo.js" async></script>
  <script src="bar.js" async></script>
</head>
<body>...</body>
  • 非同期で読み込まれたあと即座に実行されます。読み込まれたものから実行されるため順番が担保されません。
  • トラッキングコード/計測タグなど、他のJavaScriptに依存しないファイルの読み込みに使用。
  • </body>直前の読み込みでは非同期の利点が活かされないため、<head>内で読み込むこと。

defer属性の特徴

<head>
  <script src="foo.js" defer></script>
  <script src="bar.js" defer></script>
</head>
<body>...</body>
  • 非同期で読み込まれ、HTMLパース完了後(DOMContentLoadedの直前)に実行されます。記載している順番に実行されます。
  • DOMに依存する、他のJSに依存するファイルの読み込みに使用。
  • </body>直前の読み込みでは非同期の利点が活かされないため、<head>内で読み込むこと。

アンチパターン

インラインJS

<head>
  <script>
  setTimeout(function() {document.body.appendChild(document.createElement("div")}, 1000);
  </script>
</head>
<body>
  <p>テキスト1</p>
  <script>
  setTimeout(function() {document.body.appendChild(document.createElement("div")}, 1000);
  </script>
  <p>テキスト2</p>
</body>



推奨しない理由

  • <script>タグ以降のDOMの構築をブロックしてしまう。
  • HTML文書のサイズを肥大化させてしまう。
  • ブラウザのローカルキャッシュが効かない。

render03.png

属性無しで読み込み

<head>
  <script src="foo.js"></script>
</head>
<body>
  <p>テキスト</p>
</body>



推奨しない理由

  • <script>タグ以降のDOMの構築をブロックしてしまう。

render04.png

</body>の直前で読み込み

<head>...</head>
<body>
  <p>テキスト</p>
  <script src="foo.js" async></script>
</body>



推奨しない理由

  • <script>タグ以降のDOMの構築をブロックしてしまう。
  • async・defer属性を付けても、パース終了間近に読み込みを開始するため非同期の利点が活かされない。

render05.png

async・defer属性を両方指定

<head>
  <script src="foo.js" async defer></script>
</head>
<body>...</body>



推奨しない理由

  • syncに対応していないブラウザはdeferで読み込む記述方法だが、現在そんなブラウザはない。

link rel preloadで読み込み

<head>
  <script src="foo.js"></script>
  <link rel="preload" as="script" href="bar.js">
</head>
<body>...</body>



推奨しない理由

  • async・deferで代替できる。
  • ブラウザに依存する記述(IE・FireFoxでは使えない)。

ケースバイケース

Script-injectedでの読み込み

Script-injectedは外部リソース読み込みのソースコードを出力するインラインJSです。(以下の記述を参照)

Script-injected 実行前

<head>
  <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
  new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
  j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
  'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
  })(window,document,'script','dataLayer','GTM-XXXXXX');</script>
</head>
<body>...</body>

Script-injected 実行後

<head>
<script async src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXX"></script>
</head>
<body>...</body>



推奨しない理由

  • 非同期読み込みを実現できるが、インラインJSのため基本は使用しない。
  • Google Tag Managerなどはこのような仕組みだが、計測イベントのタイミングがシビアでなければ外部ファイルにしてasync・defer属性での読み込みも検討するとベター。

まとめとポイント

  • async・defer属性を使用して<head>内で読み込む。(deferは実行順序を保証するが、asyncは保証しない)
  • インラインJSを記述しない。
  • Google Tag Managerなどトラッキングコード/計測タグはケースバイケース。
  • JavaScriptは複数ファイルに分けずに出来る限り結合・圧縮する。(肥大化しすぎるのも問題なので適宜調整する)

参考URL

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

HTML + CSSでリアルなビールを作る

新年あけましておめでとうございます。
今年もよろしくおねがいします。かんぱーい!

Screen Shot 2020-12-31 at 23.51.32.png

完成品はこちら

See the Pen Pure CSS Beer by Nishihara (@Nishihara) on CodePen.

概要

ビールの図形自体は左右対称なので、半分作って残り半分はtransform: scaleX(-1)で反転しています。左半分のHTMLは以下のようになっています。

Screen Shot 2020-12-31 at 23.09.18.png

<div class="beerLeft">
  <div class="beerLeftSkew">
    <div class="beerBody"></div>
    <div class="bubbleTop"></div>
    <div class="beerGlassBottom"></div>
    <div class="beerBodyBottom"></div>
    <div class="beerGlassEdge"></div>
    <div class="bubbleBody"></div>
    <div class="beerBodyTop"></div>
  </div>
</div>

ななめのグラス

ななめの部分はtransform: skew(7deg)で平行四辺形に変形させたあと、親要素(.beerLeft)のoverflow: hiddenで隠しています。.beerLeftSkewでななめに変形させているので、子要素たちも同じようにすべて変形します。

Screen Shot 2020-12-31 at 23.11.12.png

.beerLeft {
  width: 50%;
  height: 100%;
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 0;
}

.beerLeftSkew {
  width: 100%;
  height: 100%;
  transform: skew(7deg);
  transform-origin: 0 0;
  overflow: hidden;
}

上部の泡

泡部分は楕円形と左側(グラスの端)が少しだけ暗い矩形を組み合わせて作っています。filter: blur(5px)を矩形にかけることでぼかして境界をなじませています。
Screen Shot 2020-12-31 at 23.14.22.png

Screen Shot 2020-12-31 at 23.14.28.png

.bubbleTop {
  width: 200%;
  height: 22%;
  position: absolute;
  top: 5%;
  left: 0;
  background-color: mix(#e9e6e1, #e9e6e1, 80%);
  border-radius: 50%;
}

.bubbleBody {
  width: 100%;
  height: 20%;
  overflow: hidden;
  position: absolute;
  top: 15%;
  left: -5%;
  background-image: linear-gradient(
    90deg,
    mix(#d9cfc3, #e9e6e1, 80%) 0%,
    #e9e6e1 30%
  );
  filter: blur(5px);
}

グラスの底

グラスの底はグラデーションで表現しています。左下をborder-radiusで曲線にしています。
Screen Shot 2020-12-31 at 23.22.03.png

.beerGlassBottom {
  width: 100%;
  height: 10%;
  position: absolute;
  top: 89%;
  left: 0;
  border-bottom-left-radius: 35%;
  background-image: linear-gradient(
    90deg,
    #a77619 0%,
    #fffde6 10%,
    #fffef9 30%,
    mix(#fffef9, #dfb336, 80%) 40%,
    #dfb336 55%
  );
  filter: blur(2px);
}

さらにビールの底をビールより少し暗い色で楕円をつくり、ブラーでぼかしています。
Screen Shot 2020-12-31 at 23.24.32.png

.beerBodyBottom {
  width: 208%;
  height: 4%;
  position: absolute;
  top: 87%;
  left: -4%;
  background-color: mix(#fbc80b, #834b00, 80%);
  border-radius: 50%;
  filter: blur(5px);
}

さいごにグラスの底の一番下部のエッジ部分を少し暗い線をいれて屈折を表現します。
Screen Shot 2020-12-31 at 23.26.47.png

.beerGlassEdge {
  width: 200%;
  height: 15%;
  position: absolute;
  top: 84%;
  left: 0%;
  border-bottom: 2px solid #a77619;
  border-radius: 25%;
  filter: blur(2px);
}

泡の底

上部の泡部分の底にも影をつけて立体感をだします。
Screen Shot 2020-12-31 at 23.28.02.png

.beerBodyTop {
  width: 208%;
  height: 8%;
  position: absolute;
  top: 30%;
  left: -4%;
  background-color: mix(#fbc80b, #834b00, 80%);
  border-radius: 50%;
  filter: blur(5px);
}

これでビール本体は完成です。

気泡をいれる

立ち上る気泡をいれていきます。

<div class="beerLeft">
  <div class="beerLeftSkew">
    <div class="beerBody"></div>
    <div class="bubbleTop"></div>
    <div class="beerGlassBottom"></div>
    <div class="beerBodyBottom"></div>
    <div class="beerGlassEdge"></div>
    <div class="bubbles bubbles1"></div>
    <div class="bubbles bubbles2"></div>
    <div class="bubbles bubbles3"></div>
    <div class="bubbles bubbles4"></div>
    <div class="bubbles bubbles5"></div>
    <div class="bubbles bubbles6"></div>
    <div class="bubbleBody"></div>
    <div class="beerBodyTop"></div>
  </div>
</div>

.bubbles要素が泡です。基本的には同じかたちですがアニメーションを少しずつわけています。
Screen Shot 2020-12-31 at 23.32.21.png

.bubbles {
  position: absolute;
  width: 4px;
  height: 4px;
  background-color: #fcd044;
  border-radius: 50%;
  border: 1px solid #c17b11;
  filter: blur(1.5px);
  box-shadow: 0px 2px 1px #af7101;
  animation-name: bubble;
  animation-duration: 1200ms;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  animation-fill-mode: backwards;
  &:before {
    content: "";
    width: calc(100% + 4px);
    height: 100%;
    position: absolute;
    top: -15%;
    left: -2px;
    border-radius: 50%;
    border-bottom: 3px solid #d99b01;
  }
  &:after {
    content: "";
    width: 80%;
    height: 80%;
    position: absolute;
    top: -5%;
    left: 10%;
    border-radius: 50%;
    background-color: #faec87;
  }
}

@keyframes bubble {
  0% {
    transform: translate(0, 0);
    opacity: 1;
  }
  8% {
    transform: translate(10px, -20px);
    opacity: 1;
  }
  100% {
    transform: translate(20px, -300px);
    opacity: 0;
  }
}

泡の作り方はタピオカと同じような作りで、その簡易版です。

アニメーションは左右にゆられながら最後は透明になるアニメーションです。これを開始位置とアニメーションの時間をずらして実行させています。

.bubbles1 {
  top: 72%;
  left: 35%;
}
.bubbles2 {
  top: 75%;
  left: 48%;
  transform: scale(0.6);
  animation-delay: -150ms;
}
.bubbles3 {
  top: 63%;
  left: 57%;
  transform: scale(0.8);
  animation-delay: -350ms;
}
.bubbles4 {
  top: 87%;
  left: 44%;
  transform: scale(0.7);![Screen Shot 2020-12-31 at 23.37.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463699/034bd638-e7fb-0c2e-fc16-5115ac7a45c1.png)

  animation-delay: -550ms;
}
.bubbles5 {
  top: 82%;
  left: 35%;
}
.bubbles6 {
  top: 78%;
  left: 48%;
  transform: scale(0.6);
  animation-delay: -650ms;
}

右半分と微調整

これで半身ができたので、同じようなHTMLで左側もつくります。
Screen Shot 2020-12-31 at 23.37.14.png

<div class="beerRight">
  <div class="beerRightSkew">
    <div class="beerBody"></div>
    <div class="bubbleTop"></div>
    <div class="beerGlassBottom"></div>
    <div class="beerBodyBottom"></div>
    <div class="beerGlassEdge"></div>
    <div class="bubbles bubbles7"></div>
    <div class="bubbles bubbles8"></div>
    <div class="bubbles bubbles9"></div>
    <div class="bubbles bubbles10"></div>
    <div class="bubbles bubbles11"></div>
    <div class="bubbles bubbles12"></div>
    <div class="bubbleBody"></div>
    <div class="beerBodyTop"></div>
  </div>
</div>

気泡は違う動きをさせるので、違う番号を振っています。

最後に底に影を敷いてあげて完成です。
Screen Shot 2020-12-31 at 23.37.54.png

.shadow{
  width: 60%;
  height: 25px;
  box-shadow: 0px 12px 35px 25px #b1850e;
  border-radius: 50%;
  position: absolute;
  left: 20%;
  bottom: 2%;
}

beer_animation.gif

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