解决移动端1px 边框优化的8个方法

news2024/9/22 1:19:46

前言

您是否注意到 1px 边框在移动设备上有时会显得比预期的要粗?这种不一致源于移动屏幕的像素密度不同。

在 Web 开发中,我们使用 CSS 来设置页面样式。但是,CSS 中的 1px 并不总是转换为设备上的物理 1px。这种差异就是我们的“1px 边框问题”产生的原因。

罪魁祸首:像素密度

每个设备都拥有特定的像素密度,由 devicePixelRatio 测量,它告诉我们物理像素与设备独立像素之间的比率。

devicePixelRatio = 物理像素 / 独立像素

今天我就来跟你分享8 个久经考验的解决方案 。探索解决方案,我们要重点关注像素比大于或等于 2 的情况。

1.  0.5px 边框:一个简单的解决方案

此方法涉及在设备像素比为 2 或更高时有条件地应用 0.5px 边框。

// Check if devicePixelRatio exists and is greater than or equal to 2
if(window.devicePixelRatio && devicePixelRatio>=2){
  // Create a temporary div element for testing
  var testElem = document.createElement('div');
  // Apply a 0.5px transparent border to the test element
  testElem.style.border = '.5px solid transparent';
  // Append the test element to the body
  document.body.appendChild(testElem);
  // Check if the rendered height is 1px (meaning 0.5px border works)
  if(testElem.offsetHeight == 1){
    // If yes, add the 'hairlines' class to the HTML element
    document.querySelector('html').classList.add('hairlines');
  }
  // Remove the test element
  document.body.removeChild(testElem);
}
//  Place the above script inline. If it's inside a function, 
// wrap it in $(document).ready(function(){}) to ensure it runs after the DOM is ready.

// Default border style
div{
  border: 1px solid #bbb;
}
// Apply 0.5px border when 'hairlines' class is present
.hairlines div {
  border-width: 0.5px;
}

2.  边框图像:完美的边框

使用专门制作的边框图像是一种有效的方法。以下是创建底部边框的方法:

.border-bottom-1px {
  // Set other border widths to 0
  border-width: 0 0 1px 0;
  // Apply the border-image – ‘linenew.png’ 
  // (assuming you have an image for this)
  border-image: url(linenew.png) 0 0 2 0 stretch;
  // For webkit browsers
  -webkit-border-image: url(linenew.png) 0 0 2 0 stretch;
}

解释:

  • 我们只在底部设置边框(border-width:0 0 1px 0)。

  • 使用的图像(“linenew.png”)假定为 2px 高。

  • 图像顶部 1px 是透明的,底部 1px 包含实际边框颜色。

3.  Background-Image:背景技巧

与 border-image 类似,此方法利用预先准备的图像作为边框。

.backround-image-1px{
  // Set the background image, repeating it along the x-axis and positioning it at the left bottom
  background: url(../img/line.png) repeat-x left bottom;
   // Set the background size for Webkit browsers
  -webkit-background-size: 100% 1px;
  // Set the background size (1px height for the border effect)
  background-size: 100% 1px;
}

注意事项:

  • 更改颜色需要替换图像。

  • 圆角可能会显得模糊,需要额外的样式。

4.  多背景渐变:边框的错觉

我们可以使用渐变背景来模仿边框的外观。渐变的一半显示所需的颜色,而另一半保持透明。

.background-gradient-1px{
    // Create a multi-background with linear gradients for each side
    background:
      line-gradient(180deg, black, black 50%, transparent 50%) top left / 100% 1px no-repeat,
      line-gradient(90deg, black, black 50%, transparent 50%) top right / 1px 100% no-repeat,
      line-gradient(0, black, black 50%, transparent 50%) bottom right /  100% 1px no-repeat,
      line-gradient(-90deg, black, black 50%, transparent 50%) bottom left / 1px 100% no-repeat;
  }

