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

news2024/9/22 15:32:48

目录

一、实现效果

二、完整代码

三、页面准备

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.coloradmin.cn/o/1932831.html

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

相关文章

项目管理进阶之RACI矩阵

前言 项目管理进阶系列续新篇。 RACI&#xff1f;这个是什么矩阵&#xff0c;有什么用途&#xff1f; 在项目管理过程中&#xff0c;如Team规模超5以上时&#xff0c;则有必要采用科学的管理方式&#xff0c;满足工作需要。否则可能事倍功半。 Q&#xff1a;什么是RACI矩阵 …

SQL面试题练习 —— 查询每个用户最大连续登录天数

目录 1 题目2 建表语句3 题解 1 题目 查询每个用户最大连续登录天数 样例数据如下 login_log&#xff1a; 2 建表语句 --建表语句 create table if not exists login_log (user_id int comment 用户id,login_time date comment 登录时间 ); --数据插入 INSERT overwrit…

N Puzzle (数字推盘游戏)

N Puzzle [数字推盘游戏] 1. 15 Puzzle2. N PuzzleReferences puzzle /ˈpʌzl/&#xff1a;n. 谜&#xff0c;智力游戏&#xff0c;疑问&#xff0c;不解之谜&#xff0c;令人费解的事 vt. 迷惑&#xff0c;使困惑1. 15 Puzzle https://en.wikipedia.org/wiki/15_puzzle The…

Python 在Word表格中插入、删除行或列

Word文档中的表格可以用于组织和展示数据。在实际应用过程中&#xff0c;有时为了调整表格的结构或适应不同的数据展示需求&#xff0c;我们可能会需要插入、删除行或列。以下提供了几种使用Python在Word表格中插入或删除行、列的方法供参考&#xff1a; 文章目录 Python 在Wo…

Qt QProcess 进程间通信读写数据通信

本文介绍了如何使用Qt的QProcess 进行程序开发&#xff0c;包括启动进程间通信、设置环境变量、通用方法&#xff1b;方便在日常开发中使用&#xff1b; 1.使用Qt进行程序开发&#xff0c;可以通过QProcess类用于启动外部程序并与其进行通信.&#xff1b; 进程A&#xff08;…

【时时三省】tessy 集成测试:小白入门指导手册

目录 1,创建集成测试模块且分析源文件 2,设置测试环境 3,TIE界面设置相关函数 4,SCE界面增加用例 5,编辑数据 6,用例所对应的测试函数序列 7,添加 work task 函数 8,为测试场景添加函数 9,为函数赋值 10,编辑时间序列的数值 11,执行用例 12,其他注意事项…

Hadoop3:MR程序的数据倾斜问题处理

一、数据倾斜 什么是数据倾斜&#xff1f; 学过Redis集群的都知道数据倾斜这个问题。 就是大量数据&#xff0c;分配不均匀的现象。 二、MR数据倾斜 1、怎么判断出现数据倾斜&#xff1f; 数据频率倾斜——某一个区域的数据量要远远大于其他区域。 数据大小倾斜——部分记…

【STM32】RTT-Studio中HAL库开发教程四:DAC+DMA输出波形

文章目录 一、DAC介绍二、HAL库配置初始化三、RTT中初始化四、测试验证 一、DAC介绍 1.DAC作用 DAC&#xff08;Digital-to-Analog Converter&#xff09;&#xff0c;即为数字/模拟转换模块&#xff0c;又称D/A转换器&#xff1b;作用就是把输入的数字编码&#xff0c;转换成…

昇思25天学习打卡营第16天 | Vision Transformer图像分类

昇思25天学习打卡营第16天 | Vision Transformer图像分类 文章目录 昇思25天学习打卡营第16天 | Vision Transformer图像分类Vision Transform&#xff08;ViT&#xff09;模型TransformerAttention模块Encoder模块 ViT模型输入 模型构建Multi-Head Attention模块Encoder模块Pa…

Java对象转换为JSON字符串

0 写在前面 业务中有很多场景需要 把一个带有数据的 Java对象/Java集合转换为JSON 存入数据库中。 在需要的时候还需要吧和这个JSON字符串拿出来再次转换成Java对象/集合 1 Java对象与JSON字符串互转 引入依赖: <dependency><groupId>com.alibaba</groupId&…

