60
54

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CSS3で角丸要素にマスクをかけようとしたらドハマりしたので攻略法を伝授します。

Last updated at Posted at 2016-05-22

##やりたかったこと
角丸要素にマスクをかけて、中の子要素をCSSでアニメーションさせたい
どんなアニメーションかというと、要素の中に小さな円があって、それが要素内をぶわぁ〜って広がっていくような感じ。

【成功イメージ】
maskimage_success_sample1.gif

##ハマったポイント
子要素に対してマスクはかかっていたが、アニメーションさせた時に角丸の四隅がマスクされない。

【こうなった】
maskimage_fail.gif

##失敗コードその1

HTML
<div class="box">
  click me!
  <div class="boxInner"></div>
</div>
SASS
.box{
  text-align:center;
  width:400px;
  height:400px;
  background:#efefef;
  border-radius:50px;
  position:relative;
  overflow:hidden;
  margin:10% auto;
}
.boxInner{
  content:'aaa';
  width:100px;
  height:100px;
  background:#ff0000;
  border-radius:50%;
  position:absolute;
  top:-2%;
  left:-2%;
  &.anm{
    animation-name: slidein;
    animation-duration: 4s;
  }
}
@keyframes slidein {
    0% {
      top:-200%;
      left:-200%;
      opacity:1;
      width: 0%;
      height:0%;
    }
  100%{
    top:-100%;
      left:-100%;
      opacity:0;
      width: 500%;
      height:500%;
  }
}
javascript
$(function(){
  $('.box').on('click',function(){
    $('.boxInner').toggleClass('anm');
  })
});

※javascriptはクリックした時にクラスを追加するためだけに書いています。

実際の動作はこんな感じ
maskimage_fail_sample1.gif

マスク処理サンプル:失敗その1(デモ)

###原因
keyframes内でopacityの値を入れているとマスクされないようです。
opacityを外したら四隅はマスクされました。
でも、動作的に円が中心から広がっていくようなイメージではない(widthを広げている)ため、何かイメージと違うのでこれはボツ。

##失敗コードその2

HTML
<div class="box">
  click me!
  <div class="boxInner"></div>
</div>
SASS
.box{
  text-align:center;
  width:400px;
  height:400px;
  background:#efefef;
  border-radius:50px;
  position:relative;
  overflow:hidden;
  margin:10% auto;
}
.boxInner{
  width:100px;
  height:100px;
  background:#ff0000;
  border-radius:50%;
  position:absolute;
  top:-2%;
  left:-2%;
  &.anm{
    animation-name: slidein;
    animation-duration: 2s;
  }
}
@keyframes slidein {
    0% {
      transform:scale(0.1);
    }

    100% {
      background:#FFCADE;
      transform:scale(50);
    }
}
javascript
$(function(){
  $('.box').on('click',function(){
    $('.boxInner').toggleClass('anm');
  })
});

実際の動作はこんな感じ
maskimage_fail_sample2.gif

マスク処理サンプル:失敗その2(デモ)

widthを広げるのではなく、transform:scaleで拡大させる作戦。
動作はイメージ通り、でも四隅がマスクされない問題勃発。。。

###原因
keyframes内でtransformを設定しているとこうなるらしい。

##完全に詰んだ・・・orz
この手のエフェクトはGoogleのマテリアルデザインなんかでも採用されていたりするので、色んな所で見たりもしていたけど、
まさか角丸だとマスクされないとは・・・
先人たちはこのピンチをどのように切り抜けてきたのであろうかと、
悩みながら試行錯誤を繰り返して約半日。
9割9部諦めていた時に...

##神は降臨した!
border-radiusで丸くした部分にoverflow:hiddenが効かない対処法

神様仏様qiita様!
やはり、同じ問題を抱えて解決された方がいらっしゃった!
cssに「mask-image」なるプロパティが存在していたのですね!
画像で要素にマスクがかけられるようだ!

これを使って修正してみた!

##成功コード

HTML
<div class="box">
  click me!
  <div class="boxInner"></div>
</div>
SASS
.box{
  text-align:center;
  width:400px;
  height:400px;
  background:#efefef;
  border-radius:50px;
  position:relative;
  overflow:hidden;
  margin:10% auto;
  -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);

mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);

}
.boxInner{
  width:100px;
  height:100px;
  background:#ff0000;
  border-radius:50%;
  position:absolute;
  top:-2%;
  left:-2%;
  &.anm{
    animation-name: slidein;
    animation-duration: 2s;
  }
}
@keyframes slidein {
    0% {
      transform:scale(0.1);
    }

    100% {
      background:#FFCADE;
      transform:scale(50);
    }
}
javascript
$(function(){
  $('.box').on('click',function(){
    $('.boxInner').toggleClass('anm');
  })
});

実際の動作はこんな感じ
maskimage_success_sample1.gif

マスク処理サンプル:成功(デモ)

できた!!できたよ!!!!
求めていたのはまさにこれ!
たったに行のコードを追加しただけで解決しました!

##8/23追記
mask-image を使わなくても親要素の .boxz-index を指定してあげたらマスクがかかるようです。

【参考】
http://codepen.io/geckotang/pen/NAVXmQ
http://codepen.io/geckotang/pen/XKwkAr

GeckoTang
ご指摘ありがとうございました!

##振り返り
今回の一件で、今まで要素にマスクをかける方法がoverflow:hiddenのみだと思っていたが、
mask-imageという新たな引き出しを得ることが出来た。
しかも、これだと画像で要素がくり抜けるので、いろんなことにも応用が効きそう!

さらに色々調べていくと、svgを使ってマスクをかけることも出来るみたい(http://qiita.com/C058/items/25f0c5e362ba7a5e99e3 )なので、
今度はこちらも試してみたい!

60
54
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
60
54

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?