/* Alternatively, use an older syntax for Webkit browsers*/
.background-gradient-1px{
      // Apply a linear gradient from top to bottom
      background: -webkit-gradient(linear, left top, left bottom, 
                                   color-step(.5, transparent), // Transparent at 50%
                                   color-step(.5, #c8c7cc), // Color starts at 50%
                                   to(#c8c7cc)) // End color
                                   left bottom repeat-x; 
      // Set the background size
      background-size: 100% 1px; 
}

5.  Box-Shadow:跳出框框

让我们利用 CSS 阴影来创建令人信服的边框效果。

.box-shadow-1px {
  // Apply an inset box shadow – the negative spread simulates a thin border
  box-shadow: inset 0px -1px 1px -1px #c8c7cc; 
}

6.  视口 + Rem:动态二重奏 

调整视口的 rem 基值有助于在不同设备上实现一致的 1px 边框。请记住,使用此技术修改旧项目可能需要进行重大调整。

优点:适用于各种布局的适应性解决方案。

缺点:对于遗留项目来说可能具有挑战性。

// For a device pixel ratio of 1, set the viewport as follows:
<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

// For a device pixel ratio of 2
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
// For a device pixel ratio of 3
<meta name="viewport" content="initial-scale=0.333333, maximum-scale=0.333333, minimum-scale=0.333333, user-scalable=no">

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <meta name="viewport"
        content="width=device-width,initial-scale=1,user-scalable=no"
  />
  <title>rem+viewport</title> 
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
    }
    #box {
      width: 8rem;
      height: 8rem;
      border: 1px solid #000;
    }
</style>
</head>
<body>
  <div id="box"></div>

  <script type="text/javascript">
    // Get the device pixel ratio
    var dpr = window.devicePixelRatio; // Example: 2 on a Retina display 
    console.log(dpr, 'dpr+++');

    // Calculate the inverse scale 
    var scale = 1 / dpr; 
    // Get the initial viewport width – this might be inaccurate due to the dpr
    var width = document.documentElement.clientWidth; // Example: 375 on an iPhone X
    // Adjust the viewport meta tag to counteract the device pixel ratio
    var metaNode = document.querySelector('meta[name="viewport"]');
    metaNode.setAttribute('content', 'width=device-width,initial-scale=' + scale + ',user-scalable=no');
    // Recalculate the width after viewport adjustment
    var width = document.documentElement.clientWidth; // Now, it should be closer to 750
    // Dynamically set the base font size using rem units
    var styleN = document.createElement('style');
    styleN.innerHTML = 'html{font-size: ' + width / 16 + 'px !important;}'; 
    document.head.appendChild(styleN);
</script>
</body>
</html>

7.  伪元素 + 变换:传统项目英雄 

这种方法对现有项目非常方便。我们删除原始边框,并利用伪元素制作 1px 边框,将其缩小以获得像素完美的外观

.scale-1px {
  position: relative;
  border: none; // Remove any default borders
}

.scale-1px:after {
  content: '';
  position: absolute;
  bottom: 0;
  background: #000; // Set the desired border color
  width: 100%;
  height: 1px; 
  transform: scale(0.5); // Scale down to 0.5 to achieve a thinner border
  transform-origin: 0 0; 
}
.scale-1px-top {
  border: none;
  position: relative;
}
.scale-1px-top:before {
  content: '';
  position: absolute;
  display: block;
  top: 0;
  left: 0;
  width: 200%; // Stretch to cover potential scaling issues
  height: 1px;
  border-top: 1px solid #E7E7E7;
  -webkit-transform: scale(0.5, 0.5);
  transform: scale(0.5, 0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}
.scale-1px-bottom {
  border: none;
  position: relative;
}
.scale-1px-bottom:before {
  content: '';
  position: absolute;
  display: block;
  bottom: -1px; // Adjust position to avoid overlapping content
  left: 0;
  width: 200%; 
  height: 1px;
  border-bottom: 1px solid #ccc; 
  -webkit-transform: scale(0.5, 0.5);
  transform: scale(0.5, 0.5); 
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0; 
}
.borderRadius-1px { 
  border-radius: .16rem; 
  border: none;
  position: relative;
}
.borderRadius-1px:after { 
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  border: 1px solid #d1d1d1;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  width: 200%; // Ensure the pseudo-element covers the entire element
  height: 200%;
  -webkit-transform: scale(0.5);
  transform: scale(0.5);
  -webkit-transform-origin: left top; 
  transform-origin: left top;
  border-radius: .16rem;
}

8.  SVG:绘制线条

我们也可以使用 SVG 直接绘制 1px 线条。

<svg width="100%" height="1" style="position: absolute; bottom: 0; left: 0;">
  <line x1="0" y1="0" x2="1000" y2="0" style="stroke:#E5E5E5; stroke-width:1" /> 
</svg>

关于优联前端

        武汉优联前端科技有限公司由一批从事前端10余年的专业人才创办,是一家致力于H5前端技术研究的科技创新型公司,为合作伙伴提供专业高效的前端解决方案,合作伙伴遍布中国及东南亚地区,行业涵盖广告,教育, 医疗,餐饮等。有效的解决了合作伙伴的前端技术难题,节约了成本,实现合作共赢。可进行Web前端,微信小程序、小游戏,2D/3D游戏,动画交互与UI广告设计等各种技术研发。

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

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

相关文章

uniapp对tabbar封装,简单好用

第一种&#xff0c;效果展示 上代码&#xff0c;新建一个公用组件&#xff0c;tabbar.vue <template><view class"tabbar"><view class"tabbar-item" click"tabbarbtn(0)"><image class"item-image" v-if"…

什么是机器学习中的 Bagging?带有示例的指南

文章目录 一、说明二、理解集成学习2.1 什么是 Bagging&#xff1f;2.2 Bagging 与 Boosting2.3 套袋的优点 三、Python 中的 Bagging&#xff1a;简短教程3.1 数据集3.2 训练机器学习模型3.3 模型评估 四、装袋分类器4.1 评估集成模型4.2 最佳实践和技巧 五、结论 ​ 一、说明…

systrace/perfetto第三方app的Trace.beginSection方法无效问题和TAG开放剖析

背景 针对程序如何在自己的代码中加入相关的trace方法和TAG来方便在systrace/perfetto中进行查看&#xff0c;下面这篇文章已经进行了详细的讲解&#xff1a; systrace/perfetto中需要actrace打tag相关方法-车载车机framework系统开发实战 有针对native的c代码&#xff0c;也…

Java面试题总结-基础和框架-面试题一

1、TCP和UDP tcp 和 udp 是 OSI 模型中的运输层中的协议。tcp 提供可靠的通信传输&#xff0c;而 udp 则常被用于让广播和细节控制交给应用的通信传输。 两者的区别大致如下&#xff1a; tcp 面向连接&#xff0c;udp 面向非连接即发送数据前不需要建立链接&#xff1b;tcp …

MQ-135空气质量传感器(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 mq135.h文件 mq135.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 MQ-135空气质量传感器属于MQ系列气体传感器&#xff0c;广泛用于检测有害气体、新鲜空气中的烟…

Vmware 傻瓜式安装( Linux 网络操作系统 01)

一、下载VMware虚拟机安装包 虚拟机下载链接&#xff1a;https://share.weiyun.com/4haPul0y ​ 二、安装 点击安装文件 ​ 点击下一步&#xff0c;勾选“我接受...条款"&#xff0c;继续点击下一步 修改更改安装位置&#xff0c;尽量不要安装到系统C盘&#xff1a; …

爆刷!LLM入门必备吴恩达新书-《面向开发者的LLM入门课程》

吴恩达联合OpenAI推出LLM现象级课程&#xff01;|||绝了||重磅首发&#x1f525; 1、LLM入门必看课程-吴恩达373 PDF||!适用于所有具备基础 Python 能力&#xff0c;想要入门 LLM 的学习者 2、由吴恩达老师与 OpenAI 联合推出的官方教程&#xff0c;面向入门 LLM 的开发者&…

[Linux入门]---进程替换

文章目录 1.进程替换原理2.进程替换函数2.1execl函数2.2execlp函数2.3execv函数2.4execvp函数2.5execle函数2.6execve函数2.7跨语言调用程序 3.总结 1.进程替换原理 一个程序替换的函数&#xff1a; #include <unistd.h> int execl(const char *path, const char *arg,…

Linux下的系统接口(实时更新)

文件操作 open pathname:路径 flags&#xff1a;文件的打开方式 mode&#xff1a;文件的权限 返回值 打开成功返回值该文件的文件描述符&#xff0c;打开失败返回-1。 write fd : 文件描述符 buf : 指向用于存储写入数据的缓冲区的指针 count : 写入字节的最大个数 返回…

7系列FPGA HR/HP I/O区别

HR High Range I/O with support for I/O voltage from 1.2V to 3.3V. HP High Performance I/O with support for I/O voltage from 1.2V to 1.8V. UG865&#xff1a;Zynq-7000 All Programmable SoC Packaging and Pinout

Jmeter之beanshell使用

beanshell&#xff1a;和setup类似&#xff0c;登录前需要做的工作&#xff0c;是一种java源代码解释器&#xff0c;具有脚本语言的特性 使用beanshell可以使jmeter实现更多的业务需求 beanshell常用语法 vars.get() 从jmeter中获得变量 vars.put() 把数据保存为jmeter的变量…

Access用了20年杀死VF,等来的却是:国产新型软件反杀

现如今&#xff0c;使用Access数据库的人可能不多了。 Access数据库 在早些年的时候&#xff0c;微软旗下有两个广为人知的桌面数据库开发工具。 一款是自家研发的Microsoft ACCESS&#xff0c;它依托Windows操作系统&#xff0c;并内嵌于Microsoft Office之中&#xff0c;深受…

2024下《系统规划与管理师》50个高频考点汇总!背就有效

今年高项仅考上半年一次&#xff0c;下半年考的高级科目只有系规难度相对较低&#xff0c;系规需要学习的内容比高项少很多&#xff0c;高项第四版教程731页&#xff0c;系规只有328页&#xff0c;少了一半多。并且系规IT内容会更少&#xff0c;考试内容大多在书上&#xff0c;…

接口幂等的方案

一、什么是幂等 幂等指多次操作产生的影响只会跟一次执行的结果相同&#xff0c;通俗的说&#xff1a;某个行为重复的执行&#xff0c;最终获取的结果是相同的。 二、什么是接口幂等 同一个接口&#xff0c;对于同一个请求&#xff0c;不管调用多少次&#xff0c;产生的最终…

除了C盘其它盘都不见了?专业数据恢复策略解析

在数字时代&#xff0c;数据几乎成为了我们生活与工作的核心。然而&#xff0c;当电脑突然遭遇“除了C盘其它盘都不见了”的困境时&#xff0c;无疑是对我们数据安全的一次重大挑战。面对这样的紧急情况&#xff0c;如何迅速、有效地恢复丢失的数据&#xff0c;成为了许多用户迫…

苹果被删视频怎么恢复?分享4个靠谱的方法

平时过年过节的时候&#xff0c;亲戚家的小孩总会拿你的手机乱点一通&#xff0c;有时可能会不小心点进手机相册里面&#xff0c;误删了相册里的视频。如果苹果用户遇到这种情况&#xff0c;那该如何恢复苹果被删视频呢&#xff1f;不要慌张&#xff0c;既然你点开了这篇文章&a…

cv::convexityDefects()详解

参考链接:详解OpenCV的函数convexHull()和函数convexityDefects(),并利用它们)做凸包(凸壳)检测及凸包(凸壳)的缺陷检测-CSDN博客 void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects ); 三个参数说明如下&#xff1a; contou…

Java ArrayList扩容机制 (源码解读)

结论&#xff1a;初始长度为10&#xff0c;若所需长度小于1.5倍原长度&#xff0c;则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义 1&#xff1a;数组默认长度 2:这是一个共享的空数组实例&#xff0c;用于明确创建长度为0时的ArrayList &#xff…

钙粘蛋白CDH:肿瘤靶点研究新秀

前 言&#xff1a; 钙粘蛋白是钙依赖性细胞间粘附的重要介质&#xff0c;属于跨膜糖蛋白。钙粘蛋白在组织稳态中起重要作用&#xff0c;促进组织发育、突触粘附和上皮屏障功能。钙粘蛋白功能改变与癌症进展、血管疾病和其他病理学有关。目前多种钙粘蛋白有望成为治疗靶点&…

英伟达显卡A100定制版和原厂版什么区别为什么价格相差这么大?

环境&#xff1a; 英伟达A100显卡 问题描述&#xff1a; 英伟达显卡A100定制版和原厂版什么区别为什么价格相差这么大&#xff1f; 定制版 原本 解决方案&#xff1a; NVIDIA A100显卡的定制版和原版之间的主要区别通常在于它们的设计、用途、性能以及价格。以下是一些…