纯CSS3实现蜡烛、火焰和烟雾实例页面

回到相关文章 »

展示(点蜡烛熄灭)

代码

CSS代码:
.candle {
    position: absolute;
    bottom: 40px; left: 0; right: 0;
    width: 40px;
    margin: auto;
}
.candle-body {
    width: 40px; height: 120px;
    background-color: #E90018;
    border-radius: 0 0 40px 40px/0 0 16px 16px;
    box-shadow: inset 8px 0 12px rgba(0,0,0,.1), inset -8px 0 12px rgba(0,0,0,.1);
    position: relative;
}
.candle-body::before {
    content: '';
    position: absolute;
    height: 16px;
    border-radius: 50%;    
    background-color: #EF4D65;
    top: -8px; left: 0; right: 0;
    box-shadow: inset 0 0 20px #E90018, inset 0 0 5px rgba(0,0,0,.2), 0 1px rgba(0,0,0,.05), inset 0 2px 3px rgba(0,0,0,.4);
}
/* 蜡烛芯 */
.candle-body::after {
    content: '';
    display: block;
    width: 4px;
    height: 20px;
    position: absolute;
    left: 0; right: 0; top: -20px;
    margin: auto;
    background: #fff;
    background-image: linear-gradient(to bottom,#311,#edd3d1 70%,#edd3d1);
    border-radius: 0 0 4px 4px/0 0 2px 2px;
    box-shadow: 0 1px 1px rgba(0,0,0,.25);
}
/* 火焰 */
.candle-flame {
    animation: flicker 3s infinite ease-out alternate;
    background-image: radial-gradient(ellipse at 5px 20px, rgba(75,95,124,0), hsla(0,0%,100%,.5), #fff);
    border-radius: 37% 37% 34% 34%/70% 70% 33% 33%;
    box-shadow: 0 -8px 8px 4px #fff, 0 -15px 15px 12px #ff0, 0 -15px 0 14px #f00;
    width: 10px; height: 20px;
    position: absolute;
    bottom: 100%; left: 0; right: 0; top: -24px;
    margin: auto;
    transform-origin: center bottom;
    filter: blur(1px);
}
.out .candle-flame {
    display: none;
}
@keyframes flicker {
  0% {
    transform:scale(1);
  }
  20% {
    transform:scale(1.1,0.9) rotate(3deg);
  }
  50% {
    transform:scale(1,1.2);
  }
  80% {
    transform:scale(0.9,1.1) rotate(-3deg);
  }
  100% {
    transform:scale(1);
  }
}

.candle-smoke {
    position: absolute;
    left: 50%; top: -15px;
    transform-origin: bottom center;
    transform: scale(.5);
    filter: blur(3px);
    opacity: 0;
}
.out .candle-smoke {
    animation: smokeOut 30s both;
}

@keyframes smokeOut {
    10% { opacity: 1; }
    0%,100% { opacity: 0; }
}

/* 烟雾元素们 */
.candle-smoke span { 
    position: absolute;
    bottom: -9px; left: -9px;
    width: 18px; height: 18px;
    background-image: radial-gradient(closest-side circle, rgba(0,0,0,.75), rgba(0,0,0,.6), rgba(0,0,0,.4), rgba(0,0,0,0));
    border-radius: 18px;
    opacity: 0;
}
.candle:not(.out) .candle-smoke span {
    animation: none;
}

/* 烟雾动画 */
@keyframes smokeL {
    0%   { opacity: 0; transform: scale(1) translate(0, 0); }
    10%  { opacity: .8; transform: scale(1) translate(0, -7px); }
    100% { opacity: 0; transform: scale(5) translate(-4px, -26px); }
}

@keyframes smokeR {
    0%   { opacity: 0; transform: scale(1) translate(0, 0); }
    10%  { opacity: .8; transform: scale(1) translate(0, -7px); }
    100% { opacity: 0; transform: scale(5) translate(4px, -26px); }
}

.candle-smoke .s0 { animation: smokeL 10s 0s infinite; }
.candle-smoke .s1 { animation: smokeR 10s 1s infinite; }
.candle-smoke .s2 { animation: smokeL 10s 2s infinite; }
.candle-smoke .s3 { animation: smokeR 10s 3s infinite; }
.candle-smoke .s4 { animation: smokeL 10s 4s infinite; }
.candle-smoke .s5 { animation: smokeR 10s 5s infinite; }
.candle-smoke .s6 { animation: smokeL 10s 6s infinite; }
.candle-smoke .s7 { animation: smokeR 10s 7s infinite; }
.candle-smoke .s8 { animation: smokeL 10s 8s infinite; }
.candle-smoke .s9 { animation: smokeR 10s 9s infinite; }
            
HTML代码:
<div class="candle" onClick="this.classList.toggle('out');">
    <div class="candle-body"></div>
    <!-- 火焰 -->
    <div class="candle-flame"></div>
    <!-- 烟雾 -->
    <div class="candle-smoke">
        <span class="s0"></span>
        <span class="s1"></span>
        <span class="s2"></span>
        <span class="s3"></span>
        <span class="s4"></span>
        <span class="s5"></span>
        <span class="s6"></span>
        <span class="s7"></span>
        <span class="s8"></span>
        <span class="s9"></span>
    </div>
</div>