CSS Card:纯css制作扑克牌

记得当初在写一个js版本的斗地主程序的时候,我让朋友用ps给我制作了54张扑克牌(是54张吗?)后来想换牌的大小,又不好再让人家做,当时是左右为难,今天在国外的网站上看到了一篇css制作扑克牌的文章,其效果比ps的还要好,叹为观止。其实用到的知识不多,但是国内的同行里面很少能找到有这种专研精神的人(我们的第一反应是copy)。我将这篇文章翻译给大家。

原文如下:

这篇文章中,我将给大家介绍一种简单而吸引人的制作扑克牌的方法,该方法的特点是用纯css实现。这个过程中,你将学到before 和 after的用法,以及一些动画效果。

demo演示  |  源码下载

制作扑克的html代码

第一步是制作扑克的html,我的原则是用最少最简洁的代码,不引用任何图片,也许你认为不可能,但是你还是乖乖的看我是如何工作的吧。

建立一个div,赋予两个class属性:cardand suitdiamonds

<div class="card suitdiamonds">
</div>

往这个div中添加卡片的内容,只需要一个包含字母A的段落标记

就可以了。

<div class="card suitdiamonds">
  <p>A</p>
</div>

现在你头脑里要时刻记住,我们的目的不仅仅是要制作一张扑克牌,而且要用最简洁的代码,html部分的代码就只需要这么多了(够简洁吧)。

css代码

css的第一步是规定基本的页面属性,这些属性将被card继承。

* {margin: 0; padding: 0;}
      
body {
  background: #00a651;
}
      
.card {
  position: relative;
  float: left;
  margin-right: 10px;
  width: 150px;
  height: 220px;
  border-radius: 10px;
  background: #fff;
  -webkit-box-shadow: 3px 3px 7px rgba(0,0,0,0.3);
  box-shadow: 3px 3px 7px rgba(0,0,0,0.3);
}

就如上面的代码所示,card 的样式非常简单,白色背景,圆角,边框阴影,除了position属性为relative外没有什么特别的。

现在我们给A字母润色一下

.card p {
  text-align: center;
  font: 100px/220px Georgia, Times New Roman, serif;
}

先看看效果:

screenshot

现在看起来是不是已经有卡片的效果了,但是总感觉还缺少些什么-梅花、方块、红桃、黑桃。如果我们要显示这些图形但又不引入图片的话,事情将变得复杂起来,但是我们还是有解决问题的技巧的。

考虑到我们不再想要给html部分添加更多的代码,我们引入伪元素before和after来给卡片添加梅花方块这些图形。幸运的是,绝大多数的浏览器都能识别各种种类的特殊符号。这些特殊符号的获取可以在这个网站CopyPasteCharacter找到。

.suitdiamonds:before, .suitdiamonds:after {
  content: "♦";
  color: #ff0000;
}

我同时用before 和 after这样我就能得到上下两个方块图形,其他图形依葫芦画瓢。

.suitdiamonds:before, .suitdiamonds:after {
  content: "♦";
  color: #ff0000;
}
      
.suithearts:before, .suithearts:after {
  content: "♥";
  color: #ff0000;
}
      
.suitclubs:before, .suitclubs:after {
  content: "♣";
  color: #000;
}
      
.suitspades:before, .suitspades:after {
  content: "♠";
  color: #000;
}

如果你是一个仔细的人,你应该发现了这些方块梅花的方向貌似搞反了。其实css实现反转也很容易,但是考虑到没人会把屏幕倒过来看这张扑克牌,所以这是不必要的。

我们画好了扑克的符号,还应该修饰大小和合适的定位。方块、梅花、红桃黑桃的字体大小位置摆放以及position属性都是一致的,因此我们最好只写一次。div[class*=``'suit'``]选择器就可以同时选择这四个。(原文的评论里面有人建议单独用一个class来定义,因为作者的这个方法效率上讲要低一些)

div\[class*='suit'\]:before {
  position: absolute;
  font-size: 35px;
  left: 5px;
  top: 5px;
}
     
div\[class*='suit'\]:after {
  position: absolute;
  font-size: 35px;
  right: 5px;
  bottom: 5px;
}

下面看看效果

screenshot

上面我们只是制作了一张图片,现在我想制作一组图片的效果:

<div class="hand">
  
  <div class="card suitdiamonds">
    <p>A</p>
  </div>
  
  <div class="card suithearts">
    <p>A</p>
  </div>
    
  <div class="card suitclubs">
    <p>A</p>
  </div>
    
  <div class="card suitspades">
    <p>A</p>
  </div>
  
</div>

css

.hand {
  margin: 50px;
}
  
/* For modern browsers */
.hand:before,
.hand:after {
    content:"";
    display:table;
}
   
.hand:after {
    clear:both;
}
   
/* For IE 6/7 (trigger hasLayout) */
.hand {
    zoom:1;
}
  
.card:hover {
  cursor: pointer;
}

screenshot

接下来我想利用css做出一些有趣的动画效果来:开始的时候只显示一张扑克,当鼠标移上去,扑克会展开,就像你打牌的时候手里握牌的样子。

html

和之前不同的是我增加了spread class属性

<div class="hand spread">
 
  <div class="card suitdiamonds">
    <p>A</p>
  </div>
 
  <div class="card suithearts">
    <p>A</p>
  </div>
   
  <div class="card suitclubs">
    <p>A</p>
  </div>
   
  <div class="card suitspades">
    <p>A</p>
  </div>
 
</div>

css

.spread {
  width: 350px;
  height: 250px;
  position: relative;
}
 
.spread > .card {
  position: absolute;
  top: 0;
  left: 0;
  -webkit-transition: top 0.3s ease, left 0.3s ease;
  -moz-transition: top 0.3s ease, left 0.3s ease;
  -o-transition: top 0.3s ease, left 0.3s ease;
  -ms-transition: top 0.3s ease, left 0.3s ease;
  transition: top 0.3s ease, left 0.3s ease;
}

鼠标移上去的效果:

.spread:hover .suitdiamonds {
  -webkit-transform: rotate(-10deg);
  -moz-transform: rotate(-10deg);
  -o-transform: rotate(-10deg);
  -ms-transform: rotate(-10deg);
  transform: rotate(-10deg);
}
 
.spread:hover .suithearts {
  left: 30px;
  top: 0px;
  -webkit-transform: rotate(0deg);
  -moz-transform: rotate(0deg);
  -o-transform: rotate(0deg);
  -ms-transform: rotate(0deg);
  transform: rotate(0deg);
}
 
.spread:hover .suitclubs {
  left: 60px;
  top: 5px;
  -webkit-transform: rotate(10deg);
  -moz-transform: rotate(10deg);
  -o-transform: rotate(10deg);
  -ms-transform: rotate(10deg);
  transform: rotate(10deg);
}
 
.spread:hover .suitspades{
  left: 80px;
  top: 10px;
  -webkit-transform: rotate(20deg);
  -moz-transform: rotate(20deg);
  -o-transform: rotate(20deg);
  -ms-transform: rotate(20deg);
  transform: rotate(20deg);
}

再加上点阴影效果

.spread > .card:hover {
  -webkit-box-shadow: 1px 1px 7px rgba(0,0,0,0.4);
  box-shadow: 1px 1px 7px rgba(0,0,0,0.4);
}

screenshot