切图仔,是大多数前端用来自嘲的称说。置信很多人平时写页面的时候,大部分工夫是在切图和排图,如此往返。这里并不是要否定切图自身,而是在质疑:始终切图到底对本人的功力增长有何益处?想想UI丢给你一套难看的界面,你却只需一个img标签,或者一个background-image属性即可搞定了它,但日后某个中央须要调整某些外观(色彩、文字等),你还不是会让UI再批改之前的素材,而后替换下来完事?这样就齐全受制于UI,而无奈施展本人的能动性。

那么,如何突破这个僵局?很简略,如果你CSS玩的够溜,你就无需再进行那干燥无比的切图工作,那些界面、元素都是通过你双手亲自缔造而成的,只管创作它们可能会花一些功夫,但带来的回报也是微小的,你不仅可能自在掌控你所发明进去的元素,而且能大幅提高本人的CSS功力。

在此之前

在用纯CSS实现这些成果之前,笔者先介绍几个罕用的SCSS Mixin和一个得力武器,用它们来进行创作将会事倍功半

笼罩 - cover

@mixin cover($top: 0, $left: 0, $width: 100%, $height: 100%) {  position: absolute;  top: $top;  left: $left;  width: $width;  height: $height;
}复制代码

当你想在原先元素的根底上再“复制”一个元素,并将其笼罩在它身上时,你将会用到它

嵌入 - inset

@mixin inset($inset: 0) {  position: absolute;  top: $inset;  left: $inset;  right: $inset;  bottom: $inset;
}复制代码

同样地,这也是在原先元素根底上复制出一个元素,只不过这个元素地位和原先的元素雷同,大小会基于原先的元素而增减。

举个例子,假使你想创立多个半径不同的同心圆,这个Mixin将会很有帮忙

aqua.css

aqua.css是笔者开源的一个优雅的、轻量级的CSS框架。外面有很多罕用的组件以及罕用的款式类,用它来写CSS体验将会十分爽

在codepen上,笔者筹备了一个aqua.css模版,大家能够用它来进行CSS的创作

常见UI成果

条纹成果

首先,咱们要抓住“边框”这个词,如何创作出一个非凡的边框呢?如果个别的CSS属性实现不了的话,能够思考用伪元素来实现,思路如下:在原先的元素下方创立一个有条纹背景的伪元素,并保障原先元素覆盖住它就行,这样就模仿了边框的成果。

那么如何创立条纹背景呢?这里咱们将应用repeating-linear-gradient来实现它

<div class="card w-80">
 <div class="border-stripe rounded-xl">
   Lorem ipsum...  </div></div>复制代码

.border-stripe {
 --stripe-width: 0.5rem;
 --stripe-deg: -45deg;
 --stripe-color-1: var(--grey-color-1);
 --stripe-offset-1: 2px;
 --stripe-color-2: var(--skin-color-2);
 --stripe-offset-2: 1rem;
 --stripe-radius: 15px;
 --stripe-inset: calc(var(--stripe-width) * -1);
 &::before {    @include inset(var(--stripe-inset));    content: "";    z-index: -1;    background: repeating-linear-gradient(
     var(--stripe-deg),
     var(--stripe-color-1) 0 var(--stripe-offset-1),
     var(--stripe-color-2) 0 var(--stripe-offset-2)
   );    border-radius: var(--stripe-radius);
 }
}复制代码

为了保障复用性,这里将其形象成了border-stripe类,外面的值都能够通过CSS变量来动静调节

光泽成果

一看到光泽,置信你可能会想到一个要害角色——径向突变,通过它,咱们能够创作出放射状的图案,而光泽也恰好是放射状的,再依据背景能够叠加的个性,光泽成果就能轻松实现了

<div class="flex flex-col space-y-4">
 <span class="btn btn-primary btn-round inline-flex">
   <span class="font-bold text-grad">Shine Button 1</span>
 </span>
 <span class="btn btn-info btn-round btn-depth inline-flex">
   <span class="font-bold">Shine Button 2</span>
 </span></div>复制代码

