移动web开发常见问题

1. 去掉图片下方的空白间隙

默认情况下,图片会与其下方的元素产生一段空白的间隙

<img>默认是inline(行内替换元素),遵循基线对齐,下方预留文字下行空间;

html 复制代码
<style>
  .box img {
    width: 200px;
    border: 1px solid red;
    /*1. 添加此样式*/
    vertical-align: top;
    /*2. 或者转为块级元素*/
    display:black;
  }
  .box p {
    margin: 0;
    height: 20px;
    background-color: khaki;
  }
</style>

<div class="box">
  <img src="./images/pic1.png" alt="" />
  <p></p>
</div>
  1. 清除父元素的行高影响 图片的基线对齐会受父元素 line-height 影响,将父元素行高设为 0,也能消除间隙:
css 复制代码
   .img-parent { /* .img-parent 是 img 的父容器 */
     line-height: 0;
   }

2. 元素宽高等比缩放

利用 padding-top 来撑开元素的高,padding-top 百分比是相对于当前元素的父元素宽而言,而当前元素宽与父元素宽一样,则相当于元素的高是相对于当前元素的宽而言。

html 复制代码
<style>
 .box {
    width: 25%;
  }
 .box .bl16-9 {
    --bl: calc(9 / 16 * 100%);
    padding-top: var(--bl);
    background-color: khaki;
    position: relative;
  }
  .box .content {
    position: absolute;
    inset: 0;
  }
</style>

<!-- 元素宽高比为 16:9 等比缩放 -->
<div class="box">
  <div class="bl16-9">
    <div class="content">元素宽高比为 16:9 等比缩放</div>
  </div>
</div>

3. 图片等比缩放

在实际的网站上线后,数据都是从后台读取的,用户在上传图片尺寸时,并不一定会按照设计师设计的比例来上传,这样就会造成图片上传后,大小不一样。

  • 图片高度过小,会在下面留下空白
  • 图片高度过大,会有一部分下面的内容看不到
  • 我们实际在设计一张图时,重要的内容会在中间显示,所以最理想的效果是让图片能水平垂直居中于容器中

要实现图片按一定的宽高比等比缩放,可以先将图片的直接父元素实现宽高等比缩放,然后再给图片添加如下代码

css 复制代码
img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
html 复制代码
<style>
  .box {
    width: 25%;
  }
  .box .bl16-9 {
    --bl: calc(9 / 16 * 100%);
    padding-top: var(--bl);
    background-color: khaki;
    position: relative;
  }
  .box .content {
    position: absolute;
    inset: 0;
  }
  .box img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
</style>

<!-- 元素宽高比为 16:9 等比缩放 -->
<div class="box">
  <div class="bl16-9">
    <div class="content">
      <img src="./images/pic1.png" alt="" />
    </div>
  </div>
</div>

4. 背景图等比缩放

  • 当背景图片的宽高比与容器的宽高比不一样时
  • 我们希望不管容器宽高如何缩放,图片一直填充整个容器,然后水平垂直居中显示
css 复制代码
/* 背景图填充整个容器 */
background-size: cover;
html 复制代码
<style>
  body {
    margin: 0;
  }
  .box {
    width: 100vw;
    height: 31.467vw;
    /* 背景图片  不重复  水平垂直居中显示 */
    background: url(./images/banner1-@2x.png) no-repeat center;
    /* 背景图填充整个容器 */
    background-size: cover;
  }
</style>
<body>
  <div class="box"></div>
</body>

5. 2倍精灵图使用

  • 精灵图采用的是 2 倍图
  • 所以在处理精灵图时,我们需要通过 background-size: 50% auto; ,来将背景图片大小缩小一半
  • 测量尺寸时,也需要按一半的大小来测量
html 复制代码
<style>
  .icon-play {
    width: 26px;
    height: 26px;
    border: 1px solid red;
    background-image: url(images/sprite.png);
    background-position: -36px -29px;
    background-size: 200px;
  }
