整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

"探秘CSS3:打造视觉盛宴-深度解析渐变、阴影与遮罩技

秘CSS3:打造视觉盛宴——深度解析渐变、阴影与遮罩技术

随着Web技术的不断演进,CSS3以其强大的视觉表现力,赋予网页设计无限可能。本文将深入剖析CSS3中的三大视觉魔法工具——渐变、阴影与遮罩技术,通过详尽的理论讲解和丰富的实例演示,助您掌握这些技巧,打造出令人眼前一亮的网页视觉盛宴。

一、魅力渐变:色彩的艺术流动

1. 线性渐变:平滑过渡,简约而不简单

css
background: linear-gradient(to right, #ff6b6b, #ff9595);

上述代码创建了一个从左至右,由#ff6b6b渐变到#ff9595的线性渐变背景。您可以调整方向(如`to bottom`、`45deg`等)、添加更多颜色停止点来丰富渐变效果。

2. 径向渐变:聚焦视觉中心,营造立体感

css
background: radial-gradient(circle at center, #f7f7f7, #dcdcdc);

此例中,我们创建了一个以元素中心为圆心,从#f7f7f7渐变到#dcdcdc的圆形径向渐变背景。通过调整形状(如`ellipse`)、大小(如`closest-side`)和位置(如`top left`),可以灵活定制径向渐变样式。

二、立体阴影:赋予元素生命与空间感

1. 盒子阴影(Box Shadow):轻松实现三维效果

css
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);

上述代码为元素添加了一个向右下偏移2px、模糊半径为8px、颜色为rgba(0, 0, 0, 0.3)的阴影。理解盒阴影的基本参数(水平偏移、垂直偏移、模糊半径、扩散半径、颜色)并灵活运用,即可创造出丰富的阴影效果。

2. 文本阴影(Text Shadow):让文字跃然纸上

css
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.½), -1px -1px 2px rgba(255, 255, 255, 0.5);

此处为文本设置了两个阴影:一个向右下偏移、颜色较深的阴影,以及一个向左上偏移、颜色较浅的阴影,形成微妙的浮雕效果。通过叠加多个阴影、调整参数,您可以创作出各种独特的文本样式。

三、神奇遮罩:掌控元素可见度与透明度

1. CSS Mask:精细裁剪,展现独特视界

css
mask-image: linear-gradient(to right, transparent 0%, black 50%, transparent 100%);

该代码为元素应用了一个从左至右的线性渐变遮罩,使得元素左侧和右侧各有一半区域透明。您还可以使用`mask-mode`、`mask-repeat`、`mask-position`等属性进一步调整遮罩行为。

2. CSS Clip Path:创意裁剪,打破常规布局

css
clip-path: polygon(0 0, 100% 0, .png);

上述代码使用多边形裁剪路径,将元素顶部裁剪成尖角形状。您还可以使用椭圆、圆形、内切/外切矩形等多种路径类型,甚至借助SVG路径实现更为复杂的裁剪效果。

四、实战案例:融合三大技术,打造视觉盛宴

案例一:动态渐变按钮

css
/* 定义CSS变量 */
:root {
  --start-color: #ff6b6b;
  --end-color: #ff9595;
}

.button {
  background: linear-gradient(to right, var(--start-color), var(--end-color));
  transition: background 0.3s ease-in-out;
}

.button:hover,
.button:focus {
  --start-color: #ff9595;
  --end-color: #ff6b6b;
}

利用CSS变量、伪类和动画,创建一个点击时背景渐变颜色动态变化的按钮:

案例二:悬浮卡片与阴影交互

css
.card {
  box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);
}

.card:hover {
  box-shadow: 4px 4px 16px rgba(0, 0, 0, 0.5);
}

结合盒子阴影与:hover伪类,实现鼠标悬停时卡片阴影增强的交互效果:

案例三:遮罩叠加文字特效

css
.image-overlay {
  background-image: url('image.jpg'), linear-gradient(to bottom, transparent, black);
  background-blend-mode: multiply;
  mask-image: linear-gradient(to bottom, transparent 0%, black 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 100%);
}

利用遮罩与多重背景,创造出文字在图片上淡入淡出的特效:

