20190227のCSSに関する記事は6件です。

div要素全体にリンクをつける方法

div要素全体にリンクをつけたい時の方法メモ
自分用に簡潔にまとめる。

See the Pen div要素全体にリンクをつける方法 by iwato (@iwato) on CodePen.

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

【JS不要】CSSだけで入力欄フォーカス時に消えるプレースホルダーを実装する

お問い合わせフォームなどの入力欄にプレースホルダーを入れておきつつ、いざユーザーが入力しようとして入力欄をフォーカスしたらプレースホルダーが消えるようにする機能の実装方法メモ。
CSSだけで実装可能です。以下のコードをFoundationレイヤーのファイルなどにコピペして使ってください。
transitionは好みで入れているだけなので消してしまっても構いません(あるとフワッと文字が消えるので、ちょっとだけイケてる印象になります)。

sample.scss
// 入力欄にフォーカスした時、プレースホルダーを非表示にする。
input:focus::placeholder,
textarea:focus::placeholder {
    color: transparent;
    transition: .1s;
}
// Chrome・Safari用
input:focus::-webkit-input-placeholder,
textarea:focus::-webkit-input-placeholder {
    color: transparent;
    transition: .1s;
}
// Firefox18以前用
input:focus:-moz-placeholder,
textarea:focus:-moz-placeholder {
    color: transparent;
    transition: .1s;
}
// Firefox19以上用
input:focus::-moz-placeholder,
textarea:focus::-moz-placeholder {
    color: transparent;
    transition: .1s;
}

【参考記事】
『placeholder(プレースホルダ)の表示とCSSでの装飾方法 [ホームページ作成] All About』
https://allabout.co.jp/gm/gc/23942/

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

CSS animation で遊び倒す - Beautiful Button -

CSS animation day37 となりました。
毎日記事を投稿しているせいで、画像アップロード制限(100MB月)されました。

大変申し訳ないのですが、解除されるまで、画像は極力抑えて、codesandobox で随時貼り付けてお届けいたします。

これから数回にわたり、microinteraction で使えるボタンを作っていきます。
前回割と好評だった太陽の表現方法、blur + gradient color を使い、ボタンをお届けします。

1. 完成版

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

2. 参考文献

Glowing Gradient Button Animation Effects on Hover Using Html and CSS - CSS Animation Effects

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="button">
        Button
      </div>
    </div>
  </body>
</html>
styles.scss
body {
  background: #fff;
  margin: 0;
  padding: 0;
}

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

.button {
  width: 300px;
  height: 100px;
  text-align: center;
  line-height: 100px;
  color: #000;
  font-size: 24px;
}


                 Button

というものができました。


❷.
ボタンにグラデーションをつけましょう。

