border-image(H5C3)

本文详细介绍了CSS3中的border-image属性,包括其用法、切割尺寸、边框宽度和平铺方式等特性。通过具体代码示例展示了如何使用border-image-source、border-image-slice、border-image-width和border-image-repeat等子属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

border-image

border-image是css3中的一个属性,因为兼容性问题,比较少见,但鉴于此功能在某些特定的场景中还是有些作用的;这里就简单介绍下属性和功能
我们用下面的代码来展示下 它的属性和特点

效果图

在这里插入图片描述

代码块


    <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box{
            width: 400px;
            height: 150px;
            border: 20px solid #ccc;
            margin-bottom: 30px;
        }

        .box:first-child{
            /*border-image: url("images/border01.jpg") 167/20px round;*/
            /*1.在内容变化的容器可以使用,边框自动填充*/
            /*2.用法:*/
            /*2.1 图片资源*/
            border-image-source: url("images/border01.jpg");
            /*2.2 切割的尺寸 默认的单位px 而且不能使用小数*/
            /*2.2.1 切割的位置距离对应的边的距离  切了四刀   4个切割的尺寸*/
            border-image-slice: 167;/*167 167 167 167*/
            /*2.3 边框的宽度*/
            border-image-width: 20px;
            /*2.4 平铺的方式  三种平铺方式 round stretch repeat*/
            /*round 环绕 完整的自适应(等比缩放)平铺在边框内*/
            /*stretch 拉伸 拉伸显示在边框内容 变形的*/
            /*repeat 平铺 从边框的中间向两侧平铺 自适应平铺但是不是完整的*/
            border-image-repeat: round;

        }
        .box:nth-child(2){
            border-image: url("images/border01.jpg") 167/20px stretch;
        }
        .box:last-child{
            border-image: url("images/border01.jpg") 167/20px repeat;
        }


    </style>
</head>
<body>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
</body>
</html>

