手把手实现一个简约酷美美的版权声明模块

1. 导语

版权声明在很多网站都有用到,出场率还是很高的。所以今天就实现一个属于自己分风格的版权声明模块,技术上采用原生的前端三剑客:

  • HTML
  • CSS
  • JavaScript(可能会用到)

比如CSDN的版权声明是这样的

image-20240501135811558


2. 需求分析

先看看成品吧,这篇文字结束的时候,我们大概做出来的样子就是下面这样的:

目前这个版本已经用在了我的博客网站中,欢迎随时去look look,感受一下结合实际应用的效果。直通车

image-20240501135415704

从整体的效果来看,它的实现并不复杂,作为一个名后端开发者,我都能一眼看出来结构,甚至脑阔都能浮现出来大致的代码实现了。

整体就是一个外在的盒子,里面包含了几个简单的内容元素,用来声明版权信息,盒子内左侧有一个显眼包,一个大大的 字贯穿带有一定宽度的竖条,显式的表达出它的中心立意:”劳资的作用就是版权声明!“。

大体就是这样子的啦,但在具体的实现中,还是有很多细节的,比如版权的版字的摆放位置的设计和代码中的计算方式等等。


3 . 代码实现

  • 整个模板先

为了方便阅读,这里采用外部JSCSS导入的方式,分三个文件进行。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>包含外部文件的HTML模板</title><link rel="stylesheet" href="styles.css">
</head>
<body><h1>Hello, World!</h1><p>This is a simple example of including external JavaScript and CSS files in an HTML template.</p><script src="script.js"></script>
</body>
</html>
  • 把结构草图搞出来

没什么技术含量,直接div>span*4enter即可完成。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>包含外部文件的HTML模板</title><link rel="stylesheet" href="styles.css">
</head>
<body><div><span></span><span></span><span></span><span></span></div><script src="script.js"></script>
</body>
</html>

为了方便分析,先给盒子点颜色看看,并将版权的信息加上。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>包含外部文件的HTML模板</title><link rel="stylesheet" href="./copyright.css">
</head>
<body><div class="info-box"><div><span>本文作者:</span> Gemini48</div><div><span>授权公众号:</span> 八尺妖剑</div><div><span>博客地址:</span> <a href='https://www.ilikexff.cn' style='color: #3f60de'>https://www.ilikexff.cn</a></div><div><span>声明:</span> 本博客所有文章除特别声明外,均采用 <a href='https://creativecommons.org/licenses/by-nc-sa/4.0/' style='color: #3f60de'>©BY-NC-SA</a> 许可协议。转载请注明出处及本声明!</div></div><script src="script.js"></script>
</body>
</html>

简单搞点样式,调整一下格式。这里有些样式不是必须的,只是为了方便查看结构用的,比如外边框的蓝色等等。

.info-box {margin: 20px;padding: 10px;border: 1px solid #3cb5ec;
}.info-box div {margin-bottom: 10px;color: black;font-weight: bolder;
}.info-box span, .info-box a {font-weight: bold;color: gray;
}.info-box a {color: #3f60de;
}

效果如下:

image-20240501144945725


  • 设置左侧竖形的版权条,原理比较简单,其实就是一个设置一定宽度的div,因此我们需要再次调整整体的结构:
    <div class="post-html-copyright"><div><div class="vertical-line">   <div class="square-box"></div><!--版权条目信息--><div><span>本文作者:</span> Gemini48</div><div><span>授权公众号:</span> 八尺妖剑</div><div><span>博客地址:</span> <a href='https://www.ilikexff.cn' style='color: #3f60de'>https://www.ilikexff.cn</a></div><div><span>声明:</span> 本博客所有文章除特别声明外,均采用 <a href='https://creativecommons.org/licenses/by-nc-sa/4.0/' style='color: #3f60de'>©BY-NC-SA</a> 许可协议。转载请注明出处及本声明!</div></div></div>

image-20240501145743300

可以看到,大体的效果就是这样,现在主要是通过CSS样式进一步美化和结构调整。

