CSS
CSS3

CSSで猫にFlex

sample.png

ホバーすると....

sample_gif.gif

実際に動作を確認したい方はこちらへ
https://junya0215.github.io/cacao_ame/design_ui/flex_cat/

Chrome, Firefox, Safariは正常に動作。
IE11は動かない、挙動が全体的におかしくなった。

サイドバーにいかが?


HTML

<div class="flex">
  <a class="item" href="#">link item</a>
  <a class="item" href="#">link item</a>
</div>

CSS

/* Reset */
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

*:before, *:after{
  box-sizing: border-box;
}

html, body{
  height: 100%;
}

.flex{
  position: relative;

  display: flex;
  flex-flow: column nowrap;
  width: 100px; height: auto;
  margin: 10px;

  min-height: 500px;
}

/* コンテンツ */
.flex .item{
  flex: 0 0 auto;
  width: 100px;

  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  justify-content: center;

  border-width: 0 1px;
  border-style: solid;
  border-color: darkkhaki;

  font-size: 1.3em;
  color: transparent;
  text-decoration: none;

  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;

  word-break: break-all;
  transition: 1s linear;
}

.flex:hover .item{
  flex: 1 0 auto;
  color: black;
}

.flex:hover .item + .item{
  border-top: 1px solid rgba(0,0,0,.6);
}

.flex .item:hover{
  background-color: #FFFACD;
}

/* ねこ */
.flex:before,
.flex:after{
  content: '';
  position: relative;

  display: block;
  font-size: 10px;
  color: darkkhaki;

  flex: 0 0 5.5em;
  width: 10em;
  background-repeat: no-repeat;
}

.flex:before{
  /* head, ear, eye, mouth, whiskers */
  background-image:
    radial-gradient(10em 10em at 50% 100%, 
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(1.75em 4.3em at 63% 106%, 
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(1.75em 4.3em at 37% 106%, 
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(1em 1em at 50% 50%, currentColor 50%, transparent 50%),
    radial-gradient(1em 1em at 50% 50%, currentColor 50%, transparent 50%),
    radial-gradient(3em 3em at 50% -20%,
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(3em 3em at 50% -20%,
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(4em 2em at 40% 135%,
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(4em 2em at 40% 135%,
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(4em 2em at 60% 135%,
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(4em 2em at 60% 135%,
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%);

  background-position:
    /* head */
    left 50% bottom 0, 
    /* ear */
    left calc(50% - 3em) bottom 3.5em, left calc(50% + 3em) bottom 3.5em,
    /* eye */
    left calc(50% - 1.5em) bottom 2em, left calc(50% + 1.5em) bottom 2em,
    /* mouth */
    left calc(50% - 1.3em) bottom -1.6em, left calc(50% + 1.3em) bottom -1.6em,
    /* whiskers */
    left calc(50% - 3.5em) bottom 1.8em, left calc(50% - 3.8em) bottom 1em,
    left calc(50% + 3.6em) bottom 1.8em, left calc(50% + 3.7em) bottom 1.1em;

  background-size: 
    10em 10em, 
    1.75em 4.3em, 1.75em 4.3em,
    1em 1em, 1em 1em,
    3em 3em, 3em 3em,
    4em 2em, 4em 2em, 4em 2em, 4em 2em;
}

.flex:after{
  /* body, paw */
  background-image:
    radial-gradient(10em 9em at 50% 0%, 
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(3.8em 10em at 75% -19%, 
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%),
    radial-gradient(3.8em 10em at 25% -19%, 
      transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor 50%, transparent 50%);

  background-position:
    /* body */ 
    left 50% top 0,
    /* paw */
    left calc(50% - 2.2em) top 1.6em, left calc(50% + 2.2em) top 1.6em;

  background-size: 10em 9em, 3.8em 10em, 3.8em 10em;
}

補足

ねこは .flex(flexコンテナ)の疑似要素を使って作ります。
::beforeが猫の顔で,::afterが体および足です。
今回はHTML構造を少なくするため、グラデーションを用いました。

flexコンテナに疑似要素を設定すると疑似要素はflexアイテムになります。
アイテムの配置順は::beforeが先頭になり、::afterが末尾に配置されます。

ねこはfont-sizeで比率を維持しながらサイズを変更できます。


IEで使いたい人向け

flexを使わないパターンも用意しました、IE11でも正常に動作します。
ただしflexがないためアイテムの高さを固定で指定する必要があります。

https://junya0215.github.io/cacao_ame/design_ui/block_cat/