:root {
 --blue-color-1: #08123d;
 --gold-color-1: #dcb687;
 --brown-color-1: #50301f;
 --brown-color-2: #936237;
 --gold-grad-1: radial-gradient(
     circle at 50% 5%,
     #{transparentize(white, 0.5)},      #eba262
   ),    #eba262;
 --gold-grad-2: linear-gradient(88deg, #e7924e 0%, #f8ffee 50%, #e7924e 100%);
 --blue-grad-1: radial-gradient(
     circle at 50% 5%,
     #{transparentize(white, 0.8)},      #091344
   ),    #091344;
 --primary-color: var(--blue-grad-1);
 --info-color: var(--gold-grad-1);
}.btn {
 &-primary {    border: 4px solid var(--gold-color-1);    span {      background-image: var(--gold-grad-2);
   }
 }
 &-info {    color: var(--brown-color-1);    border: none;
 }
 &-depth {    box-shadow: 0 -5px 0 var(--brown-color-2);
 }
}复制代码

不规则形态

首先,让咱们先察看一下上图的缎带形态是由哪些根本形态组成的:两头是一个矩形,矩形下方有2个三角形,左右2侧各有一个被裁切过的矩形。一提裁切,就能想到clip-path这个属性,于是问题也就很好解决了

<div class="ribbon">
 Pure CSS Ribbon  <div class="block"></div>
 <div class="block"></div>
 <div class="block"></div>
 <div class="block"></div></div>复制代码

.ribbon {
 --ribbon-color-1: var(--yellow-color-1);
 --ribbon-color-2: var(--yellow-color-2);
 --ribbon-color-3: var(--yellow-color-3);  position: relative;  padding: 0.5rem 1rem;  color: white;  background: var(--ribbon-color-1);  .block {
   &:nth-child(1),
   &:nth-child(2) {      position: absolute;      bottom: -20%;      width: 20%;      height: 20%;      background: var(--ribbon-color-2);      clip-path: polygon(0 0, 100% 100%, 100% 0);
   }
   &:nth-child(1) {      left: 0;
   }
   &:nth-child(2) {      right: 0;      transform: scaleX(-1);
   }
   &:nth-child(3),
   &:nth-child(4) {      position: absolute;      z-index: -1;      top: 20%;      width: 40%;      height: 100%;      background: var(--ribbon-color-3);      clip-path: polygon(0 0, 25% 50%, 0 100%, 100% 100%, 100% 0);
   }
   &:nth-child(3) {      left: -20%;
   }
   &:nth-child(4) {      right: -20%;      transform: scaleX(-1);
   }
 }
}复制代码

留神到有一行代码transform: scaleX(-1);,这起到了程度翻转的作用,它能够避免再写一遍clip-path

浮雕成果

通过仔细观察,你会发现这是由2个同心的元素组成的,于是天然就想到了inset这个Mixin。

创立了2个同心元素后,就要想方法来创立它们的浮雕光泽了。这里的光泽能够用box-shadow来实现,通过叠加多重暗影,咱们就能模拟出浮雕的成果了

<div class="px-6 py-2 text-xl embossed cursor-pointer" data-text="浮雕按钮" >
 浮雕按钮</div>复制代码

:root {
 --red-color-1: #af2222;
 --red-color-2: #c1423e;
 --red-color-3: #c62a2a;
 --red-color-4: #951110;
 --green-color-1: #486433;
 --green-color-2: #2b361a;
 --red-grad-1: linear-gradient(
   to right,
   var(--red-color-1) 50%,
   var(--red-color-2) 0
 );
}.embossed {
 --emboss-radius: 1rem;
 --emboss-out: 6px;
 --emboss-out-minus: calc(var(--emboss-out) * -1);
 --emboss-inset: 2px;
 --emboss-inset-minus: calc(var(--emboss-inset) * -1);
 --emboss-blur: 1px;
 --emboss-bg-1: var(--red-color-3);
 --emboss-bg-2: var(--green-color-1);
 --emboss-color-1: white;
 --emboss-color-2: var(--red-color-4);
 --emboss-color-3: var(--green-color-2);  position: relative;  box-sizing: border-box;  white-space: nowrap;
 &::before {    @include inset(var(--emboss-out-minus));    content: "";    background: var(--emboss-bg-1);    box-shadow: inset var(--emboss-inset-minus) var(--emboss-inset-minus)
       var(--emboss-blur) var(--emboss-color-1),
     inset var(--emboss-inset) var(--emboss-inset) var(--emboss-blur)
       var(--emboss-color-2);    border-radius: calc(var(--emboss-radius) + var(--emboss-out));
 }
 &::after {    @include inset;    @include flex-center;    content: attr(data-text);    color: white;    font-weight: bold;    background: var(--emboss-bg-2);    box-shadow: inset var(--emboss-inset) var(--emboss-inset) var(--emboss-blur)
       var(--emboss-color-1),
     inset var(--emboss-inset-minus) var(--emboss-inset-minus)
       var(--emboss-blur) var(--emboss-color-3);    border-radius: var(--emboss-radius);
 }
}复制代码