<template> <view class="container"> <!-- 顶部用户信息区域 --> <view class="user-info-section"> <view class="avatar-container"> <image src="/static/workbanch/banner/workbench/4.jpg" class="avatar-image" mode="aspectFill" /> <view class="avatar-frame"></view> </view> <!-- 用户信息 --> <view class="user-details"> <text class="welcome-text">您好,</text> <text class="username">{{ userName || &#39;加载中...&#39; }}</text> <view class="user-meta"> <text class="user-role">{{ userRole }}</text> <text class="user-dept">{{ userDept }}</text> <text class="user-phone" v-if="userPhone">电话:{{ userPhone }}</text> </view> </view> </view> <!-- 功能板块区域 --> <view class="function-section"> <!-- 重置密码按钮 --> <view class="function-item" @click="handleResetPassword" @touchstart="handleTouchStart(&#39;reset&#39;)" @touchend="handleTouchEnd(&#39;reset&#39;)" > <view class="item-left"> <image src="/static/workbanch/icons/reset-password.png" class="item-icon" /> <text class="item-text">重置密码</text> </view> <view class="arrow-icon">›</view> </view> <!-- 分隔线 --> <view class="divider"></view> <!-- 退出登录按钮 --> <view class="function-item logout-item" @click="handleLogout" @touchstart="handleTouchStart(&#39;logout&#39;)" @touchend="handleTouchEnd(&#39;logout&#39;)" > <view class="item-left"> <image src="/static/workbanch/icons/logout.png" class="item-icon" /> <text class="item-text">退出登录</text> </view> <view class="arrow-icon">›</view> </view> </view> <!-- 这里添加了function-section的结束标签 --> <!-- 重置密码弹窗 (优化后的布局) --> <view v-if="showResetModal" class="modal-overlay" @click.self="closeResetModal"> <view class="modal-content"> <view class="modal-header"> <text class="modal-title">重置密码</text> <text class="modal-close" @click="closeResetModal">×</text> </view> <view class="input-group"> <view class="input-item"> <image src="/static/workbanch/icons/lock.png" class="input-icon" /> <input v-model="oldPassword" :type="showOldPassword ? &#39;text&#39; : &#39;password&#39;" placeholder="请输入旧密码" class="password-input" placeholder-style="color: #aaa;" /> <view class="eye-icon-wrapper" @click="togglePasswordVisibility(&#39;old&#39;)"> <image :src="showOldPassword ? &#39;/static/workbanch/icons/eye-open.png&#39; : &#39;/static/workbanch/icons/eye-close.png&#39;" class="eye-icon" /> </view> </view> <view class="input-item"> <image src="/static/workbanch/icons/lock.png" class="input-icon" /> <input v-model="newPassword" :type="showNewPassword ? &#39;text&#39; : &#39;password&#39;" placeholder="请输入新密码(6-20位)" class="password-input" placeholder-style="color: #aaa;" /> <view class="eye-icon-wrapper" @click="togglePasswordVisibility(&#39;new&#39;)"> <image :src="showNewPassword ? &#39;/static/workbanch/icons/eye-open.png&#39; : &#39;/static/workbanch/icons/eye-close.png&#39;" class="eye-icon" /> </view> </view> <view class="input-item"> <image src="/static/workbanch/icons/lock.png" class="input-icon" /> <input v-model="confirmPassword" :type="showConfirmPassword ? &#39;text&#39; : &#39;password&#39;" placeholder="请确认新密码" class="password-input" placeholder-style="color: #aaa;" /> <view class="eye-icon-wrapper" @click="togglePasswordVisibility(&#39;confirm&#39;)"> <image :src="showConfirmPassword ? &#39;/static/workbanch/icons/eye-open.png&#39; : &#39;/static/workbanch/icons/eye-close.png&#39;" class="eye-icon" /> </view> </view> </view> <view class="modal-buttons"> <button class="cancel-btn" @click="closeResetModal">取消</button> <button class="confirm-btn" @click="submitResetPassword">确定</button> </view> </view> </view> </view> </template> <script setup> import { ref } from &#39;vue&#39;; import { onShow, onTabItemTap } from &#39;@dcloudio/uni-app&#39;; // 用户信息相关 const userName = ref(&#39;&#39;); const userRole = ref(&#39;&#39;); const userDept = ref(&#39;&#39;); const userPhone = ref(&#39;&#39;); // 重置密码 const showResetModal = ref(false); const oldPassword = ref(&#39;&#39;); const newPassword = ref(&#39;&#39;); const confirmPassword = ref(&#39;&#39;); // 密码可见性状态 const showOldPassword = ref(false); const showNewPassword = ref(false); const showConfirmPassword = ref(false); // 触摸状态 const touchState = ref({ reset: false, logout: false }); // 页面显示时加载数据 onShow(() => { // console.log(&#39;onShow 被触发&#39;); loadUserInfo(); // 加载用户信息 }); // tabbar 页面被点击时触发 onTabItemTap(() => { // console.log(&#39;tabbar 页面被点击&#39;); loadUserInfo(); // 强制刷新数据 }); const forceRefresh = true; // 加载用户信息 const loadUserInfo = async () => { try { const userInfo = uni.getStorageSync(&#39;userInfo&#39;); // console.log(&#39;本地缓存 userInfo:&#39;, userInfo); if (!forceRefresh && userInfo && userInfo.userName) { // 使用缓存 userName.value = userInfo.nickName || userInfo.userName || &#39;未知用户&#39;; userRole.value = userInfo.roles?.[0]?.roleName || &#39;普通用户&#39;; userDept.value = userInfo.dept?.deptName || &#39;未分配部门&#39;; userPhone.value = userInfo.phonenumber || &#39;暂无电话&#39;; } else { // console.log(&#39;开始请求用户信息...&#39;); const res = await uni.request({ url: &#39;http://172.26.26.43/dev-api/system/user/profile&#39;, method: &#39;GET&#39;, header: { &#39;Authorization&#39;: &#39;Bearer &#39; + uni.getStorageSync(&#39;token&#39;) } }); // console.log(&#39;接口返回结果:&#39;, res); if (res.statusCode === 200 && res.data.code === 200) { const userData = res.data.data; uni.setStorageSync(&#39;userInfo&#39;, userData); userName.value = userData.nickName || userData.userName || &#39;未知用户&#39;; userRole.value = userData.roles?.[0]?.roleName || &#39;普通用户&#39;; userDept.value = userData.dept?.deptName || &#39;未分配部门&#39;; userPhone.value = userData.phonenumber || &#39;暂无电话&#39;; } else { uni.showToast({ title: &#39;获取用户信息失败&#39;, icon: &#39;none&#39; }); uni.redirectTo({ url: &#39;/pages/login/login&#39; }); } } } catch (error) { console.error(&#39;加载用户信息失败:&#39;, error); uni.showToast({ title: &#39;加载用户信息失败&#39;, icon: &#39;none&#39; }); uni.redirectTo({ url: &#39;/pages/login/login&#39; }); } }; // 处理触摸开始 const handleTouchStart = (type) => { touchState.value[type] = true; }; // 处理触摸结束 const handleTouchEnd = (type) => { touchState.value[type] = false; }; // 切换密码可见性 const togglePasswordVisibility = (type) => { switch (type) { case &#39;old&#39;: showOldPassword.value = !showOldPassword.value; break; case &#39;new&#39;: showNewPassword.value = !showNewPassword.value; break; case &#39;confirm&#39;: showConfirmPassword.value = !showConfirmPassword.value; break; } // 确保图标状态更新后UI重新渲染 setTimeout(() => { const input = document.querySelector(`.input-item:nth-child(${ type === &#39;old&#39; ? 1 : type === &#39;new&#39; ? 2 : 3 }) .password-input`); if (input) input.focus(); }, 50); }; // 显示弹窗 const handleResetPassword = () => { uni.vibrateShort(); // 震动反馈 showResetModal.value = true; }; // 关闭弹窗 const closeResetModal = () => { showResetModal.value = false; }; // 提交重置密码 const submitResetPassword = async () => { const { oldPassword: oldPass, newPassword: newPass, confirmPassword: confirmPass } = { oldPassword: oldPassword.value, newPassword: newPassword.value, confirmPassword: confirmPassword.value }; if (!oldPass || !newPass || !confirmPass) { uni.showToast({ title: &#39;所有密码都必须填写&#39;, icon: &#39;none&#39; }); return; } if (newPass !== confirmPass) { uni.showToast({ title: &#39;新密码与确认密码不一致&#39;, icon: &#39;none&#39; }); return; } uni.showLoading({ title: &#39;提交中...&#39; }); try { const res = await uni.request({ url: &#39;http://172.26.26.43/dev-api/system/user/profile/updatePwd&#39;, method: &#39;POST&#39;, header: { &#39;Authorization&#39;: &#39;Bearer &#39; + uni.getStorageSync(&#39;token&#39;), &#39;Content-Type&#39;: &#39;application/json&#39; }, data: { oldPassword: oldPass, newPassword: newPass } }); uni.hideLoading(); if (res.statusCode === 200 && res.data.code === 200) { uni.showToast({ title: &#39;密码修改成功&#39;, icon: &#39;success&#39; }); uni.removeStorageSync(&#39;token&#39;); uni.removeStorageSync(&#39;userInfo&#39;); setTimeout(() => { uni.reLaunch({ url: &#39;/pages/login/login&#39; }); }, 1500); } else { uni.showToast({ title: &#39;密码修改失败&#39;, icon: &#39;none&#39; }); } } catch (error) { uni.hideLoading(); uni.showToast({ title: &#39;网络请求失败&#39;, icon: &#39;none&#39; }); console.error(&#39;请求失败:&#39;, error); } closeResetModal(); }; // 处理退出登录 const handleLogout = () => { uni.vibrateShort(); // 添加震动反馈 uni.showModal({ title: &#39;确认退出&#39;, content: &#39;您确定要退出当前账号吗?&#39;, confirmText: &#39;退出登录&#39;, confirmColor: &#39;#e74c3c&#39;, success: (res) => { if (res.confirm) { // 清除用户相关数据 uni.removeStorageSync(&#39;token&#39;); uni.removeStorageSync(&#39;userInfo&#39;); uni.removeStorageSync(&#39;savedUsername&#39;); // 显示退出提示 uni.showToast({ title: &#39;已退出登录&#39;, icon: &#39;success&#39;, duration: 1500 }); // 跳转到登录页 setTimeout(() => { uni.reLaunch({ url: &#39;/pages/login/login&#39; }); }, 1500); } } }); }; </script> <style lang="scss" scoped> .container { padding: 20rpx; background-color: #f5f7fa; min-height: 100vh; } /* 用户信息区域样式 */ .user-info-section { display: flex; align-items: center; padding: 30rpx; margin: 20rpx 0; background: linear-gradient(135deg, #3498db, #8e44ad); color: white; position: relative; overflow: hidden; border-radius: 24rpx; &::before { content: &#39;&#39;; position: absolute; top: -50%; right: -50%; width: 200%; height: 200%; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%); pointer-events: none; } } .user-phone { display: block; font-size: 24rpx; // margin-top: 10rpx; color: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.2); padding: 4rpx 12rpx; border-radius: 20rpx; backdrop-filter: blur(10px); } .avatar-container { position: relative; width: 120rpx; height: 120rpx; margin-right: 30rpx; } .avatar-image { width: 100%; height: 100%; border-radius: 50%; background-color: #fff; } .avatar-frame { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 4rpx solid rgba(255, 255, 255, 0.3); border-radius: 50%; box-sizing: border-box; } .user-details { flex: 1; } .welcome-text { font-size: 28rpx; opacity: 0.9; } .username { display: block; font-size: 40rpx; font-weight: bold; margin: 8rpx 0; text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.2); } .user-meta { display: flex; flex-wrap: wrap; gap: 15rpx; margin-top: 15rpx; } .user-role, .user-dept { font-size: 24rpx; background: rgba(255, 255, 255, 0.2); padding: 4rpx 12rpx; border-radius: 20rpx; backdrop-filter: blur(10px); } /* 功能板块区域 */ .function-section { background-color: #fff; border-radius: 24rpx; margin: 30rpx 40rpx; /* 左右边距增加 */ box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); overflow: hidden; } .function-item { display: flex; align-items: center; justify-content: space-between; padding: 30rpx 35rpx; /* 增加左右内边距 */ position: relative; transition: all 0.2s ease; /* 点击效果 - 缩放 */ &:active { transform: scale(0.98); background-color: #f8f8f8; } /* 触摸效果 - 高亮 */ &.touch-active { background-color: #f0f9ff; transform: scale(0.98); .item-text { font-weight: bold; } } } .logout-item { .item-text { color: #e74c3c; } &.touch-active { background-color: #fff0f0; } } .item-left { display: flex; align-items: center; } .item-icon { width: 44rpx; height: 44rpx; margin-right: 20rpx; transition: transform 0.2s ease; .touch-active & { transform: scale(1.1); } } .item-text { font-size: 32rpx; color: #333; transition: all 0.2s ease; .touch-active & { transform: translateX(5px); } } .arrow-icon { font-size: 40rpx; color: #999; transform: scale(1.5, 1.5); transition: all 0.2s ease; .touch-active & { transform: scale(1.5, 1.5) translateX(-5px); } } .divider { height: 1rpx; background-color: #f0f0f0; margin: 0 35rpx; /* 与内边距一致 */ } /* 动画效果 */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .pulse { animation: pulse 0.3s ease; } /* 重置密码弹窗*/ .modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 9999; animation: fadeIn 0.3s ease; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .modal-content { background-color: #fff; width: 80%; max-width: 600rpx; border-radius: 24rpx; overflow: hidden; box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.2); animation: slideUp 0.3s ease; } @keyframes slideUp { from { transform: translateY(100rpx); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 30rpx; background-color: #f8f8f8; border-bottom: 1rpx solid #eee; } .modal-title { font-size: 34rpx; font-weight: bold; color: #333; } .modal-close { font-size: 40rpx; color: #999; padding: 10rpx 20rpx; } .input-group { padding: 30rpx; } .input-item { display: flex; align-items: center; margin-bottom: 30rpx; padding-bottom: 15rpx; border-bottom: 1rpx solid #eee; position: relative; &:last-child { margin-bottom: 0; } } .input-icon { width: 36rpx; height: 36rpx; margin-right: 20rpx; opacity: 0.7; } .eye-icon-wrapper { position: absolute; right: 10rpx; top: 50%; transform: translateY(-50%); width: 60rpx; /* 增大点击区域 */ height: 60rpx; display: flex; align-items: center; justify-content: center; z-index: 100; /* 提高层级 */ touch-action: manipulation; background-color: rgba(255, 255, 255, 0.8); /* 添加背景 */ border-radius: 50%; &:active { background-color: rgba(200, 200, 200, 0.8); transform: translateY(-50%) scale(0.95); } } .eye-icon { width: 40rpx; height: 40rpx; opacity: 0.7; transition: opacity 0.2s; } .password-input { flex: 1; height: 70rpx; /* 增加高度 */ font-size: 32rpx; color: #333; padding-right: 80rpx; /* 增加右侧内边距 */ } .modal-buttons { display: flex; border-top: 1rpx solid #eee; } .cancel-btn, .confirm-btn { flex: 1; height: 90rpx; line-height: 90rpx; font-size: 32rpx; border-radius: 0; background: none; position: relative; &::after { content: &#39;&#39;; position: absolute; top: 0; bottom: 0; width: 1rpx; background-color: #eee; } } .cancel-btn { color: #666; &:active { background-color: #f8f8f8; } } .confirm-btn { color: #3498db; font-weight: bold; &:active { background-color: #f0f9ff; } } .confirm-btn::after { left: 0; } .cancel-btn::after { display: none; } </style> 在重置密码弹窗的输入框输入密码时可以点击小眼睛显示输入的具体内容,但是点击其他地方后这个输入框就没有小眼睛了也就不能点击小眼睛查看该输入框输入的内容了
最新发布
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值