结语

CSS3的渐变、阴影与遮罩技术,如同网页设计的调色板、光影魔术师和剪刀手,赋予网页视觉表现无尽的可能性。通过深入理解并熟练运用这些技术,您将能打造出既美观又富有创意的网页界面,为用户带来极致的视觉体验。持续探索、实践与创新,您的每一个作品都将成为Web世界中的一道独特风景。

最近在业务上遇到了一个问题是要将页面打印输出成pdf文件,通过点击一个按钮,就能够将页面写在一个pdf上,并下载下来,需要保证pdf的内容具有很好的可读性。

经评估要实现这个需求,一种可行的方案是将HTML页面转为PDF,并实现下载。通过技术调研,最终的方案确定为通过html2canvas + jspdf这两个库来实现,通过使用html2canvas提供的方法,将页面元素转为base64图片流,然后将其插入jspdf插件中,实现保存并下载pdf。

html2canvas + jspdf方案是前端实现页面打印的一种常用方案,但是在实践过程中,遇到的最大问题就是分页截断的问题:当页面元素超过一页A4纸的时候,连续的页面就会因为分页而导致内容被截断,进而影响了pdf的可读性。

由于网上关于分页截断的解决思路比较少,所以特意将此次的解决方案记录下来。

使用 JSPDF 和 html2canvas 创建简单的 PDF文件

首先,我们开始使用 JSPDF 和 html2canvas 生成一个简单的 PDF文件。

创建一个 JSPDF 实例

创建一个 JSPDF 实例,设置页面的大小、方向和其他参数。参考官网可以写一个很简单的实例