解决VMware虚拟机在桥接模式下无法上网的问题

解决VMware虚拟机在桥接模式下无法上网的问题 windows11系统自动启动了热点功能&#xff0c;开启热点可能会干扰虚拟机的桥接设置。 方法一&#xff1a;windows11可以提供网络热点服务 方法二&#xff1a;手动指定桥接的物理网卡 方法一&#xff1a;关闭热点功能 优点&#xff…

【Java项目笔记】01项目介绍

一、技术框架 1.后端服务 Spring Boot为主体框架 Spring MVC为Web框架 MyBatis、MyBatis Plus为持久层框架&#xff0c;负责数据库的读写 阿里云短信服务 2.存储服务 MySql redis缓存数据 MinIO为对象存储&#xff0c;存储非结构化数据&#xff08;图片、视频、音频&a…

【开发指南】HTML和JS编写多用户VR应用程序的框架

1.概述 Networked-Aframe 的工作原理是将实体及其组件同步到连接的用户。要连接到房间&#xff0c;您需要将networked-scene组件添加到a-scene元素。对于要同步的实体&#xff0c;请向其添加networked组件。默认情况下&#xff0c;position和rotation组件是同步的&#xff0c;…

【Spring Cloud】掌握Gateway核心技术,实现高效路由与转发

目录 前言示例创建一个服务提供者创建网关 创建common子项目 前言 Spring Cloud Gateway 是一个基于 Spring Boot 的非阻塞 API 网关服务&#xff0c;它提供了动态路由、请求断言、过滤器等功能。 以下是关于 Spring Cloud Gateway 的示例&#xff1a; 示例 创建一个服务提…

什么是 std::ios::sync_with_stdio(false)

介绍 std::ios::sync_with_stdio(false) 是 C 中的一个配置设置&#xff0c;用于控制标准 I/O 流&#xff08;如 std::cin, std::cout&#xff09;的行为。这个设置主要用于优化输入输出操作的性能&#xff0c;尤其是在处理大量数据时。 在 C 中&#xff0c;标准流库&#xf…

PHP连接MySQL数据库

PHP本身不具备操作MySQL数据库的能力&#xff0c;需要借助MySQL扩展来实现。 1、PHP加载MySQL扩展&#xff1a;php.ini文件中。&#xff08;不要用记事本打开&#xff09; 2、PHP中所有扩展都是在ext的文件夹中&#xff0c;需要指定扩展所在路径&#xff1a;extension_dir。 3、…

3D问界—MAYA制作铁丝栅栏(透明贴图法)

当然&#xff0c;如果想通过建立模型法来实现铁丝栅栏的效果&#xff0c;也不是不行&#xff0c;可以找一下栅栏建模教程。本篇文章主要是记录一下如何使用透明贴图来实现创建铁丝栅栏&#xff0c;主要应用于场景建模&#xff0c;比如游戏场景、建筑场景等大环境&#xff0c;不…

Spring3(代理模式 Spring1案例补充 Aop 面试题)

目录 一、代理模式 介绍 意图 主要解决的问题 使用场景 实现方式 关键代码 应用实例 优点 缺点 使用建议 注意事项 结构 什么是代理模式&#xff1f; 为什么要用代理模式&#xff1f; 有哪几种代理模式&#xff1f; 1. 静态代理 实现 2. 基于接口的动态代理…

基于python旅游景点满意度分析设计与实现

1.1研究背景与意义 1.1.1研究背景 随着旅游业的快速发展&#xff0c;满意度分析成为评估旅游景点质量和提升游客体验的重要手段。海口市作为中国的旅游城市之一&#xff0c;其旅游景点吸引了大量游客。然而&#xff0c;如何科学评估和提升海口市旅游景点的满意度&#xff0c;…

Qt创建列表,通过外部按钮控制列表的选中下移、上移以及左侧图标的显现

引言 项目中需要使用列表QListWidget,但是不能直接拿来使用。需要创建一个列表,通过向上和向下的按钮来向上或者向下移动选中列表项,当当前项背选中再去点击确认按钮,会在列表项的前面出现一个图标。 实现效果 本实例实现的效果如下: 实现思路 思路一 直接采用QLis…