styles.scss
.button {
  width: 300px;
  height: 100px;
  text-align: center;
  line-height: 100px;
  color: #fff;
  font-size: 24px;
  border-radius: 30px;
  background: linear-gradient(90deg, #5433ff, #a5fecb, #20bdff, #5433ff);
  background-size: 400%;
}

ポイントは2つ
background-size で大きな値を設定し、ボタンの色をgradientの3色のうちの、単色だけ表にでるように設定します。
・linear-gradientの色設定で、最初(#5433ff)と最後(#5433ff)を同じ色にしましょう。
これは、アニメーションで色が変化するときに、0% → 100% まではスムーズに変化しますが、
また100% → 0% に戻るときに全く違う色でれば、変な境界の線が一本入り、デザインを損ないます。
アニメーションの移行をスムーズにするための一工夫ですね。


❸.

ボタンにhoverしたら、色が変化するようにしましょう。

styles.scss
.button {
  width: 300px;
  height: 100px;
  text-align: center;
  line-height: 100px;
  color: #fff;
  font-size: 24px;
  border-radius: 30px;
  background: linear-gradient(90deg, #5433ff, #a5fecb, #20bdff, #5433ff);
  background-size: 400%;

  &:hover {
    animation: changeColor 8s linear infinite;
  }
  @keyframes changeColor {
    0% {
      background-position: 0%;
    }
    100% {
      background-position: 400%;
    }
  }
}

See the Pen Glowing Button (Explanation) by hiroya iizuka (@hiroyaiizuka) on CodePen.

background-position を、hover で変化させることで、あらかじめliear-gradientで設定していた色が全て表に出てくるようになります。面白いですね。


❹.
beforeクラスで、blur を設定し、表現力をつけましょう。
参考文献のテクニックを、もろパクリします。

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

.button:before {
  content: "";
  position: absolute;
  top: -5px;
  left: -5px;
  right: -5px;
  bottom: -5px;
  z-index: -1;
  border-radius: 30px;
  background: linear-gradient(90deg, #5433ff, #a5fecb, #20bdff, #5433ff);
  background-size: 400%;
  filter: blur(20px);
}

今あるボタンに、全周的に5px 一回り大きな、擬似要素をつけます。
(このCSSの表現方法には、大変感銘を受けました。)
そして、そこに、filterをつけました。

最後に、このfilterのついた一回り大きくなった要素を、hoverで出現し、色が変化するようにしましょう。

styles.scss
.button {
  position: relative;
  width: 300px;
  height: 100px;
  text-align: center;
  line-height: 100px;
  color: #fff;
  font-size: 24px;
  border-radius: 30px;
  background: linear-gradient(90deg, #5433ff, #a5fecb, #20bdff, #5433ff);
  background-size: 400%;

  &:hover {
    animation: changeColor 8s linear infinite;

    &:before {
      opacity: 1;
      animation: changeColor 8s linear infinite;
    }
  }
  @keyframes changeColor {
    0% {
      background-position: 0%;
    }
    100% {
      background-position: 400%;
    }
  }
}

.button:before {
  content: "";
  position: absolute;
  top: -5px;
  left: -5px;
  right: -5px;
  bottom: -5px;
  z-index: -1;
  border-radius: 30px;
  background: linear-gradient(90deg, #5433ff, #a5fecb, #20bdff, #5433ff);
  background-size: 400%;
  filter: blur(20px);
  opacity: 0;
  transition: 0.5s;
}

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

完成しました! 
いやはや、こういう表現方法を最初に考えた人は、天才ですね・・・。 

それでは、また明日〜

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

stylelintの導入方法と各ルール解説

フロントエンドエンジニアの松田です。
先日、副業で開発に参加しているFindyでstylelintの導入を行ったので、導入方法と各ルールについてまとめてみました。

stlyelintとは

eslint, tslint等と同じようなCSSのlinterです。導入することによって、詳細度や!importantの使用制限など、CSSがカオスになってしまうのを防いでくれる効果があります。

導入方法(技術面)

User Guideに書かれているように、stylelintを利用する方法は幾つかあります。チーム開発する場合はCLIツールとして導入し、npm scriptsで実行できるようにするのが良いでしょう。各種CIツールで実行する際にも便利です。

インストール

他のCLIツールと同様にnpmもしくはyarnでパッケージを追加し、package.jsonのscriptsで実行できるようにしましょう。

npm install stylelint --save-dev
// or
yarn add -D stylelint
package.json
"scripts": {
  "lint:css": "stylelint **/*.scss",
}

導入方法(運用面)

stylelintはデフォルトではルールが設定されていないので、とりあえず導入だけしてルールを広げていくという方法がとれます。prettierなどの場合はデフォルトでもある程度ルールが決まっているので、導入の際にはルールを無効化しておいて徐々に有効化していくことが必要になりますが、stylelintではその必要はありません。

まずは導入してCIツールなどの設定をしておき、徐々にルールを拡張してきましょう。

Findyのstylelint設定

Findyではこの記事の執筆時点(2019/2/26)で、以下のルール設定になっています。まだ導入はしたばかりで、導入の際にチェックしたかった簡単なルールしか設定していませんが、徐々に拡張していきたいと考えています。

FindyではSCSSを使っているため、プラグインを追加してSCSSのルールも設定できるようにしています。

stylelintrc.json
{
  "plugins": [
    "stylelint-scss"
  ],
  "rules": {
    "color-no-invalid-hex": [true],
    "color-named": "never",
    "color-hex-case": ["lower"]
  }
}

各ルールについて

ルールごとの導入敷居

Possible errosは、そもそもCSSが機能していない部分を指摘するルールなので比較的導入が容易です。しかしPossible errosで指摘されている箇所が発生している場合は、修正の際に影響箇所の調査を必要とする場合があるので、導入ハードルはかなり上がります。ここでエラーが出ているルールは後回しにしておきましょう。

Limit language featureとStylistic issuesについては、表記の変更だけ(color-hex-lengthなど)のルールが多く、スタイル崩れが発生しづらいので導入が容易です。導入してもwarningが発生しない箇所から導入していき、warningが出る箇所については影響範囲を調査しつつ地道に導入していくのが良いでしょう。

ここからは各ルールの内容解説になります。

Possible erros

Color

color-no-invalid-hex
16進数表記が正しいかチェックしてくれます。

/* NG */
.ng { color: #00; }
/* OK */
.ok { color: #000; }

Font family

font-family-no-duplicate-names
指定が重複していないかチェックしてくれます。

/* NG */
.ng { font-family: sans-serif, sans-serif; }
/* OK */
.ok { font-family: sans-serif; }

font-family-no-missing-generic-family-keyword
sans-serifなどの一般的な使えるようなフォントを1つ以上指定しないとエラーになります。もちろんフォントがない場合は使えるフォントで自動的に表示されるため、文字自体が消えることはないですが、明示的に書きましょうというルールです。

/* NG */
.ng { font-family: Times; }
/* OK */
.ok { font-family: Times, sans-serif; }

Function

function-calc-no-invalid
calc()の表記が間違っていないかをチェックしてくれます。

/* NG */
.ng { width: calc(100% -20px); }
/* OK */
.ok { width: calc(100% - 20px); }

function-calc-no-unspaced-operator
calc()の演算子の左右にスペースが入っているかをチェックしてくれます。
NGパターンでも一見すると動作するように見えますが、スペースが入っていないとダメです。

/* NG */
.ng { width: calc(100%+20px); }
/* OK */
.ok { width: calc(100% + 20px); }

function-linear-gradient-no-nonstandard-direction
linear-gradientの表記が間違っていないかチェックしてくれます。
toが入っていない、同じ位置が指定されている、などがエラーの対象です。

/* NG */
.ng1 { background: linear-gradient(top, #fff, #000); }
.ng2 { background: linear-gradient(to top top, #fff, #000); }
/* OK */
.ok { background: linear-gradient(to bottom right, #fff, #000); }

String

string-no-newline
文字列の途中で改行が入っていないかをチェックしてくれます。CSSには文字列連結がないため、改行はできません。

/* NG */
.ng {
  content: "first
    second";     
}  
/* OK */
.ok { content: "first\\nsecond";  }

Unit

正しい単位が使われているかをチェックしてくれます。

/* NG */
.ng { width: 200pixels; }
/* OK */
.ok { width: 200px; }

Property

property-no-unknown
存在しないプロパティが使われていないかをチェックしてくれます。

/* NG */
.ng { widt: 200px; }
/* OK */
.ok { width: 200px; }

Keyframe declaration

keyframe-declaration-no-important
keyframeで!importantが使われていないかをチェックしてくれます。
ブラウザによって、keyframe内の!important指定が無視される場合があります。

/* NG */
@keyframes important1 {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(100px) !important;
  }
}
/* OK */
@keyframes important1 {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(100px);
  }
}

Declaration block

declaration-block-no-duplicate-properties
同一セレクタ内で同じプロパティが使われていないかをチェックしてくれます。displayやfont-sizeなどのコピー&ペーストでヒューマンエラーが出やすく、エラーになる場合もあるかもしれません。

/* NG */
.ng {
  display: block;
  display: inline-block;
}
/* OK */
.ok { display: block; }

declaration-block-no-shorthand-property-overrides

/* NG */
.ng {
  padding-left: 10px;
  padding: 20px;
}
/* OK */
.ok {
 padding: 20px;
 padding-left: 10px;
}

Block

block-no-empty
セレクタ指定内にプロパティがない場合にエラーになります。

/* NG */
.ng { }
/* OK */
.ok { width: 200px; }

Selector

selector-pseudo-class-no-unknown
擬似クラスの名前があっているかをチェックしてくれます。

/* NG */
.ng:hoverr { }
/* OK */
.ok:hover { }

selector-pseudo-element-no-unknown
擬似要素の名前があっているかをチェックしてくれます。

/* NG */
.ng::beforee { }
/* OK */
.ok::before { }

selector-type-no-unknown
存在しないHTML要素を指定していないかをチェックしてくれます。

/* NG */
aa { }
/* OK */
a { }

Media feature

media-feature-name-no-unknown
メディアクエリの指定が正しいかチェックしてくれます。

/* NG */
@media screen and (unknown) {}
/* OK */
@media screen and (min-width: 700px) {}

At-rule

at-rule-no-unknown
@で始まる指定が正しいかどうかチェックしてくれます。

/* NG */
@unknown {}
/* OK */
@charset "UTF-8";

Comment

comment-no-empty
空のコメントがないかチェックしてくれます。

/* NG */
/* */
/* OK */
/* Comment */

General / Sheet

no-descending-specificity
以下のような指定がないかチェックしてくれます。NGの.ng aは次の行の指定で無効化されてしまうため、意味のない指定になってしまいます。

/* NG */
.ng a { }
a { }
/* OK */
a { }
.ok a { }

no-duplicate-at-import-rules
同一ファイルをimportしていないかチェックしてくれます。

/* NG */
@import 'a.css';
@import 'a.css';
/* OK */
@import 'a.css';
@import 'b.css';

no-duplicate-selectors
重複セレクタがないかをチェックしてくれます。

/* NG */
.ng .ng1 { }
.ng .ng1 { }
/* OK */
.ok .ok1 { }
.ok1 .ok { }

no-empty-source
CSSファイルが空でないかをチェックしてくれます。

no-extra-semicolons(Autofixable)
セミコロンが重複していないかをチェックしてくれます。

no-invalid-double-slash-comments
//で始まるコメントがないかをチェックしてくれます。

Limit language features

Color

color-named
"always-where-possible"では色名をつける、"never"では色名をつけないことを強制します。必ずしも色名がついているカラーコードだけが使われているわけではなく、表記が混在してしまうので、neverがオススメです。

/* NG */
.ng { color: black; }
/* OK */
.ok { color: #000; }

Function

function-blacklist
function-whitelist
オプションによってscaleなどの関数の利用を制限できます。

function-url-no-scheme-relative
//example.comのような//で始まるURL指定がないかをチェックしてくれます。

function-url-scheme-blacklist
function-url-scheme-whitelist
オプションによってURLのscheme制限ができます。

Keyframes

keyframes-name-pattern
正規表現によってkeyframeの名前を制限できます。

Number

number-max-precision
小数点以下の桁数を制限できます。

Time

time-min-milliseconds
時間を指定する場合の最小ミリ秒を制限できます。早すぎるアニメーションが実装されてしまうことを防ぐことができます。

Unit

unit-blacklist
unit-whitelist
em, remなどの特定の単位のしようを制限できます。

Shorthand property

shorthand-property-no-redundant-values (Autofixable)

/* NG */
.ng { margin: 1px 1px 1px 1px; }
/* OK */
.ok { margin: 1px; }

Value

value-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

Custom property

custom-property-pattern
正規表現でカスタムプロパティの名前を制限できます。

Property

property-blacklist
property-whitelist
プロパティの使用を制限できます。

property-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

Declaration

declaration-block-no-redundant-longhand-properties

/* NG */
.ng {
  padding-top: 1px;    
  padding-right: 2px;    
  padding-bottom: 3px;    
  padding-left: 4px;    
}
/* OK */
.ok { padding: 1px 2px 3px 4px; }

declaration-no-important
!importantが使われていないかをチェックできます。ユーティリティクラスを集めたファイルなど、特定の箇所でのみ無効化すると良いでしょう。既存のプロジェクトに導入するのは現実的にかなり難しいので、新規プロジェクトの初期段階で設定しておきましょう。

declaration-property-unit-blacklist
declaration-property-unit-whitelist
declaration-property-value-blacklist
declaration-property-value-whitelist
特定のピクセル指定や、プロパティと値の設定を制限できます。

Declaration block

declaration-block-single-line-max-declarations
1行に設定できるプロパティの数を制限できます。設定する場合は1にしましょう。

Selector

selector-attribute-operator-blacklist
selector-attribute-operator-whitelist
selector-class-pattern
selector-combinator-blacklist
selector-combinator-whitelist
selector-id-pattern
特定のセレクタ指定を制限できます。combinatorは+などの演算子のことです。

selector-max-attribute
selector-max-class
selector-max-combinators
selector-max-compound-selectors
selector-max-empty-lines
selector-max-id
selector-max-pseudo-class
selector-max-specificity
selector-max-type
selector-max-universal
1つのセレクタ指定で使える最大値を指定できます。
compound-selectorsは.a .bなどクラスの連結の回数、specificityは詳細度の制限、typeはaなどのタグ指定の回数制限を、universalは*の回数を制限できます。

selector-max-typeはスタイル崩れを防ぐためにかなり有効です。spanタグなどの指定を使っていると、HTMLの構成を変更してspanタグではなくなってしまった場合にスタイルが崩れてしまいますが、selector-max-typeをチェックしておくと事前に防げます。

selector-max-specificityで詳細度の上限を決めておけば、複雑なCSSになることを防げます。

selector-nested-pattern
ネストのパターンを指定できます。通常のCSSではネストを使った場合はエラーになります。

selector-no-qualifying-type
aタグなどタグ指定を一切できないようにします。特定のファイル内でのみ無効化しておくと良いでしょう。

selector-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

selector-pseudo-class-blacklist
selector-pseudo-class-whitelist
selector-pseudo-element-blacklist
selector-pseudo-element-whitelist
擬似クラス、擬似要素の制限ができます。

Media feature

media-feature-name-blacklist
media-feature-name-whitelist
media-feature-name-value-whitelist
メディアクエリの指定を制限できます。

media-feature-name-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

Custom media

custom-media-pattern
正規表現でカスタムメディアクエリのパターンを指定できます。

At-rule

at-rule-blacklist
at-rule-whitelist
@ルールの制限ができます。

at-rule-no-vendor-prefix
ベンダープレフィックスが書かれていないかをチェックしてくれます。バージョン管理するソースにはベンダープレフィックスを含めずに書いて、autoprefixerを使って自動追加するようにしましょう。

Comment

comment-word-blacklist
正規表現でコメントの文言を制限できます。TODOを残さないようにする、などが可能です。

General / Sheet

max-nesting-depth
ネストの最大深さを設定できます。

no-unknown-animations
keyframeで定義されていないアニメーション名を使用していないかチェックしてくれます。

Stylistic issues

Color

color-hex-case((Autofixable))
color-hex-length((Autofixable))
16進数の大文字小文字(lower or upper)、長さ(short or long)の指定ができます。

Font family

font-family-name-quotes
スペースが含まれるフォントをクォートで囲むかどうかを指定できます。

Font weight

font-weight-notation
"numeric"にすると700などの数値指定を、"named-where-possible"にするとboldなどの名前での指定を強制できます。フォントによってはboldの数値が700でない場合もあるので、設定するなら"named-where-possible"が良いでしょう。

Function

function-comma-newline-after (Autofixable)
function-comma-newline-before (Autofixable)
function-comma-space-after (Autofixable)
function-comma-space-before (Autofixable)
function-max-empty-lines(Autofixable)
function-name-case(Autofixable).
function-parentheses-newline-inside(Autofixable)
function-parentheses-space-inside (Autofixable)
function-url-quotes
function-whitespace-after(Autofixable)
概ね名前の通りですが、表記のスタイルをチェックしてくれます。

Number

number-leading-zero (Autofixable)
1未満の数の表記を制御できます。"always"なら0.5, "never"なら.5を強制できます。これはどちらでも良いでしょう。

number-no-trailing-zeros(Autofixable)
1.0など数字が0で終わっていないかをチェックしてくれます。

String

string-quotes(Autofixable)
シングルクォートかダブルクォートかを指定できます。

Length

length-zero-no-unit(Autofixable)
0px0にするかどうかを指定できます。

以下については、カンマや空白・改行のスタイルについてのチェックなので割愛します。
Unit
Value
Value list
Custom property
Property
Declaration
Declaration block
Block
Selector
Selector list
Rule
Media feature
Media query list
At-rule
Comment
General / Sheet

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

突然「スマイルください」と言われたときの対策 ~ CSS 編 ~

「スマイルください」

笑顔を求めるその脅威は、突然私たちに襲い掛かる。
次の脅威はいつ、だれを襲うのか。予告なしに襲い掛かるその脅威から身を守り、被害を最小限に抑えるために、日頃から正しいスマイルの出し方を見につけておくことが重要である。

今回のスマイル :smiley:

今回作るスマイルはこのようなスマイル :smiley: で、原材料は CSS を使う。
また、本家スマイル1が極めて安価( 0 円)で、提供までの時間が短いことをリスペクトして、スマイルを作るにあたり、以下の規則を設け、遵守した。

  • 使用する要素は 1 つまで
  • 擬似要素は利用しないことが好ましい
  • 所要時間は 1 時間以内

スマイル :smiley: の作り方

HTML を書く

HTML は、上記の規則からnico-chanクラスを付与したdiv要素 1 つとした。

<div class="nico-chan"></div>

CSS を書く

まず、スマイル :smiley: をパーツごとに分割すると、円と楕円のみで構成されていることがわかる。円や楕円は、radial-gradient関数を使えば、描くことができる。

顔を描く

radial-gradient関数を使って、顔の輪郭を作っていく(動作例)。良い感じ。

:root {
  --canvas-size: 300px;

  --face-inside-color: #ffcc4d;
  --face-outline-color: #ffcc4d;
  --face: radial-gradient(
      circle,
      var(--face-inside-color) 140px,
      var(--face-outline-color) 141px,
      var(--face-outline-color) 149px,
      transparent 150px
    )
    no-repeat;
}

.nico-chan {
  width: var(--canvas-size);
  height: var(--canvas-size);

  background: var(--face);
}

目を描く

次に、目を作っていく(動作例)。

:root {
  --canvas-size: 300px;

  --eye-size: 17px;
  --eye: radial-gradient(
    11px 15px,
    #664500 calc(var(--eye-size) - 2px),
    transparent var(--eye-size)
  );

  --left-eye-position: 50px -50px;
  --right-eye-position: -50px -50px;

  --left-eye: var(--eye) var(--left-eye-position) no-repeat;
  --right-eye: var(--eye) var(--right-eye-position) no-repeat;

  --eyes: var(--left-eye), var(--right-eye);
}

.nico-chan {
  width: var(--canvas-size);
  height: var(--canvas-size);

  background: var(--eyes);
}

口を描く

次に、口を描く。これは、円の上に楕円を重ねれば良い感じに作れると思う(動作例)。

:root {
  --canvas-size: 300px;

  --face-inner-color: #ffcc4d;

  --mouth-size: 35px;
  --mouth-color: #664500;
  --mouth-overlay: radial-gradient(
      2px 1px,
      var(--face-inner-color) 111px,
      transparent 113px
    )
    0 -50px no-repeat;
  --mouth: radial-gradient(var(--mouth-color) 90px, transparent 91px) 0 10px
    no-repeat;

  --teeth-size: 35px;
  --teeth-color: #fff;
  --teeth-overlay: radial-gradient(
      350px 100px,
      var(--mouth-color) 85px,
      transparent 87px
    )
    0 -10px no-repeat;
  --teeth: var(--teeth-overlay),
    radial-gradient(80px 60px, var(--teeth-color) 80px, transparent 81px) 0 -15px
      no-repeat;
}

.nico-chan {
  width: var(--canvas-size);
  height: var(--canvas-size);

  background: var(--mouth-overlay), var(--teeth), var(--mouth);
}

作ったパーツを組み合わせる

上で作ったパーツを適当に組み合わせる。すると、 CSS は全体でこんな感じになる。ごちゃごちゃしていて読みにくいが、やっていることは円、楕円の作成と配置だけなので、それほど難しいことはしていない。
また、background-imageプロパティをコンマ区切りで適用するとき、最初に適用した値の結果が常に最前面に表示される2、という動作に注意しなければならない。

:root {
  --canvas-size: 300px;

  --face-inner-color: #ffcc4d;
  --face-outline-color: #ffcc4d;
  --face: radial-gradient(
      circle,
      var(--face-inner-color) 140px,
      var(--face-outline-color) 141px,
      var(--face-outline-color) 149px,
      transparent 150px
    )
    no-repeat;

  --eye-size: 17px;
  --circle-eye: radial-gradient(
    11px 15px,
    #664500 calc(var(--eye-size) - 2px),
    transparent var(--eye-size)
  );
  --left-eye-position: 50px -50px;
  --right-eye-position: -50px -50px;
  --left-eye: var(--circle-eye) var(--left-eye-position) no-repeat;
  --right-eye: var(--circle-eye) var(--right-eye-position) no-repeat;
  --eyes: var(--left-eye), var(--right-eye);

  --mouth-size: 35px;
  --mouth-color: #664500;
  --mouth-overlay: radial-gradient(
      2px 1px,
      var(--face-inner-color) 111px,
      transparent 113px
    )
    0 -50px no-repeat;
  --mouth: radial-gradient(var(--mouth-color) 90px, transparent 91px) 0 10px
    no-repeat;

  --teeth-size: 35px;
  --teeth-color: #fff;
  --teeth-overlay: radial-gradient(
      350px 100px,
      var(--mouth-color) 85px,
      transparent 87px
    )
    0 -10px no-repeat;
  --teeth: var(--teeth-overlay),
    radial-gradient(80px 60px, var(--teeth-color) 80px, transparent 81px) 0 -15px
      no-repeat;
}

.nico-chan {
  width: var(--canvas-size);
  height: var(--canvas-size);

  background: var(--eyes), var(--mouth-overlay), var(--teeth), var(--mouth),
    var(--face);
}

完成

というわけで、完成したスマイルがこちら!

See the Pen Pure CSS Smiley Face by Hakaato (@hakaato) on CodePen.

まとめ

このスマイルを作るうえで使用したプロパティは、実質 3 つだけ(カスタムプロパティを除く)になった。このことからも、連続的な色の変化を様々な形状で表現できることは強力で、スタイルをより柔軟に適用できることがわかる。
また、CSS グラデーションはブラウザによって生成されるので、ズーム表示された場合も割りと綺麗に表示されるのも Good ポイント。

CSS の場合、グラデーションさえあれば、スマイルは作れるのだ。もし道端で、突然スマイルを求められても、慌てず冷静にグラデーションを駆使すれば良い。グッドラック。

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

ワイプスライダーに機能を追加し、プラグイン化してみた

こちらの記事で作ったスライダーに機能を追加し、プラグインとして使えるように拡張しました。
サンプル

使い方

ファイルはGithubから一式ダウンロードできます。
https://github.com/Kackie/wipeSlider
※test.htmlは旧バージョン。

HTML

外部ファイル読み込み

<link rel="stylesheet" href="css/wipeSlider.css">
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="script/jquery.wipeSlider.js"></script>

スライド用のCSSとjQuery、プラグインのJSを読み込みます。
CSSは開いてみればわかりますがすごくシンプルです。必須なのはこれだけです。
ページャー等の見た目の調整はサンプルのHTMLに直書きしています。参考にしてもらっても、自由にスタイルを書くのもよいと思います。

スライド部分

<div class="slidesWrap js_wiper">
    <ul class="slides">
        <li class="slide">
            <img src="https://dummyimage.com/980x500/ccc/fff&text=1" alt="">
        </li>
        <li class="slide">
            <img src="https://dummyimage.com/980x500/ccc/fff&text=2" alt="">
        </li>
        <li class="slide">
            <img src="https://dummyimage.com/980x500/ccc/fff&text=3" alt="">
        </li>
    </ul><!-- / .slides -->
</div><!-- / .js_wiper -->

一番シンプルな形です。
階層が守られていればulタグ以外でも構いません。

jQuery

$('.js_wiper').wipeSlider();

最低限これだけ書けば動きます。

$('.js_wiper').wipeSlider({
    transition : 1000,
    auto : true
});

オプションを設定するとこんな感じです。

オプション設定

ラベル 機能
transition スライドが切り替わるときの速度を設定します。
初期値は500。
auto 自動再生を設定します。
初期値はfalse。
duration 自動再生時、スライドの表示時間を設定します。
初期値は4000。
pager ページャーを生成します。
初期値はtrue。
controls 前後のスライドに切り替えるコントローラーを生成します。
初期値はtrue。

その他の仕様

表示中のスライドにはactiveクラスが付きます。
これを使用して、スライド内のインタラクション作成に役立ててもらえればと思います。

前回のバージョンでは、別タブでページを閲覧してから戻ってくると、アニメーションがおかしくなってしまうことがありました(setIntervalの仕様ですが)。
タブが非アクティブ時にはclearIntervalがかかり、戻ってくるとsetIntervalが再発動するようになっています。

感想と反省

プラグイン自作初挑戦です。意外と簡単ですね。
前回作った元のスライダーがシンプル過ぎたので、最低限スライダーのプラグインに必要になるであろう機能を追加しておきました。
表示中のものより前のスライドに移動したときは逆方向にアニメーションさせたりとか、ユーザー設定でアニメーション方向を自由に帰らるようにしたかったのですが、アニメーションをCSSのtransitionでやっているがためにclipの再設定ができないという問題に直面し断念。。
backFlagという変数をつくり、戻る動作のときはbackFlag = true;となるようにしたもののそのままうまく扱えていないです。
keyframesを動的生成はできなさそうだし、やるとしたらanimateメソッドのstepを使うことになるのだろうか・・?
時間がかかりそうだったのでひとまず公開してしまいましたが、これはなんとか作ってみたいのでじっくり考えてみることにします。

せっかくなのでクレジットを入れようと思ったのですが書き方がわかりませんでした(恥)。

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