Web开发:四角线框效果(HTML、CSS、JavaScript)

目录

一、实现效果

二、完整代码

三、页面准备

1、页面结构

2、初始样式

3、现有效果

三、线框实现

1、需求分析

2、线框结构

3、线框大小

4、线框位置

5、线框样式

6、移动线框

7、添加过渡效果

8、使用CSS变量


一、实现效果

如下图所示,当鼠标移动到某个图片时,就给这个图片添加四角线框;

四角线框效果

二、完整代码

test.html

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>四角线框效果</title><style>:root {/* 定义变量 *//* 图片的宽度 */--img-width: 240px;/* 图片的高度 */--img-height: 160px;/* 图片的间距 */--img-gap: 40px;/* 线框的样式 */--line-box-border: 2px solid #666;}* {/* 清除默认边距 */margin: 0;padding: 0;}body {/* 设为flex布局 */display: flex;/* 设置子元素水平居中 */justify-content: center;/* 设置子元素垂直居中 */align-items: center;width: 100vw;height: 100vh;background-color: #eeffff;caret-color: transparent;}.grid-container {/* 设为相对定位 */position: relative;/* 设为Grid布局 */display: grid;/* 划分3列,列宽为240px */grid-template-columns: repeat(3, var(--img-width));/* 划分3行,行高为160px */grid-template-rows: repeat(3, var(--img-height));/* 元素间距为40px */gap: var(--img-gap);}.one-img {/* 图片大小为其父元素大小 240px * 160px */width: 100%;height: 100%;box-shadow: 0 0 6px 1px #666;border-radius: 6px;}.line-box {/* 设置线框为绝对定位 */position: absolute;/* 距离父元素的上、左距离为0; */top: 0;left: 0;/* 线框盒子的宽度为图片宽度(240px) +  图片的间距(40px) */width: calc(var(--img-width) + var(--img-gap));/* 线框盒子的高度为图片高度(160px) +  图片的间距(40px) */height: calc(var(--img-height) + var(--img-gap));/* 设置线框的margin值 */margin-top: calc(-1 * var(--img-gap) / 2);margin-left: calc(-1 * var(--img-gap) / 2);/* 添加过渡效果 */transition: top 0.4s, left 0.4s;}.line-item {/* 四角边框采用绝对定位 */position: absolute;/* 盒子的宽高均为20px */width: calc(var(--img-gap) / 2);height: calc(var(--img-gap) / 2);}/* 左上角的线框 */.line-item:nth-child(1) {top: 0;left: 0;border-top: var(--line-box-border);border-left: var(--line-box-border);}/* 右上角的线框 */.line-item:nth-child(2) {top: 0;right: 0;border-top: var(--line-box-border);border-right: var(--line-box-border);}/* 左下角的线框 */.line-item:nth-child(3) {bottom: 0;left: 0;border-bottom: var(--line-box-border);border-left: var(--line-box-border);}/* 右下角的线框 */.line-item:nth-child(4) {right: 0;bottom: 0;border-bottom: var(--line-box-border);border-right: var(--line-box-border);}</style>
</head><body><div class="grid-container"><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_1.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_2.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_3.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_4.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_5.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_6.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_7.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_8.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_9.jpg" alt=""></div><div class="line-box"><div class="line-item"></div><div class="line-item"></div><div class="line-item"></div><div class="line-item"></div></div></div>
</body>
<script>// 获取图片元素列表var itemList = document.querySelectorAll(".grid-item");// 获取线框盒子var lineBox = document.querySelector(".line-box");itemList.forEach(item => {// 给每个图片注册鼠标进入事件item.addEventListener("mouseenter", function () {// 获取图片的左、上边距(距离父元素),并赋值给线框作为left、top值lineBox.style.top = item.offsetTop + 'px';lineBox.style.left = item.offsetLeft + 'px';})});
</script></html>

三、页面准备

1、页面结构

(1)结构分析

根据上述效果图,可知:

  • 页面中有一个大容器,在其父容器中水平垂直居中
  • 容器中排列了三行三列,总共9个元素;
  • 每个元素中放一张图片;

(2)结构代码

  • 页面中添加一个Grid布局容器【.grid-container】和9个Grid元素【.grid-item】;
  • 每个Grid元素中添加一个img元素【.one-img】,用来展示图片;
<body><div class="grid-container"><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_1.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_2.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_3.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_4.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_5.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_6.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_7.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_8.jpg" alt=""></div><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_9.jpg" alt=""></div></div>
</body>

2、初始样式

(1)样式分析

根据上述效果图,可知:

  • Grid容器【.grid-container】中的9个Grid元素【.grid-item】,呈现【3行3列】的排列方式;
  • 设置body为Flex布局,使Grid容器在页面中水平垂直居中显示;
  • img元素的大小为父容器Grid元素【.grid-item】的大小;

(2)样式代码

<style>* {/* 清除默认边距 */margin: 0;padding: 0;}body {/* 设为flex布局 */display: flex;/* 设置子元素水平居中 */justify-content: center;/* 设置子元素垂直居中 */align-items: center;width: 100vw;height: 100vh;background-color: #eeffff;caret-color: transparent;}.grid-container {/* 设为Grid布局 */display: grid;/* 划分3列,列宽为240px */grid-template-columns: repeat(3, 240px);/* 划分3行,行高为160px */grid-template-rows: repeat(3, 160px);/* 元素间距为40px */gap: 40px;}.one-img {/* 图片大小为其父元素大小 240px * 160px */width: 100%;height: 100%;box-shadow: 0 0 6px 1px #666;border-radius: 6px;}
</style>

3、基本效果

三、线框实现

1、需求分析

对于上述图中的线框效果,实现步骤如下:

(1)准备线框盒子

需要准备一个盒子【.line-box】,这个盒子要比图片大,包裹住图片,如下图所示:

(2)添加四角小盒子

但是效果图中的边框只在四角出现,这个盒子显然不能实现这样的效果;

这里采用的办法是,给这个线框盒子的四角分别添加一个小盒子【.line-item】,如下图所示:

(3)边框调整

到这里,基本上已经很明显了,只需要去除线框盒子【.line-box】的边框效果,再给四角小盒子【.line-item】分别添加上对应位置的边框,就可以实现了;

注意:线框效果的实现方式有很多,这里仅介绍这种简单粗暴的实现方式;

( 如果有其他更好的实现方式,还希望请各位大佬不吝赐教~!)

2、线框结构

根据上述分析可知:

  • 线框盒子的位置是相对与Grid容器【.grid-container】的;
  • 在Grid容器中添加一个div盒子【.line-box】,与9个图片盒子同级;
  • 在【.line-box】盒子中添加四角小盒子【.line-item】* 4;

注意:这里将线框添加到Grid容器【.grid-container】中,是为了给后续线框的定位做准备;

<body><div class="grid-container"><div class="grid-item"><img class="one-img" src="D:\\test\\zyl-img\\bg_1.jpg" alt=""></div>......<div class="line-box"><div class="line-item"></div><div class="line-item"></div><div class="line-item"></div><div class="line-item"></div></div></div>
</body>

3、线框大小

如何确定线框的大小?

分析效果图可知:它的位置如下图红色框所示:

  • 线框的宽度 = 图片的宽度(240px) +  两图的间距(40px);(左右间距各一半)
  • 线框的高度 = 图片的高度(160px) +  两图的间距(40px);(上下间距各一半)

4、线框位置

如何确定线框位置?

分析效果图可知:

  • 首先,线框需要采用绝对定位,相对其父元素【.grid-container】(脱离标准流,覆盖在图片上);
  • 其次,当线框出现在第一个图片之上时,很明显不能和和它的父元素【.grid-container】的上边界和左边界贴合;

如下图所示,这并不是想要的结果:

这里采用的方式是给线框【.line-box】一个负的margin值(当然也可以采用其他方式);

这样一来,线框中心就会与图片中心重合,在视觉上达到需要的效果,如下图所示:

5、线框样式

根据上述分析可知:

  • 线框【.line-box】采用绝对定位:position: absolute;
  • 父元素【.grid-container】采用相对定位:position: relative;
  • 线框距离父元素的左、上距离均为0(线框的初始位置);
  • 线框设置负的margin值:margin-top: -20px; margin-left: -20px;
  • 四角盒子采用绝对定位,相对于父元素线框【.line-box】:position: absolute;
  • 四角盒子大小为图片间距(40px)的一半:width: 20px;  height: 20px;
  • 分别给每个顶角盒子单独设置位置和样式;

相关元素的样式代码如下:

<style>.......grid-container {/* 设为相对定位 */position: relative;......}.line-box {/* 设置线框为绝对定位 */position: absolute;/* 距离父元素的上、左距离为0; */top: 0;left: 0;/* 线框盒子的宽度为图片宽度(240px) +  图片的间距(40px) */width: 280px;/* 线框盒子的高度为图片高度(160px) +  图片的间距(40px) */height: 200px;/* 设置线框的margin值 */margin-top: -20px;margin-left: -20px;}.line-item {/* 四角边框采用绝对定位 */position: absolute;/* 盒子的宽高均为20px */width: 20px;height: 20px;}/* 左上角的线框 */.line-item:nth-child(1) {top: 0;left: 0;border-top: 2px solid red;border-left: 2px solid red;}/* 右上角的线框 */.line-item:nth-child(2) {top: 0;right: 0;border-top: 2px solid red;border-right: 2px solid red;}/* 左下角的线框 */.line-item:nth-child(3) {bottom: 0;left: 0;border-bottom: 2px solid red;border-left: 2px solid red;}/* 右下角的线框 */.line-item:nth-child(4) {right: 0;bottom: 0;border-bottom: 2px solid red;border-right: 2px solid red;}
</style>

效果如下图所示:

6、移动线框

分析需求可知:

  • 当鼠标移入某个图片时,将线框移动到该图片周围;
  • 分别给每个图片盒子注册鼠标进入事件;
  • 当鼠标进入该图片时,计算其到父盒子【.grid-container】的上边距和左边距,并赋值给线框作为top和left值;
<script>// 获取图片元素列表var itemList = document.querySelectorAll(".grid-item");// 获取线框盒子var lineBox = document.querySelector(".line-box");itemList.forEach(item => {// 给每个图片注册鼠标进入事件item.addEventListener("mouseenter", function () {// 获取图片的左、上边距(距离父元素),并赋值给线框作为left、top值lineBox.style.top = item.offsetTop + 'px';lineBox.style.left = item.offsetLeft + 'px';})});
</script>

7、添加过渡效果

可以给线框添加过渡效果,让它的移动看起来平滑一点;

.line-box {....../* 添加过渡效果 */transition: top 0.4s, left 0.4s;
}

8、使用CSS变量

上述代码中,很多地方都使用了同样的属性值;例如,

  • 顶角盒子边框样式;
  • 根据图片大小和间距计算的线框大小和位置等;

这些内容均可以通过CSS中的变量来实现;具体可以这样修改:

<style>:root{/* 定义变量 *//* 图片的宽度 */--img-width:240px;/* 图片的高度 */--img-height:160px;/* 图片的间距 */--img-gap:40px;/* 线框的样式 */--line-box-border: 2px solid red;}.......grid-container {....../* 划分3列,列宽为240px */grid-template-columns: repeat(3, var(--img-width));/* 划分3行,行高为160px */grid-template-rows: repeat(3, var(--img-height));/* 元素间距为40px */gap: var(--img-gap);}.line-box {....../* 线框盒子的宽度为图片宽度(240px) +  图片的间距(40px) */width: calc(var(--img-width) + var(--img-gap));/* 线框盒子的高度为图片高度(160px) +  图片的间距(40px) */height: calc(var(--img-height) + var(--img-gap));/* 设置线框的margin值 */margin-top: calc(-1 * var(--img-gap) / 2);margin-left: calc(-1 * var(--img-gap) / 2);......}.line-item {....../* 盒子的宽高均为20px */width: calc(var(--img-gap) / 2);height: calc(var(--img-gap) / 2);}/* 左上角的线框 */.line-item:nth-child(1) {......border-top: var(--line-box-border);border-left:var(--line-box-border);}/* 右上角的线框 */.line-item:nth-child(2) {......border-top: var(--line-box-border);border-right: var(--line-box-border);}/* 左下角的线框 */.line-item:nth-child(3) {......border-bottom: var(--line-box-border);border-left: var(--line-box-border);}/* 右下角的线框 */.line-item:nth-child(4) {......border-bottom: var(--line-box-border);border-right: var(--line-box-border);}
</style>

这样一来,如果需要更改图片大小、间距,线框大小、位置、样式等,直接在变量声明的地方统一更改即可,不需要再多做修改;

=========================================================================

每天进步一点点~!

记录一下这个有意思的CSS效果~~!

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

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

相关文章

html 单页面引用vue3和element-plus

引入方式&#xff1a; element-plus基于vue3.0&#xff0c;所以必须导入vue3.0的js文件&#xff0c;然后再导入element-plus自身所需的js以及css文件&#xff0c;导入文件有两种方法&#xff1a;外部引用、下载本地使用 通过外部引用ElementPlus的css和js文件 以及Vue3.0文件 …

光热熔盐储能

长时储能的新赛道上&#xff0c;多种技术正在加速竞逐&#xff0c;谁最有可能成为其中的王者&#xff1f; 液流电池、压缩空气储能、重力储能&#xff1f;储能行业的玩家们通常不会想到的答案是光热熔盐储能。 1 基础的原理 光热发电系统包括太阳能集热、传储热、发电三大模…

MK米客方德推出新一代工业级SD NAND

--更长寿命、更高速度、更优功耗 目录 --更长寿命、更高速度、更优功耗 1.LGA-8封装&#xff1a; 2.工业级SLC存储颗粒&#xff1a; 3.高IOPS性能&#xff1a; 4.健康状态侦测(Smart Function)&#xff1a; 5.内嵌ECC校验、坏块管理、垃圾回收、磨损平均算法等功能。 6…

大厂面试官问我:Redis为什么使用哈希槽的方式进行数据分片?为什么不适用一致性哈希的方式?【后端八股文十三:Redis 集群哈希八股文合集(1)】

本文为【Redis 集群哈希 八股文合集&#xff08;1&#xff09;】初版&#xff0c;后续还会进行优化更新&#xff0c;欢迎大家关注交流~ hello hello~ &#xff0c;这里是绝命Coding——老白~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注…

百日筑基第二十三天-23种设计模式-创建型总汇

百日筑基第二十三天-23种设计模式-创建型总汇 前言 设计模式可以说是对于七大设计原则的实现。 总体来说设计模式分为三大类&#xff1a; 创建型模式&#xff0c;共五种&#xff1a;单例模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式。结构型模式&#xff0c;共…

防洪墙的安全内容检测+http请求头

1、华为的IAE引擎&#xff1a;内部工作过程 IAE引擎主要是针对2-7层进行一个数据内容的检测 --1、深度检测技术 (DPI和DPF是所有内容检测都必须要用到的技术) ---1、DPI--深度包检测&#xff0c;针对完整的数据包&#xff0c;进行内容的识别和检测 1、基于特征子的检…

数据分析01——系统认识数据分析

1.数据分析的全貌 1.1观测 1.1.1 观察 &#xff08;1&#xff09;采集数据 a.采集数据&#xff1a;解析系统日志 当你在看视频的时候———就会产生日志———解析日志———得到数据 b.采集数据&#xff1a;埋点获取新数据&#xff08;自定义记录新的信息&#xff09; 日志…

【Vue】Vue3 安装 Tailwind CSS 入门

初始化 Vue 3 项目 npm install -g vue/cli vue create my-project安装 Tailwind CSS 进入你的项目目录&#xff0c;然后安装 Tailwind CSS 和其依赖项&#xff1a; npm install -D tailwindcss postcss autoprefixer配置 PostCSS Tailwind CSS 需要通过 PostCSS 进行处理。…

Python酷库之旅-第三方库Pandas(029)

目录 一、用法精讲 74、pandas.api.interchange.from_dataframe函数 74-1、语法 74-2、参数 74-3、功能 74-4、返回值 74-5、说明 74-6、用法 74-6-1、数据准备 74-6-2、代码示例 74-6-3、结果输出 75、pandas.Series类 75-1、语法 75-2、参数 75-3、功能 75-4…

牛客 7.13 月赛(留 C逆元 Ddp)

B-最少剩几个&#xff1f;_牛客小白月赛98 (nowcoder.com) 思路 奇数偶数 奇数&#xff1b;奇数*偶数 奇数 所以在既有奇数又有偶数时&#xff0c;两者结合可以同时删除 先分别统计奇数&#xff0c;偶数个数 若偶个数大于奇个数&#xff0c;答案是偶个数-奇个数 若奇个数…

六边形动态特效404单页HTML源码

源码介绍 动态悬浮的六边形,旁边404文字以及跳转按钮,整体看着像科技二次元画风,页面简约美观,可以做网站错误页或者丢失页面,将下面的代码放到空白的HTML里面,然后上传到服务器里面,设置好重定向即可 效果预览 完整源码 <!DOCTYPE html> <html><head…

PyCharm查看文件或代码变更记录

背景&#xff1a; Mac笔记本上有一个截图的定时任务在运行&#xff0c;本地Python使用的是PyCharm IDE&#xff0c;负责的同事休假&#xff0c;然后定时任务运行的结果不符合预期&#xff0c;一下子不知道问题出现在哪里。 定位思路&#xff1a; 1、先确认网络、账号等基本的…

Qt 快速保存配置的方法

Qt 快速保存配置的方法 一、概述二、代码1. QFileHelper.cpp2. QSettingHelper.cpp 三、使用 一、概述 这里分享一下&#xff0c;Qt界面开发时&#xff0c;快速保存界面上一些参数配置的方法。 因为我在做实验的时候&#xff0c;界面上可能涉及到很多参数的配置&#xff0c;我…

实战打靶集锦-31-monitoring

文章目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 ssh服务4.2 smtp服务4.3 http/https服务 5. 系统提权5.1 枚举系统信息5.2 枚举passwd文件5.3 枚举定时任务5.4 linpeas提权 6. 获取flag 靶机地址&#xff1a;https://download.vulnhub.com/monitoring/Monitoring.o…

django学习入门系列之第四点《BootStrap依赖》

文章目录 往期回顾 BootStrap依赖于JavaScript的类库&#xff0c;JQuery下载 下载JQuery&#xff0c;在界面上应用JQuery 在页面上应用BootStrap和avaScript的类库【JQuery是avaScript的类库】 JQuery的官网&#xff1a; jQuery 如果要应用JQuery 则要在body里面导入文件…

MySQL(7)内外连接+索引

目录 1.内外连接; 2. 索引; 1.内外连接: 1.1内连接: 语法: select 字段 from 表名 inner join 表名 on 字段限制; 1.2 外连接: 分为左右外连接; (1)左外连接: 语法: select * from 表名 left join 表名 on 字段限制. &#x1f330;查询所有学生的成绩&#xff0c;如果这个学生…

什么才是好用的大模型?

随着大模型在千行百业的逐步落地&#xff0c;中国基础大模型正直面来自用户端的诸多拷问。 近日&#xff0c;随着OpenAI宣布禁止中国用户使用其API&#xff0c;更多的国产大模型都在提供替代方案和优惠措施&#xff0c;来吸引和支持开发者进行用户迁移。 这既是一次挑战&…

多多OJ评测系统 前端项目环境初始化 安装Vue脚手架 引入Arco Design组件

目录 确定环境 命令行输入 装一下脚手架 监测一下是否安装成功 创建一个项目 选择一系列的配置后 我们打开webStorm 配置脚手架后我们先运行 我们这边能获取到网址 其实我们脚手架已经帮我们做到了 接下来要引入相关的组件 选择用npm进行安装 我们建议的是完整引入…

UDP客户端、服务端及简易聊天室实现 —— Java

UDP 协议&#xff08;用户数据包协议&#xff09; UDP 是无连接通信协议&#xff0c;即在数据传输时&#xff0c;数据的发送端和接收端不建立逻辑连接&#xff0c;简单来说&#xff0c;当客户端向接收端发送数据时&#xff0c;客户端不会确认接收端是否存在&#xff0c;就会发出…

windows镜像下载网站

一个专注于提供精校、完整、极致的Windows系统下载服务的仓储站&#xff0c;网站托管于Github。 网站&#xff1a;https://hellowindows.cn/ 下载方式&#xff1a;ED2k&#xff0c;BT&#xff0c;百度网盘 MSDN - 山己几子木&#xff0c;提供Windows 11、Windows 10等不同版本…