先从最外层的盒子开始:

  • 加一个背景颜色,虽然这里默认就是FFFFFF白,但加上这个样式可以方便后续根据需求直接修改颜色即可
  • 处理一下边框弧度,仔细看实现好的贴图,它最外层边框其实是有一定弧度的,很微妙,不容易察觉而已。
  • 设置边框阴影效果
  • 注意到盒子上下边框固定位置分别有两条红颜色的线条效果,并且上下两条所处的位置都是绝对左右严格对齐的,而相对位置上,又具有一定的位移差,凸显出一种非对称偏差的美感。
  • 这个效果将会用到linear-gradient属性完成
  • 为了帮助理解,后续的代码都会加上注释,请结合注释食用。
/* 设置宽度为65% */
width: 65%;/* 设置外边距为20px */
margin: 20px;/* 设置内边距为10px */
padding: 10px;/* 设置边框为2px宽,颜色为#e80e5a */
border: 2px solid #e80e5a;/* 设置背景颜色为白色 */
background-color: #ffffff;/* 设置边框圆角为1px */
border-radius: 1px;/* 设置阴影效果 */
box-shadow: 12px 12px 15px rgb(155, 172, 186);/* 设置变换效果的过渡时间为0.3秒,缓动函数为ease-in-out */
transition: transform 0.3s ease-in-out;/* 设置边框图案 */
border-image: linear-gradient(45deg, transparent 30%, #e80e5a 30%, #e80e5a 70%, transparent 70%) 1;/* 水平居中 */
margin: 0 auto;

实时效果:

image-20240501151054472

到此为止,距离最终的效果就一步之遥了,主要就是放在版字的处理上了。

对于这部分,我们先把左侧垂直的面条处理了

.vertical-line {/*相对定位*/  position: relative;
}.vertical-line::before {/* 创建一个空内容的伪元素 */content: '';/* 使用绝对定位,相对于最近的已定位父元素 */position: absolute;/* 从父元素的顶部开始定位 */top: 0;/* 从父元素的左侧开始定位 */left: 0;/* 水平方向平移使竖线居中 */transform: translateX(-50%);/* 竖线的宽度 */width: 5px;/* 竖线的高度占据整个父元素的高度 */height: 100%;/* 竖线的背景颜色 */background-color: #e80e5a;
}

可以通过伪元素 ::before 在元素的内部插入一个空内容的元素,并对该伪元素应用样式来实现垂直线的效果。

  • content: '';:这个属性在伪元素中是必须的,用于指定伪元素的内容为空。
  • position: absolute;:将伪元素绝对定位,相对于最近的已定位父元素。
  • top: 0;left: 0;:将伪元素放置在父元素的左上角。
  • transform: translateX(-50%);:通过 transform 属性将伪元素水平居中,translateX(-50%) 表示沿着 X 轴向左平移元素的宽度的一半。
  • width: 5px;:设置竖线的宽度为 5px
  • height: 100%;:设置竖线的高度与父元素相同,即铺满整个父元素的高度。
  • background-color: #e80e5a;:设置竖线的背景颜色为 #e80e5a,这是竖线的颜色。

image-20240501152030387

最后一步,调整 字的位置:

.square-box {/* 设置方块的宽度为20px */width: 20px;/* 设置方块的高度为20px */height: 20px;/* 设置方块的背景颜色为 #e80e5a */background-color: #e80e5a;;/* 设置文本颜色为白色 */color: white;/* 文本水平居中 */text-align: center;/* 设置行高为20px,使文本垂直居中 */line-height: 20px;/* 绝对定位 */position: absolute;/* 设置距离顶部距离为父元素高度的30% */top: 30%;/* 设置距离左侧距离为0 */left: 0;/* 将方块水平垂直居中 */transform: translate(-50%, -50%);
}

image-20240501152713876

从效果来看,似乎已经100%实现了贴图的效果,不过仔细观察还是会发现有一些瑕疵,比如竖条和右侧的文字信息的关系似乎过于亲密了,不行,得让它们明白什么叫距离产生美。

.post-html-copyright span {margin-left: 15px;
}

最终修改之后的成品和原图效果:

image-20240501154501727


其他细节就不全部贴这里了,最终的代码我会全部放在GitHubCodePen上面,需要的自取。


4. 功能扩展

在实际的业务中,一般情况下,用户如果复制了携带版权声明的文章,这个版权声明也会一并被复制到剪切板。基于这个需求,我们在上面的基础上扩展一个版权信息的复制功能。

4.1 如何实现

  • 我们需要先获取到要复制的文本内容。这里可以使用选择器去实现。
  • 使用navigator.clipboard方法实现内容的复制,为了用户体验,建议在版权内容上面添加 **版权信息:**几个字。
  • 同时不能将竖条中的 字复制进去。这块可以使用replace函数解决。

下面是这个思路的实现:

// 获取版权信息
const originalCopyright = document.querySelector('.post-html-copyright .vertical-line').innerText.replace("复制","").replace("版","");// 创建复制按钮
const copyButton = document.querySelector('.copy-button');
copyButton.addEventListener('click', async () => {try {// 将版权信息复制到剪贴板await navigator.clipboard.writeText('版权信息:\n' + originalCopyright);// 显示复制成功提示alert('版权信息已复制到剪贴板!');} catch (err) {// 处理复制失败的情况console.error('复制失败:', err);alert('复制失败,请手动复制!');}
});

复制之后粘贴出来的效果:

版权信息:

本文作者: Gemini48
授权公众号: 八尺妖剑
博客地址: https://www.ilikexff.cn
声 明: 本博客所有文章除特别声明外,均采用 ©BY-NC-SA 许可协议。转载请注明出处及本声明!


  • 优化

上面的代码虽然功能实现了,但是在提示上使用了alert(),这种方式需要用户每次都手动关闭,很影响用户的体验,因此下面将自定义一个通知函数,实现自动关闭的轻量化通知功能。

// 显示通知函数
function showNotification(type, message) {const notification = document.createElement('div');notification.classList.add('notification', type);notification.innerText = message;document.body.appendChild(notification);// 在一段时间后移除通知setTimeout(() => {document.body.removeChild(notification);}, 3000); // 3秒后移除通知
}

image-20240501163541941

显然,初步的效果是实现了,自动关闭也没问题,但提示的显示位置一般放在屏幕左右侧和顶部居中位置并且有一定的过度动画(参考Element-Plus框架中通知组件的设计)。所以针对这个问题再优化一下:

/*自定义通知*/
.notification {position: fixed;top: 0;left: 50%;transform: translateX(-50%);background-color: #333;color: rgb(63, 223, 169);padding: 10px 20px;border-radius: 5px;opacity: 0;transition: opacity 0.5s;
}.notification.show {opacity: 1;
}

调整通知函数:

// 显示通知函数
function showNotification(type, message) {const notification = document.createElement('div');notification.classList.add('notification', type);notification.innerText = message;document.body.appendChild(notification);// 触发重绘void notification.offsetWidth;notification.classList.add('show');// 在一段时间后移除通知setTimeout(() => {notification.classList.remove('show');setTimeout(() => {document.body.removeChild(notification);}, 500); // 等待过渡动画结束后再移除通知}, 3000); // 3秒后移除通知
}

image-20240501165310953

嗯哼,差不多了,就实用和美感来说,已经达到 了一个业余前端码农的审美要求了,再继续美化就和Element-Plus一样了,那我为什么不直接用它?


现在还有个小瑕疵,注意看右小角的 复制 按钮,丑不拉吉!虽然这是写文章用的演示,但作为般完美主义的强迫症患者,实在是看不下去,再美化下吧。

此时此刻的美化思路有二:

  • 将复制按钮调整到右上角并简单加点样式;
  • 不用按钮,通过组合键的方式触发复制事件,用户鼠标移动到版权信息区域的时候给出提示,比如

请按下Space + C复制版权信息。

这里先采用第一种方案实现,后面这种留给有缘人当作家庭作业!!

/* 复制样式 */
.copy-button {position:absolute;top: -6px;right:405px;transform: translate(50%, 50%);background-color: rgba(255, 255, 255, 0.7); /* 使用rgba来设置背景颜色和透明度 */color: white;padding: 5px 10px;border-radius: 5px;cursor: pointer;
}

image-20240501171923628


5. 小完结撒花

项目地址:

  • CodePen
  • GitHub
  • GitCode

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/5671.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Access to image at ... from origin ... has been blocked

Access to image at ‘http://127.0.0.1:3000/api/getImg?url/uploads/file/20240421/file-1713715007811-logo.png’ from origin ‘http://ggbol.gnway.cc’ has been blocked by CORS policy: The request client is not a secure context and the resource is in more-pri…

【C++】---模板进阶

【C】---模板进阶 一、模版参数1、类型参数2、非类型参数 二、模板的特化1、函数模板的特化2、类模板特化&#xff08;1&#xff09;全特化&#xff08;2&#xff09;偏特化 三、模板分离编译1、模板支持分离编译吗&#xff1f;2、为什么模板不支持分离编译&#xff1f;3、如何…

google search API 获取

登录谷歌云启动服务 首先登录谷歌云Google Cloud: https://console.cloud.google.com/&#xff0c;登录后创建一个项目。 选择创建的项目&#xff0c;进入API库。搜索Google Search。 选择custom Search API并启用。 此外&#xff0c;有个非常具有类似的API-- Google Search …

3D建模在游戏行业的演变和影响

多年来&#xff0c;游戏行业经历了显着的转变&#xff0c;这主要是由技术进步推动的。 深刻影响现代游戏的关键创新之一是 3D 建模领域。 从像素化精灵时代到我们今天探索的错综复杂的游戏世界&#xff0c;3D 建模已成为游戏开发不可或缺的基石。 本文讨论 3D 建模在游戏行业中…

PyVista 3D数据可视化 Python 库 一行代码实现裁剪 含源码

简介&#xff1a; Pyvista是一个用于科学可视化和分析的Python库,使3D数据可视化变得更加简单和易用&#xff1b; 只增加一行代码就可以实现裁剪&#xff1b; 1.效果&#xff1a; 2.代码如下&#xff1a; 加载模型数据&#xff1a; 代码实现&#xff1a; import pyvista a…

查找算法之二分查找

一、算法介绍 二分查找&#xff0c;也称为折半查找&#xff0c;是一种在有序数组中查找特定元素的高效算法。对于包含 n 个元素的有序数组&#xff0c;二分查找的步骤如下&#xff1a; 确定搜索范围&#xff1a;首先&#xff0c;将要查找的元素与数组中间的元素进行比较。如果…

引领农业新质生产力,鸿道(Intewell®)操作系统助力农业机器人创新发展

4月27日至29日&#xff0c;2024耒耜国际会议在江苏大学召开。科东软件作为特邀嘉宾出席此次盛会&#xff0c;并为江苏大学-科东软件“农业机器人操作系统”联合实验室揭牌。 校企联合实验室揭牌 在开幕式上&#xff0c;江苏大学、科东软件、上交碳中和动力研究院、遨博智能研究…

查看笔记本电池容量/健康状态

1. 打开命令行提示符 快捷键“win R”后输入“cmd” 2. 在命令提示符中输入命令 “powercfg /batteryreport" 并回车 3. 查看文件 最后就可以看到笔记本的电池使用报告了

高效率的做事方法?

高效率的做事方法可以帮助我们更好地管理时间和资源&#xff0c;以下是一些建议&#xff1a; 1.明确目标和计划&#xff1a; 在开始任何任务之前&#xff0c;先明确你的目标是什么。 制定一个详细的计划&#xff0c;包括步骤、时间表和预期结果。 将任务分解成小块&#xff0…

第11章 数据库技术(第一部分)

一、数据库技术术语 &#xff08;一&#xff09;术语 1、数据 数据描述事物的符号描述一个对象所用的标识&#xff0c;可以文字、图形、图像、语言等等 2、信息 现实世界对事物状态变化的反馈。可感知、可存储、可加工、可再生。数据是信息的表现形式和载体&#xff0c;信…

python实现的基于单向循环链表插入排序

相比于定义一个循环双向链表来实现插入排序来说&#xff0c;下面的实现采用一个单向循环链表来实现&#xff0c;并且不需要定义一个单向循环链表类&#xff0c;而是把一个list&#xff08;数组/顺序表&#xff09;当成单向循环链表来用&#xff0c;list的元素是一个包含两个元素…

【Windows,亲测有效】手动激活Sublime Text

前言 Sublime Text 是一款非常好用的文本编辑器&#xff0c;但是免费版时不时会跳弹窗 本方法无毒无害&#xff0c;简单易上手 2023/12/22 更新&#xff1a;实测从 4143 支持到 4169 开始 先确保你用的是官方版本的 Sublime Text&#xff0c;还没下的可以去官方下载&#…

net lambda 、 匿名函数 以及集合(实现IEnumerable的 如数组 、list等)

匿名函数&#xff1a;》》》 Action a1 delegate(int i) { Console.WriteLine(i); }; Lambda:>>> Aciont a1 (int i) > { Console.WriteLine(i); }; 可以简写 &#xff08;编译器会自动根据委托类型 推断&#xff09; Action a1 &#xff08;i&#xff09;> {…

笔记本无线网络共享给有线使用

1.鼠标右击wifi图标选择打开网络和Internet设置 2.选择WLAN项&#xff0c;点击进入更改适配器选项 3.进入到以下界面&#xff0c;右击以太网选择启动&#xff08;不确定的话可以在设备管理器查看网卡&#xff09; 4.右击WLAN选项&#xff0c;点击属性 5.点击共享&#xff0…

esp32s3使用psram后音频播报不了的问题解决记录

idf.py menuconfig开启psram后会报错 提示需要打补丁&#xff1a; 根据提示切换到IDF_PATH目录&#xff0c;然后执行git apply %ADF_PATH%/ida_patches/idf5.0_freertos.patch打补丁。 再次编译提示如下错误&#xff1a; assert failed: spi_flash_disable_interrupts_cach…

【Qt QML】Pane组件

Pane&#xff08;窗格&#xff09;提供与应用程序样式和主题匹配的背景色。窗格不提供自己的布局&#xff0c;但需要您定位其内容&#xff0c;例如通过创建RowLayout或ColumnLayout。 声明为窗格的子项的项自动成为窗格的contentItem的父项。动态创建的项需要显式地添加到conte…

VSCode 配置 CMake

VSCode 配置 C/C 环境的详细过程可参考&#xff1a;VSCode 配置 C/C 环境 1 配置C/C编译环境 方案一 如果是在Windows&#xff0c;需要安装 MingW&#xff0c;可以去官网(https://sourceforge.net/projects/mingw-w64/)下载安装包。 注意安装路径不要出现中文。 打开 windows…

06 - 步骤 add constants

简介 Add Constants 步骤是用于在数据流中添加常量字段的步骤。它允许用户在数据流中插入一个或多个常量字段&#xff0c;并为这些字段指定固定的数值、字符串或其他类型的常量值。 使用 场景 我需要在数据清后&#xff0c;这个JSON 字符串有一个固定的行流数据。 1、拖拽…

数字旅游引领未来智慧之旅:科技应用深度重塑旅游生态,智慧服务全面升级打造极致高品质旅游体验

随着信息技术的飞速发展&#xff0c;数字旅游作为旅游业与科技融合的新兴业态&#xff0c;正以其独特的魅力和优势&#xff0c;引领着旅游业迈向智慧之旅的新时代。数字旅游不仅通过科技应用重塑了旅游生态&#xff0c;更通过智慧服务为游客带来了高品质的旅游体验。本文将深入…

Flask简介

Flask简介 安装概述使用PyCharm创建一个Flask程序 Flask程序的基本结构初始化路由和视图函数启动服务器请求-响应循环 安装 概述 Flask算是小型框架&#xff0c;小到可以称为“微框架”。Flask 非常小&#xff0c;因此你一旦能够熟练使用它&#xff0c;很可能就能读懂它所有的…