var doc = new jsPDF({
  orientation: 'landscape',
  unit: 'in',
  format: [4, 2]
}

doc.text('Hello world!', 1, 1)
doc.save('two-by-four.pdf')

生成一个pdf文件,并且在文件中写入一定内容,其实JSPDF这个库就能做到。

但是很多业务场景下,我们的目标内容会更复杂,而且还要考虑样式,所以最好的方式是引入html2canvas这个库,将页面元素转换成base64数据,然后贴在pdf中(使用addImage方法),这样就能保证页面的内容。

引入了html2canvas库后,我们更多关注是利用现成组件库、框架或者原生html和css实现更复杂的页面内容

引入 html2canvas

使用 html2canvas 捕捉 HTML 内容或特定的 HTML 元素,并将其转换为 Canvas。其中,html2canvas 函数的主要用法是:

html2canvas(element, options);
  • element 要渲染为 canvas 的 HTML 元素。这可以是一个 DOM 元素,也可以是一个选择器字符串,表示需要渲染的元素。
  • options(可选): 一个包含配置选项的对象,用于定制 html2canvas 的行为。

以下是一些常见的配置选项:

  • allowTaint(默认值: false): 是否允许加载跨域的图片,默认为 **false**。如果设为 truehtml2canvas 将尝试加载跨域的图片,但在某些情况下可能会受到浏览器的限制。
  • backgroundColor(默认值: #ffffff): canvas 的背景颜色。
  • useCORS(默认值: false): 是否使用 CORS(Cross-Origin Resource Sharing)来加载图片。如果设置为 **true**,则 html2canvas 将尝试使用 CORS 来加载图片。
  • logging(默认值: false): 是否输出日志信息到控制台。
  • widthheight canvas 的宽度和高度。如果未指定,则默认为目标元素的宽度和高度。
  • scale(默认值: window.devicePixelRatio): 缩放因子,决定 canvas 的分辨率。

下面是一个简单的demo,可以看到html2canvas能够将dom元素转化为一张base64图片,将鼠标选中元素,可以感受到图片和文字的不同。

<div id="capture" style="padding: 10px; background: #f5da55">
    <h4 style="color: #000; ">Hello world!</h4>
</div>
html2canvas(document.querySelector("#capture")).then(canvas => {
    document.body.appendChild(canvas)
});

Untitled.png

将html2canvas转化的图片放到pdf中

这一步我们需要使用JSPDF 的addImage方法,其语法如下:

addImage(imageData, format, x, y, width, height, alias, compression)
  • imageData - 要添加的图像数据。可以是图像的 URL、图像的 base64 编码字符串或图像的二进制数据
  • format - 图像的格式。可以是 "JPEG"、"PNG" 或 "TIFF"。
  • x - 图像在 PDF 文档中的 x 坐标。
  • y - 图像在 PDF 文档中的 y 坐标。
  • width - 图像的宽度。
  • height - 图像的高度。
  • alias - 图像的别名。此别名可用于在 PDF 文档中引用图像。
  • compression - 图像的压缩级别。可以是 "NONE"、"FAST" 或 "SLOW"。

下面是一串示例代码:

import jsPDF from 'jspdf';

export default function addImageUsage() {
  const doc = new jsPDF();
  const imageData = 【替换成base64数据流】;
  doc.addImage(imageData, 'png', 0, 0, 10, 10);
  doc.addImage(imageData, 'png', 100, 100, 10, 10);
  doc.addImage(imageData, 'png', 200, 200, 10, 10);

  drawNet(doc);

  doc.save('output.pdf');
}

const drawNet = (doc) => {
  const gap = 10;
  const start = [0, 0];
  const end = [595.28, 841.89];

  // 所有横线
  for (let i = start[0]; i < end[0]; i = i + gap) {
    doc.line(i, 0, i, end[0]);
  }
  // 所有纵线
  for (let j = start[1]; j < end[1]; j = j + gap) {
    doc.line(0, j, end[1], j);
  }
};

此示例将在 PDF 文档(默认是A4纸大小,宽高为[595.28, 841.89]像素)的 (10, 10)(100, 100)(200, 200) 坐标处,添加一张png 图像。图像的宽度和高度将分别为 10 和 10 像素,为了了解pdf中的坐标系统,此示例还在pdf文档中生成了间距为10px的网格系统。

JSPDF 和 html2canvas结合起来用

了解了上面的三个关键点,接下来我们将这三个步骤串联起来,实现一个基本的html→pdf的方案。大致步骤如下:

  1. 写一个基本html页面
  2. 创建jspdf实例
  3. 获取页面的dom节点,使用html2canvas将其转化为base64数据流
  4. base64数据流装载到jspdf提供的addImage方法中
  5. 保存pdf

基于这5个步骤,可以实现基本的页面打印。

import html2canvas from 'html2canvas';
import jsPDF, { RGBAData } from 'jspdf';

// 将元素转化为canvas元素
// 通过 放大 提高清晰度
// width为内容宽度
async function toCanvas(element: HTMLElement) {
  if (!element) return { width: 0, height: 0 };

  // canvas元素
  const canvas = await html2canvas(element, {
    scale: window.devicePixelRatio * 2, // 增加清晰度
    useCORS: true // 允许跨域
  });

  // 获取canvas转化后的宽高
  const { width: canvasWidth, height: canvasHeight } = canvas;

  // 转化成图片Data
  const canvasData = canvas.toDataURL('image/jpeg', 1.0);

  return { width: canvasWidth, height: canvasHeight, data: canvasData };
}

/**
 * 生成pdf(A4多页pdf截断问题, 包括页眉、页脚 和 上下左右留空的护理)
 */
export async function generatePDF({
  /** pdf内容的dom元素 */
  element,

  /** pdf文件名 */
  filename
}) {
  if (!(element instanceof HTMLElement)) {
    return;
  }

  const pdf = new jsPDF();

  // 一页的高度, 转换宽度为一页元素的宽度
  const {
    width: imageWidth,
    height: imageHeight,
    data
  } = await toCanvas(element);

  // 添加图片
  function addImage(
    _x: number,
    _y: number,
    pdfInstance: jsPDF,
    base_data:
      | string
      | HTMLImageElement
      | HTMLCanvasElement
      | Uint8Array
      | RGBAData,
    _width: number,
    _height: number
  ) {
    pdfInstance.addImage(base_data, 'JPEG', _x, _y, _width, _height);
  }

  addImage(0, 0, pdf, data!, imageWidth, imageHeight);

  return pdf.save(filename);
}

多页:比例缩放+循环移位

通常,在我们的实践中,会发现2个问题:

  • 生成的pdf内容与实际的页面元素比例不一致
  • 页面内容超出一页pdf的高度,但是生成的pdf只有一页,没有展示全部的页面信息

这两个问题的解决方案是等比例缩放+循环移位

  • 等比例缩放

通过比例缩放,实现页面内容等比例展示在pdf文档中

令页面元素的宽高为x, y(转化成canvas图片的宽高),pdf文档的宽高为w, h。因为高度可以通过加页延伸,所以可以按照宽度进行缩放,缩放后的图片高度可以通过下列公式计算

  • 循环移位

如果页面的高度超出了pdf文档的高度,即y > h,使用addPage方法添加一页即可。但是在新的一页中,我们的图片内容的高度需要调整。

假设y = 2 * h,这意味我们需要两页才能完整得展示页面内容。在一页pdf中,图片在起始位置插入即可,即

 PDF.addImage(pageData, 'JPEG', 0, 0, x, y)// 注意x,y 是缩放后的大小

在第二页pdf中,图片的纵向位置需要调整一页pdf的高度,即

 PDF.addImage(pageData, 'JPEG', 0, -h, x, y)// 注意x,y 是缩放后的大小

通过循环计算剩余高度,然后不停调整纵向位置移动base64的图片位置,可以解决多页的问题。

分页截断的挑战

尽管 JSPDFhtml2canvas 是功能强大的工具,但是他们也有很多槽点,比如得手动分页,手动处理分页截断的问题。等你实践到这一步,就开始面临分页截断的问题,类似的问题也有网友在Github上提出,但是底下依然没有很好的解决思路。

好在掘金上有人分享了一个不错的方法:

jsPDF + html2canvas A4分页截断 完美解决方案(含代码 + 案例) - 掘金

概括一下,其处理分页截断的原理就是在使用addImage之前,将html进行分页,通过维护一个高度位置数据,来记录每次循环迭代addImage的位置。

从高到低遍历维护一个分页数组pages,该数组记录每一页的起始位置,如:pages[0] 对应 第一页起始位置,pages[1] 对应第二页起始位置

Untitled2.png

接下来我们重点讨论如何将页面进行切割,然后生成pages这个数组。

假设页面的高度是1500,pdf宽高是[500, 900],如果不用处理分页截断的问题,我们可以想到第一页(0-900)是用来承载页面从高度为0到900的信息;

第二页(900-1800)是用来承载页面从高度900到1500的,所以pages数组为[0, 900]。

如果要处理分页截断呢,这时候就需要计算页面元素的距离pdf文档起始位置的高度h1,以及该元素的内部高度h2,通过这两个高度来判断这个元素要不要放在下一页,防止截断,示意图如下:

Untitled4.png

如果h1 + h2 > 页面高度, 这时候说明这个元素不处理的就会被分页截断,所以应该要把这个元素放到第二页去渲染,这就意味着pages记录的数据要变化,示意图如下,可以看到pages[1]我们往上调整了,比第二页pdf的起始位置更高。

Untitled5.png

说明渲染第二页pdf的时候,要从h1开始渲染,pages数组为[0, h1],解释为第一页pdf渲染页面高度区域为0-900, 第二页pdf渲染html高度区域为h1-1500。注意到第一页渲染的时候到尾部的时候,会有部分内容和第二页头部内容重合。因为h1900这部分的内容肯定会渲染,这部分内容一直都是页面元素,我们改变pages[1]的值的原因只是创建一个副本,让页面看起来内容没有被截断。

为了解决这个问题(为了美观),我们用填充一块白色区域遮掉它!此处使用jspdfrectsetFillColor方法,把重合的区域遮白处理。

pdf.setFillColor(255, 255, 255);
pdf.rect(x, y, Math.ceil(_width), Math.ceil(_height), 'F');

如何获得h1和h2

上面我们谈到了h1h2,其中h1是元素盒子的上边距到打印区域的高度(比例缩放后的高度),h2是元素盒子的内部高度。

计算h1: getBoundingClientRect方法

const rect = contentElement.getBoundingClientRect() || {};
const topDistance = rect.top;
return topDistance;

Untitled6.png

计算h2:offsetHeight方法

Untitled7.png

值得注意的是,因为打印区域的html元素不一定是从窗口顶部开始,所以为了计算实际的h1(元素到打印区域的顶部距离),可以采用这样的方法:

  • getBoundingClientRect方法计算元素到窗口顶部的距离
  • 循环打印之前将pages信息针对第一个元素进行一个高度校准。
// 对pages进行一个值的修正,因为pages生成是根据根元素来的,根元素并不是我们实际要打印的元素,而是element,
  // 所以要把它修正,让其值是以真实的打印元素顶部节点为准
  const newPages = pages.map((item) => item - pages[0]);

在线demo演示和源代码

上述即是在实现前端页面生成pdf的过程中遇到的问题,以及解决思路。

为了更直观得感受效果,本文也给出了不同场景(单页、多页、多页截断、自定义页眉页脚、横向)下的pdf生成效果,可以通过此链接体验:https://pdf-demo-phi.vercel.app/

此demo的源代码如下:pdf-demo

与现有文章不同的是,本仓库的代码特点在于:

  • 支持设置pdf打印的方向,比如横向
  • 修正了高度计算问题,解决了多出一个空白页问题。掘金那篇文章计算元素高度时候没有减去容器距离顶部高度,所以导致很多新手使用那份代码的时候,会发现自己的页面顶部被裁剪到了,原因就是这个
  • 支持自定义页眉页脚
  • 支持扩展自定义分页方法,如果遇到复杂的组件,可以自定扩展逻辑计算高度

作者:燕平

来源:微信公众号:Goodme前端团队

出处:https://mp.weixin.qq.com/s/-1nA-VI6kmgqHRcYs_NZFA

文:https://blog.csdn.net/TriDiamond6/article/details/105222289

5. 图片视差效果

这个超级炫酷的效果在官网中非常的受欢迎,这种效果可以给用户带来视觉冲击,也给我们的网站带来了活力。普通的网页图片会跟随着网页一起滑动,但是视觉差效果图就会固定在底部,只有图片所在的窗口上的元素会移动。

仅使用CSS

对你没有看错,这个效果只需要用到CSS就能轻易的实现!我们只要使用一个CSS背景图的属性background-attachment: fixed,这个特性会把背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。

实现理论:

一、在含有图片的元素中加入background: url()和background-size: cover(第二个属性适用于定义图片为封面,可以让图片大小自动适应,在很大的屏幕也会显示完整的图片)

二、然后附加固定背景图的属性background-attachment: fixed

三、最后给这个元素加入一个高度height: 100%或者任意的高度height: 400px

就那么简单哦!不用怀疑,马上上代码,大家都可以自己去试试哦!

HTML

<div class="wrapper">
   <div class="parallax-img"></img>
   <p>这里填写一堆文字就可以了,尽量多一点哦</p>
</div>

CSS

.wrapper {  
  height: 100wh;
}
.parallax-img {  
  background-attachment: fixed;  
  background-position: center;  
  background-repeat: no-repeat;  
  background-size: cover;  
  height: 100%;  
  background-image: url("http://ppe.oss-cn-shenzhen.aliyuncs.com/collections/182/7/thumb.jpg");
}
p {  
  font-size: 20px;  
  padding: 1.5rem 3rem;  
  min-height: 1000px; 
  // 当你的文字内容不够,也能撑出足够的高度来看到效果,当然如果你文字足够多,就不需要了
}

知识总结

  • background-attachment: fixed — 把背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。
  • background-size: cover — 可以让图片大小自动适应,在很大的屏幕也会显示完整的图片。

使用CSS + JavaScript

有些童鞋可能没有被这个震撼到或者还是觉得不够刺激。那我们再来一个高级例子,上面的例子在滑动的时候图片是固定死的。如果我们加上JavaScript的助力,我们可以让窗口的图片缓慢的跟随这个页面滑动,使得效果更有动力和更有冲击感。

实现理论

首先讲一下排版,因为我们需要在我们滑动页面的时候使用JavaScript偏移图片,所以我们需要给图片一个CSS属性让我们可以让图片可以根据一个速度来往上或者往下移动。这个例子里面我们让所有图片包裹在一个div里面,class名为block。这个div给予相对定位属性position: relative,这个时候我们就可以在里面加入图片,然后让图片绝对定位position: absolute在这个div盒子里面。

但是图片是可能很大的,我们需要把图片不超出我们定义个盒子,所以我们的div同时也给予了overflow: hidden和一个高度height: 100%。这样图片超出div盒子就会被隐藏。


布局代码如下:

<div class="block">  
  <img    src="https://unsplash.it/1920/1920/?image=1005"    data-speed="-1"    class="img-parallax"  />  
    <h2>视差速度 -1</h2>
</div><div class="block">  
<img    src="https://unsplash.it/1920/1920/?image=1067"    data-speed="1"    class="img-parallax"  />  
  <h2>视差速度 1</h2>
</div>
html, body{  
  margin: 0;  
  padding: 0;  
  height: 100%;  
  width: 100%;  
  font-family: 'Amatic SC', cursive;
}
.block{  
  width: 100%;  
  height: 100%;  
  position: relative;  
  overflow: hidden;  
  font-size: 16px;
}
.block h2{  
  position: relative;  
  display: block;  
  text-align: center;  
  margin: 0;  
  top: 50%;  
  transform: translateY(-50%);  
  font-size: 10vw;  
  color: white;  
  font-weight: 400;
}
.img-parallax {  
  width: 100vmax;  
  z-index: -1;  
  position: absolute;  
  top: 0;  
  left: 50%;  
  transform: translate(-50%,0);  
  pointer-events: none
}

实现这个布局,在你滑动的时候,图片是不会移动的。因为最后一步就是加入JavaScript的辅助,让图片活起来。

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">
  </script><script>
// 循环获取每一个图片元素
$(".img-parallax").each(function () {  
  var img = $(this);  
  var imgParent = $(this).parent();  
  function parallaxImg() {    
    var speed = img.data("speed"); /
    / 获取每张图片设置了的偏移速度    var imgY = imgParent.offset().top; // 获取图片盒子所在的Y位置    var winY = $(this).scrollTop(); // 获取当前滑动到的位置    var winH = $(this).height(); // 获取浏览器窗口高度    var parentH = imgParent.innerHeight(); // 获取图片盒子的内高度    // 浏览器窗口底部的所在位置    var winBottom = winY + winH;     // 当前图片是否进入浏览器窗口    if (winBottom > imgY && winY < imgY + parentH) {      // 运算图片需要开始移动的位置      var imgBottom = (winBottom - imgY) * speed;      // 运算出图片需要停止移动的位置      var imgTop = winH + parentH;      // 获取从开始移动到结束移动的%(根据开始与结束像素 + 移动速度)      var imgPercent = (imgBottom / imgTop) * 100 + (50 - speed * 50);    }    img.css({      top: imgPercent + "%",      transform: "translate(-50%, -" + imgPercent + "%)",    });  }  $(document).on({    scroll: function () {      parallaxImg();    },    ready: function () {      parallaxImg();    },  });});</script>

知识总结

  • position: relative — 相对定位。
  • position: absolute — 绝对定位。
  • overflow: hidden — 如果需要,内容将被剪裁以适合填充框。不提供滚动条。

6. 裁剪图像的动画

在有CSS3之前裁剪图片实现也是颇有难度的。现在我们有了两个非常方便简单的CSS3属性可以实现裁剪,那就是object-fit和object-position, 这两个属性可以让我们改变图片的大小,但是不影响图片的长宽比。

当然我们可以使用图片处理工具或者使用JavaScript等插件来实现图片裁剪功能。但是因为有了CSS3的属性,我们不只可以裁剪,我们还可以用裁剪的属性来做图片的动态效果。

为了让我们的例子更加简单,我们这里使用了<input type="checkbox">复选框元素,这样我们就可以使用:checked的伪类来触发启动效果。所以在例子里面我们完全不需要JavaScript的协助。

实现原理:

一、首先给予图片一个宽高height: 1080px,width: 1920px。

二、然后用CSS选择器,锁定当input被选中后img标签的样式变化。当被选中时,给图片设定一个新的宽高,这里我们给宽高各自500像素:width: 500px,height: 500px。

三、然后我们加上了过渡效果和时间让图片改变宽高时有动画过渡效果:transition: width 2s, height 4s;。

四、最后加上object-fit: cover和object-position: left-top这两个属性来保持图片的宽高比例,这样就大功告成了!

我们来看看完成的代码:

勾选裁剪图片 
  <input type="checkbox" />
    <br />
    <img  src="https://img-blog.csdnimg.cn/2020032122230564.png"  alt="Random"/>
input {  
  transform: scale(1.5); 
  /* 只是用来放大复选框大小 */  
  margin: 10px 5px;  
  color: #fff;
}
img {  
  width: 1920px;  
  height: 1080px;  
  transition: 0s;
}
/* css选择器锁定复选框被选中时的状态 */
input:checked + br + img {  
  width: 500px;  
  height: 500px;  
  object-fit: cover;  
  object-position: left-top;  
  transition: width 2s, 
  height 4s;
}

知识总结

object-fit — CSS 属性指定可替换元素的内容应该如何适应到其使用的高度和宽度确定的框。

object-position — 用来切换被替换元素的内容对象在元素框内的对齐方式。

transition — 过渡可以为一个元素在不同状态之间切换的时候定义不同的过渡效果。

7. 混合模式(Blend)

如果有使用过Photoshop的同学对blend混合模式应该是非常熟悉了,我们都知道混合模式是非常强大,也是p图时非常常用的一个功能。但是你们有没有想象过可以在浏览器的CSS中直接使用呢?对我们不需要设计师给我们做图,我们前端也可以实现混合模式了。

在CSS中我们不只可以对background背景加入混合模式,我们可以对任何一个元素的自带背景加入混合模式,让你可以做出很多之前没有想过的效果和排版。

往一个元素加入混合模式,我们只需要使用到一个CSS属性mix-blend-mode即可。

简单实现原理:

首先我们只需要加一个h1标题标签

<h1>混合模式:颜色减淡</h1>

然后我们给h1标签加入mix-blend-mode中的颜色减弱模式color-dodge,但是要注意的是我们需要给body和html加入背景颜色background: white,要不你会发现这个效果会无效。因为h1我们没有给颜色,会自动往上级继承,并且混合模式是针对背景颜色的过滤,所以body和html需要有背景颜色才行。

h1 {   
  mix-blend-mode: color-dodge;   
  font-family: yahei;   
  font-size: 5rem;   
  text-align: center;   
  margin: 0;    
  padding: 20vh 200px;   
  color: #D1956C; 
} 
html, body {   
  margin: 0;   
  background-color: white; 
} 
body {   
  background-image: url(https://images.unsplash.com/photo-1505567745926-ba89000d255a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3302&q=80);   
  background-repeat: no-repeat;   
  background-size: cover;   
  min-height: 100vh;   
  overflow: hidden; 
}

换换背景图和h1标签的字体颜色就可以弄出各种不同的特效了。

知识总结

  • mix-blend-mode — CSS 属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。

8. 瀑布流布局

CSS Grid和Flexbox让我们可以更简便,更容易和更快的实现各式各样的响应布局,并且让我们快捷方便的在布局中实现横向剧中和竖向剧中。但是回想一下以前是颇为困难的。

虽然这些新出的布局方式可以让我们解决很多以前的布局难题,但是像瀑布流布局这种,就无法用它们简单来实现了。因为瀑布流一般来说都是宽度一致,但是高度是根据图片自适应的。并且图片的位置也是根据在上方图片的位置而定的。

其实最好实现瀑布流布局的办法就是用CSS的列属性套件,这套属性大多数都是用于排版杂志中的文本列。但是用于布局瀑布流也是特别实用哦。因为以前需要实现瀑布流,就必须有JavaScript的辅助来计算图片高度然后决定每张图片的定位和位置,所以现在有了列属性就可以使用纯CSS实现了。

实现原理:

实现这个布局,首选我们需要把所有的内容先包裹在一个div元素里面,然后给这个元素column-width和column-gap属性。

然后,为了防止任何元素被分割到两个列之间,将column-break-inside: avoid添加到各个元素中。

神奇的效果就完美实现了,零JavaScript。

我们来看看代码:

<div class="columns">  
  <figure>    
  	<img src="https://source.unsplash.com/random?city" alt="" />  
    </figure>  
	<figure>    
    <img src="https://source.unsplash.com/random?night" alt="" />  
  </figure>  
  <figure>    
    <img src="https://source.unsplash.com/random?developer" alt="" />  
  </figure>  
  <figure>    
    <img src="https://source.unsplash.com/random?building" alt="" />  
  </figure>  
  <figure>    
    <img src="https://source.unsplash.com/random?water" alt="" />  
  </figure>  
  <figure>    
    <img src="https://source.unsplash.com/random?coding" alt="" />  
  </figure>  
  <figure>    
    <img src="https://source.unsplash.com/random?stars" alt="" />  
  </figure>  
  <figure>    
    <img src="https://source.unsplash.com/random?forest" alt="" />  
  </figure>  
  <figure>    
    <img src="https://source.unsplash.com/random?girls" alt="" />  
  </figure>  
  <figure>    
    <img src="https://source.unsplash.com/random?working" alt="" />  
  </figure>
</div>
.columns {  
  column-width: 320px;  
  column-gap: 15px;  
  width: 90%;  
  max-width: 1100px;  
  margin: 50px auto;
}
.columns figure {  
  display: inline-block;  
  box-shadow: 0 1px 2px rgba(34, 25, 25, 0.4);  
  column-break-inside: avoid;  
  border-radius: 8px;
}
.columns figure img {  
  width: 100%;  
  height: auto;  
  margin-bottom: 15px;  
  border-radius: 8px;
}

知识总结

column-width — CSS属性建议一个最佳列宽。列宽是在添加另一列之前列将成为最大宽度。

column-width — 该 CSS 属性用来设置元素列之间的间隔 (gutter) 大小。

column-break-inside — 设置或检索对象内部是否断。

总结

我希望这8个前端小技巧和特效对大家有帮助,或多或少有吸收一点新的前端知识。这篇文章提到的内容,其实很多都是值得深挖和学习的。有一些例子我做的比较简单,但是其实是有无限的可能性。喜欢前端的童鞋们,让我们继续在前端领域中一起深挖,让我们的热爱无限的燃烧起来吧!

在最后我想给大家讲一下我对前端的热爱和态度。

回想前端这几年,发展真的是突飞猛进,从前端排版,HTML5+CSS3做H5页面,到前端组件化,各种UI框架满天飞。

一开始我随着热潮用起了UI框架,起初觉得特别方便,来一个新的项目就直接上一个UI框架,研发速度也非常快。但是久而久之就觉得前端开发变成了处理数据,对接接口,实现交互。

某天在阅览国外的一些前端设计和框架的时候,我突然发现国内多数的前端开发者都不再怎么使用CSS3做出一些很好玩的布局和特效了。现在市面上的系统和页面都是千篇一律,普遍都是用一些知名的UI框架搭建系统和APP,基本自己动手去排版已经少之又少。前端已不再是以前的前端,缺少了灵魂。

但是我们回想一下,我们刚刚开始学习前端的时候,让我们最有成就感,觉得前端特别有意思的那种感觉。就是那种让我们觉得神乎奇迹,不可思议的布局,特效和交互。那种感觉自己成功实现了很优美,很炫酷的页面和特效的感觉,让我们越做越来劲,越做越是兴奋。

但是在某些公司,研发部都是要求快速开发,UI设计部门也是受到时间的控制和限制,所以逐步走进了UI框架的限制之中。都是围绕这一些UI框架来设计和开发系统和应用。

作为一名热爱前端的开发者,我还是坚持在绝大多数的项目中,自己排版和实现页面交互特效。然后使用UI框架作为辅助,主要是用来减轻一些小组件和常用组建的快速实现。(可以说我是比较追求完美和外貌协会的程序员 )

————————————————

版权声明:本文为CSDN博主「三钻」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/TriDiamond6/article/details/105222289