电话

18600577194

当前位置: 首页 > 资讯观点 > 软件开发

web开发前端技术分享-CSS光学错觉效果

标签: 前端开发 css效果 2026-01-16 

CSS光学错觉

过去一周,我仅用CSS(其中有一个用了点HTML,但大部分都是纯CSS)编写了一系列光学错觉效果。我在CodePen上建了个合集,放了40个,接下来几周可能还会加新的。

很多都玩转色彩效果,有些是动画的,不少都应该有(也确实加了)动态提示……不过可能我还得多加几个。编其中几个的时候,我自己都看得头晕眼花😬

下面是合集里我最喜欢的几个:

迈因茨-莱恩兹错觉

这个是动画效果的(在窄屏或宽屏上看效果更好)。玩法是:先盯着红点看,注意它们上下移动;然后盯住任意一个黑色十字……突然红点就开始波浪式移动了!

/* 光学错觉  
看红点:它们走直线。现在盯住任意黑十字,红点就会像沿着曲线而非直线移动。  
*/  
@keyframes ball {  
  0% { transform: translate(0, 0); }  
  100% { transform: translate(0, -92%); }  
}  
body {  
  margin: 0;  
  height: 100vh;  
  overflow: hidden;  
  font-size: 0.8vw;  
  background: 
    linear-gradient(#000 0 0) 50% 50% / 0.4em 2em,  
    linear-gradient(#000 0 0) 50% 50% / 2em 0.4em,  
    linear-gradient(#000 0 0) 50% 3em / 0.4em 2em,  
    linear-gradient(#000 0 0) 50% 3.8em / 2em 0.4em,  
    linear-gradient(#000 0 0) 50% calc(100% - 3em) / 0.4em 2em,  
    linear-gradient(#000 0 0) 50% calc(100% - 3.8em) / 2em 0.4em,  
    #777;  
  background-repeat: no-repeat;  

  &::before {  
    content: "";  
    position: absolute;  
    width: 100%;  
    height: 100%;  
    top: 50%;  
    left: 50%;  
    translate: -50% -50%;  
    --mask:  
      radial-gradient(7.75em at calc(100% + 5.25em) 50%,#0000 calc(99% - 1em),#000 calc(101% - 1em) 99%,#0000 101%) calc(50% - 5em + .5px) calc(50% - 10em)/ 10em 20em,  
      radial-gradient(7.75em at -5.25em 50%,#0000 calc(99% - 1em),#000 calc(101% - 1em) 99%,#0000 101%) calc(50% + 5em) 50%/10em 20em;  
    -webkit-mask: var(--mask);  
    mask: var(--mask);  
    background: #fff;  
    clip-path: polygon(5% 0, 45% 0, 45% 100%, 55% 100%, 55% 0, 95% 0, 95% 100%, 5% 100%);  
    clip-path: polygon(0% 0, 45% 0, 45% 100%, 55% 100%, 55% 0, 100% 0, 100% 100%, 0% 100%)  
  }  
  
  &::after {  
    --color: #f00;  
    content: "";  
    position: absolute;  
    width: 100%;  
    height: 100%;  
    top: 50%;  
    left: 50%;  
    translate: -50% -50%;  
    background:  
      radial-gradient(circle at 50% 96%, red 2em, #0000 0) 50% 50% / 8% 100%  
      ;  
    animation: ball 3s linear alternate infinite;  
    clip-path: polygon(0% 0, 45% 0, 45% 100%, 55% 100%, 55% 0, 100% 0, 100% 100%, 0% 100%)  
  }  
}

迈因茨-莱恩兹错觉图

这个(和下一个)我用的是超巧妙的波浪形状生成器。

曲率盲视

这几组曲线几乎一样:唯一区别是颜色。从拐点画到拐点,或从波峰画到波峰,会让它们看起来完全不同——甚至其中一个看着都不太像波浪了!(小屏上看效果更好)

曲率盲视-效果图

/* 视觉效果:  
一组线看着更直(上),另一组更圆润(下)……但两组波纹程度一样,唯一区别是着色方式。鼠标悬停可揭晓  
*/  
@property --c {  
  syntax: '<color>';  
  initial-value: #fff;  
  inherits: true;  
}  

body {  
  /* 改编自Temani Afif在CSS Tricks的代码:https://css-tricks.com/how-to-create-wavy-shapes-patterns-in-css/ */  
  --s: 60px;  
  --c: #fff;  
  --c1: radial-gradient(68.08px at 50% calc(100% + 60px),#0000 calc(99% - 2px),#000 calc(101% - 2px) 99%,#0000 101%);  
  --c2: radial-gradient(68.08px at 50% -60px,#0000 calc(99% - 2px),#000 calc(101% - 2px) 99%,#0000 101%);  
  --s1: 120px 32px repeat-x;  
  --mask:  
    var(--c1) 0 calc(50% - 16px + .5px) / var(--s1),  
    var(--c2) var(--s) calc(50% + 16px) / var(--s1),  
    var(--c1) 0 calc(50% - 6px + .5px)  / var(--s1),  
    var(--c2) var(--s) calc(50% + 26px) / var(--s1),  
    var(--c1) 0 calc(50% + 20px + .5px) / var(--s1),  
    var(--c2) var(--s) calc(50% + 52px) / var(--s1),  
    var(--c1) 0 calc(50% + 30px + .5px) / var(--s1),  
    var(--c2) var(--s) calc(50% + 62px) / var(--s1);  
  background: #aaa;  
  margin: 0;  
  height: 100vh;  
  transition: --c 1s;  
  overflow: hidden;  
  
  &:hover {  
    --c: #000;  
  }  

  &::before {  
    content: "";  
    position: absolute;  
    inset: 0;  
    background: linear-gradient(90deg, #000 50%, var(--c) 0) 0 0 / calc(var(--s) * 2) 100%;  
    mask: var(--mask);  
    translate: 0 -100px;  
  }  

  &::after {  
    content: "";  
    position: absolute;  
    inset: 0;  
    background: linear-gradient(90deg, #000 50%, var(--c) 0) calc(var(--s) / -2) 0 / calc(var(--s) * 2) 100%;  
    translate: 0 100px;  
    mask: var(--mask);  
  }  
}

灰色圆圈错觉

你看到红、蓝、绿的圆球了吗?要是我告诉你它们都是灰色的呢?(真的!鼠标悬停在演示上就能看到本色)但在上面叠了些原色后,大脑会用看到的颜色“填补”圆圈。一开始我把线条画太高,效果就看不出来了。我喜欢最终效果。

灰色圆圈错觉-效果图

/* 光学错觉  
三个“圆球”颜色相同,但叠加图层后看着像绿的、红的、蓝的。鼠标悬停揭晓;  
*/  
body {  
  --size: 1em;  
  --line-size: calc(var(--size) / 3);  
  font-size: 10px;  
  margin: 0;  
  height: 100vh;  
  overflow: hidden;  

  &::after {  
    content: "";  
    width: calc(var(--size) * 30);  
    height: calc(var(--size) * 30);  
    position: absolute;  
    top: calc(var(--size) * 20);  
    left: 50%;  
    translate: -50% -33.333%;  
    background:  
      radial-gradient(farthest-side circle, #fff 0%, #bbb 66.66%, #0000 calc(66.66% + 1px)) 0 0 / 33.333% 100%;  
    background:  
      radial-gradient(farthest-side circle at 45% 45%, #0000 60%, #0004) 0 0 / 33.333% 33.333%,  
      radial-gradient(farthest-side circle at 33% 33%, #fffc 0%, #fff0) 0 0 / 33.333% 33.333%,  
      radial-gradient(farthest-side circle at 20% 20%, #0000 0%, #0004) 0 0 / 33.333% 33.333%,  
      #ba9;  
    mask:  
      radial-gradient(farthest-side circle, #fff 66.66%, #0000 calc(66.66% + 1px)) 0 0 / 33.333% 33.333% intersect,  
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 0 0 / 33.333% 33.333% no-repeat,  
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 50% calc(var(--size) / 3) / 33.333% 33.333% no-repeat,  
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 100% calc(var(--size) / 3 * 2) / 33.333% 33.333% no-repeat,  
      
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 0 calc(50% + var(--size) / 3) / 33.333% 33.333% no-repeat,  
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 50% calc(50% + var(--size) / 3 * 2) / 33.333% 33.333% no-repeat,  
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 100% 50% / 33.333% 33.333% no-repeat,  
      
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 0 calc(100% + var(--size) / 3 * 2) / 33.333% 33.333% no-repeat,  
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 50% 100% / 33.333% 33.333% no-repeat,  
      repeating-linear-gradient(#000 0 calc(var(--size) / 3 * 2), #0000 0 var(--size)) 100% calc(100% + var(--size) / 3) / 33.333% 33.333% no-repeat;  
  }  

  &::before {  
    content: "";  
    width: 100%;  
    height: 100%;  
    top: 0;  
    left: 0;  
    position: absolute;  
    background:  
      linear-gradient(#00f 33.33%, #0f0 0 66.66%, #f00 0) 0 0 / var(--size) var(--size);  
    transition: height 1s;  
  }  

  &:hover {  
    &::before {  
      height: 0;  
    }  
  }  
}

灰色条纹错觉

两侧竖条和中间横线都是同一种平涂灰色——没错,单一灰度。唯一的渐变是背景,线条本身没有。我喜欢这个演示,容易看清也容易编。

灰色条纹错觉-效果图

/* 视觉效果  
中间的横线看着像从浅灰到深灰的渐变,但其实全是同色。这和屏幕两侧的竖条颜色一样,尽管一边看着比另一边暗。  
*/  
body {  
  height: 100vh;  
  margin: 0;  
  background:  
    linear-gradient(#aaa 0 0) 0 0 / 5vw 100%,  
    linear-gradient(#aaa 0 0) 100% 0 / 5vw 100%,  
    linear-gradient(#aaa 0 0) 50% 50% / 70% 7.5vw,  
    linear-gradient(90deg, #666, #eee);  
  background-repeat: no-repeat;  
}

吸方块错觉-效果图

另一个动画效果的,得去CodePen看。蓝色方块看似在脉动或呼吸,依次变大变小……但其实它是同一个方块,大小没变,只是在旋转。鼠标悬停就能看清。


/* 光学错觉  
背景里的方块看似在像呼吸或心跳一样胀缩。其实它只是旋转,大小一直不变。鼠标悬停揭晓。  
*/  
@keyframes spin {  
  0% { rotate: 0; }  
  100% { rotate: 360deg; }  
}  

body {  
  &::before {  
    content: "";  
    position: absolute;  
    top: 50%;  
    left: 50%;  
    translate: -50% -50%;  
    background: blue;  
    width: 40vmin;  
    aspect-ratio: 1;  
    animation: spin 4.5s linear infinite;  
  }  
  
  &::after {  
    content: "";  
    position: absolute;  
    top: 50%;  
    left: 50%;  
    translate: -50% -50%;  
    background: conic-gradient(at 80% 80%, #0000 75%, #097 0) 0 0 / 55.5% 55.5%;  
    width: 80vmin;  
    aspect-ratio: 1;  
    scale: 1;  
    transition: scale 1s;  
  }  
  
  &:hover {  
    &::after {  
      scale: 8;  
    }  
  }  
}

接下来几周北京心玥软件公司还会继续加新的。


加载中~