</style>
<body>
  <div class="icon-play"></div>
</body>

6.经典的 1 像素问题

6.1、何为 1 像素问题

PSD 设计稿

  • 我们的设计稿是以 750px 宽来设计的,而我们实际开发时,代码是按 375px 来的。
  • 在 750px 设计稿中的 1px,按我们实际的开发代码来说,要折半,折成 0.5px 才对。
  • 但是不同手机上,不同浏览器对小数的处理是不一样的
  • 0.5px 在一些老的 IOS 和 Android 设备上不支持,他会把低于 0.5px 当成 0 来处理,>= 0.5px 当成 1px 来显示。
  • IOS 上会把>= 0.75px 的当作 1px 来处理 ,< 0.75 当成 0.5px 来处理 < 0.5px 当成 0 来处理
  • 而且 IOS 上,用 height: 1px 来代替 border-bottom: 1px solid red;测出的效果不同
  • 不同的手机上,效果不一样,具体以真机测试为主
  • 所以直接把代码折半,设置成 0.5px 显然是达不到目的。

1px 实际显示的大小

1px 在 dpr (像素比)不同时,其显示的大小不同,如下

所以在不同 dpr 下,显示的 1px 的线的宽度是下面图标出的蓝色 的高度大小(1 物理像素大小) 因此, 1px 像素问题(用当前设备的物理像素的1px进行渲染这根线的高度),本质上不是问题,如果公司觉得没有必要,也就不用处理。

如果公司认为就是要用设备能显示的最细的那个小方格显示,那我们就要处理这个问题。

6.2、1px 像素解决方案(最优的解决方案 transform+伪元素来实现)

实现原理:

  • 利用伪元素来绘制 1px 的线条,然后利用定位,把线条放在对应位置
  • 利用 media 查询判断不同的设备像素比对线条进行缩放
HTML 复制代码
<style>
  .box {
    height: 50px;
    margin: 0 auto;
    position: relative;
  }
  .border-1px::before {
    position: absolute;
    content: "";
    height: 1px;
    width: 100%;
    background-color: red;
    bottom: 0;
    /* transform: scaleY(0.5); */
    /* 变换原点 */
    transform-origin: 50% 0%;
  }
  /* dpr=2,需要缩放一半,即0.5 */
  @media only screen and (-webkit-min-device-pixel-ratio: 2) {
    .border-1px:before {
      transform: scaleY(0.5);
    }
  }
  /* dpr=3,需要缩放到1/3,即0.33 */
  @media only screen and (-webkit-min-device-pixel-ratio: 3) {
    .border-1px:before {
      transform: scaleY(0.33);
    }
  }
</style>
<body>
  <div class="box border-1px"></div>
</body>

也可以通过 js 来判断 dpr,然后给元素添加对应的 Class 名字,来实现

JS 复制代码
if (window.devicePixelRatio && devicePixelRatio >= 2) {
  document.querySelector(".box").className = "border-1px";
}
相关推荐
ahhdfjfdf20 小时前
前端实现带滚动区域的 DOM 长截图导出
前端·javascript·react.js
周星星日记20 小时前
vue3中使用defineModel
前端·vue.js
八哥程序员20 小时前
javascript 为什么会有闭包这么个烧脑的东西
前端·javascript
JavaEdge在掘金20 小时前
上线卡半夜、出 bug 只能硬扛?前端自动化部署 + 秒级回滚方案来了
前端
方也_arkling20 小时前
【八股】JS中的事件循环
开发语言·前端·javascript·ecmascript
颜酱20 小时前
从经典问题入手,吃透动态规划核心(DP五部曲实战)
前端·javascript·算法
深盾科技21 小时前
C++ 中 std::error_code 的应用与实践
java·前端·c++
Jagger_21 小时前
我的AI驯服记:从7640px大屏的惨败,到总结出一套高效协作SOP
前端
hy352821 小时前
VUE 踩坑合集
前端·javascript·vue.js