用css媒体查询修复Higress官网移动端适配问题

432 阅读8分钟

Higress官网出现移动端适配问题,在手机浏览器上面,background显示一个视频,而且是自定义播放的视频,视频会覆盖掉原本位置的所有元素。然后我就去仔细检查了一下源码,是有人直接把MP4文件嵌入进去的。

<source src="https://cloud.video.taobao.com/vod/play/V3VEOGxHS3IxSU5wWkFYeTFuZU4wdHJ2eXloK1g1aXlXV0pvNU0zVjhmYTZQZWw1SnpKVVVCTlh4OVFON0V5UUVMUDduY1RJak82VE1sdXdHTjNOaHc9PQ"
        type="video/mp4"
      />

在移动端浏览器(尤其是iOS设备上的Safari浏览器)上,视频的处理方式与桌面端浏览器有显著不同。这种差异主要源于移动设备的硬件资源和电池续航能力的限制。

移动端浏览器对视频播放的处理原理

  1. 自动播放限制:在移动端设备上,为了节省用户的数据流量和电池电量,浏览器通常默认禁止视频的自动播放。尤其是在iOS设备上的Safari浏览器中,视频不会在页面加载时自动播放,除非视频设置为静音(muted)。即使设置为自动播放,Safari也可能要求用户与页面进行某种形式的交互(例如点击页面)才能开始播放视频。

  2. 背景视频处理:当视频被用作背景时(即使用CSS属性将视频定位在页面背景),在桌面浏览器上,通常可以实现无缝播放。然而,在移动端,特别是在iOS上,视频背景通常会遇到问题。这些问题包括视频无法自动播放、在播放时覆盖其他页面元素、以及不支持循环播放或静音播放等。

  3. 覆盖问题:在某些移动端浏览器中,当视频作为背景插入页面时,它可能会以比预期更高的层级显示,导致覆盖原本应该在视频上层显示的其他页面元素。这可能是由于浏览器在处理层级顺序(z-index)或其他渲染相关问题时的差异所导致的。

  4. 浏览器性能与电池优化:移动设备的硬件资源有限,浏览器通常会对资源密集型操作(如视频播放)进行优化。例如,Safari可能会限制在后台播放视频或限制多个视频同时播放。这些限制可能导致视频无法正确显示或影响页面的其他元素。

应对策略

由于移动端浏览器对视频的处理存在这些限制,开发者通常需要通过一些方法来优化用户体验:

  1. 媒体查询:使用CSS的媒体查询,根据设备类型或屏幕尺寸选择性地加载视频或替代静态图像。在小屏幕设备(如手机)上,可以隐藏视频并替换为静态图片,以避免视频覆盖内容。

    @media (max-width: 767px) {
        .video-background {
            display: none;
        }
        .background-image {
            display: block;
        }
    }
    
  2. 交互触发播放:在需要自动播放的视频上,可以使用JavaScript监听用户交互事件(如点击或滑动)后再触发视频播放,这样可以绕过自动播放的限制。

  3. 性能优化:减少在移动端加载的视频文件大小,或使用更优化的视频格式(如WebM),以减少设备的负载。此外,可以选择性地在桌面端加载高分辨率视频,在移动端加载低分辨率视频或静态图片。

当时GPT给我的几个方案

1. 确保视频静音

  • iOS设备上,只有静音视频可以自动播放。如果视频没有静音,浏览器会强制显示播放按钮并且不会自动播放。
  • 确保 muted 属性已经添加到 <video> 标签上。

2. 使用 playsinline 属性

  • iOS设备上,playsinline 属性可以确保视频在页面内播放而不是全屏播放。
  • playsinline 添加到 <video> 标签中:
<video
  autoplay
  muted
  loop
  playsinline
  class="video-background"
  poster="https://img.alicdn.com/imgextra/i1/O1CN01U3PG171Wiz4B85TGK_!!6000000002823-0-tps-2388-1168.jpg"
>
  <source
    src="https://cloud.video.taobao.com/vod/play/V3VEOGxHS3IxSU5wWkFYeTFuZU4wdHJ2eXloK1g1aXlXV0pvNU0zVjhmYTZQZWw1SnpKVVVCTlh4OVFON0V5UUVMUDduY1RJak82VE1sdXdHTjNOaHc9PQ"
    type="video/mp4"
  />
</video>

3. 使用替代方案

  • 如果视频影响了移动端的显示效果,可以考虑用动画GIF或者CSS动画代替视频,尤其是在移动端设备上。
  • 你可以通过JavaScript检测是否是移动设备,然后选择性地加载视频或其他替代内容。

4. 隐藏视频

  • 如果在iOS设备上视频效果不佳,你可以选择在CSS中通过媒体查询隐藏视频,并使用一个静态图像或其他替代方案来代替。
@media only screen and (max-width: 600px) {
  .video-background {
    display: none;
  }
  .introduce {
    background-image: url('https://img.alicdn.com/imgextra/i1/O1CN01U3PG171Wiz4B85TGK_!!6000000002823-0-tps-2388-1168.jpg');
    background-size: cover;
  }
}

5. 避免自动播放视频

  • 如果以上解决方案仍然无法解决问题,可以考虑在移动端禁用自动播放,并在需要时让用户手动点击播放。

==可以通过检测设备类型来决定在不同设备上展示视频或静态图像。这可以通过CSS中的媒体查询来实现,或者通过JavaScript动态检测用户的设备类型。==

方法一:使用CSS媒体查询

你可以通过媒体查询检测屏幕宽度,以判断是移动设备还是桌面设备。然后基于此选择性地展示视频或静态图像。

<!-- HTML 部分 -->
<div class="home-introduce-wrapper h-[65vh] relative">
  <video
    autoplay
    muted
    loop
    playsinline
    class="video-background"
    poster="https://img.alicdn.com/imgextra/i1/O1CN01U3PG171Wiz4B85TGK_!!6000000002823-0-tps-2388-1168.jpg"
  >
    <source
      src="https://cloud.video.taobao.com/vod/play/V3VEOGxHS3IxSU5wWkFYeTFuZU4wdHJ2eXloK1g1aXlXV0pvNU0zVjhmYTZQZWw1SnpKVVVCTlh4OVFON0V5UUVMUDduY1RJak82VE1sdXdHTjNOaHc9PQ"
      type="video/mp4"
    />
  </video>
  <div class="introduce flex flex-col justify-center items-center bg-transparent h-full relative z-1">
    <!-- 其他内容 -->
  </div>
  <!-- 静态图像背景 -->
  <div class="static-image-background"></div>
</div>

<!-- CSS 部分 -->
<style is:global>
  .home-introduce-wrapper {
    position: relative;
  }

  .video-background {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    object-fit: cover;
  }

  .static-image-background {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    background-image: url('https://img.alicdn.com/imgextra/i1/O1CN01U3PG171Wiz4B85TGK_!!6000000002823-0-tps-2388-1168.jpg');
    background-size: cover;
    display: none; /* 默认不显示 */
  }

  @media only screen and (max-width: 768px) {
    /* 隐藏视频,显示静态图像 */
    .video-background {
      display: none;
    }
    .static-image-background {
      display: block;
    }
  }
</style>

方法二:使用JavaScript检测设备类型

通过JavaScript,你可以更精确地检测用户的设备类型,然后根据结果动态切换视频或静态图像。

<!-- HTML 部分 -->
<div class="home-introduce-wrapper h-[65vh] relative">
  <div id="media-container">
    <!-- 视频或图片将通过JavaScript动态插入 -->
  </div>
  <div class="introduce flex flex-col justify-center items-center bg-transparent h-full relative z-1">
    <!-- 其他内容 -->
  </div>
</div>

<!-- JavaScript 部分 -->
<script>
  function isMobileDevice() {
    return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
  }

  const mediaContainer = document.getElementById('media-container');

  if (isMobileDevice()) {
    // 如果是移动设备,插入静态图像
    mediaContainer.innerHTML = `
      <div class="static-image-background"></div>
    `;
  } else {
    // 如果是桌面设备,插入视频
    mediaContainer.innerHTML = `
      <video
        autoplay
        muted
        loop
        playsinline
        class="video-background"
        poster="https://img.alicdn.com/imgextra/i1/O1CN01U3PG171Wiz4B85TGK_!!6000000002823-0-tps-2388-1168.jpg"
      >
        <source
          src="https://cloud.video.taobao.com/vod/play/V3VEOGxHS3IxSU5wWkFYeTFuZU4wdHJ2eXloK1g1aXlXV0pvNU0zVjhmYTZQZWw1SnpKVVVCTlh4OVFON0V5UUVMUDduY1RJak82VE1sdXdHTjNOaHc9PQ"
          type="video/mp4"
        />
      </video>
    `;
  }
</script>

<!-- CSS 部分 -->
<style is:global>
  .home-introduce-wrapper {
    position: relative;
  }

  .video-background {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    object-fit: cover;
  }

  .static-image-background {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    background-image: url('https://img.alicdn.com/imgextra/i1/O1CN01U3PG171Wiz4B85TGK_!!6000000002823-0-tps-2388-1168.jpg');
    background-size: cover;
  }
</style>

方法总结

  • 媒体查询: 适用于简单的场景,通过CSS自动切换视频和图片,适应不同屏幕宽度。
  • JavaScript: 提供更多的控制和灵活性,能够根据设备类型精准切换视频和图片。

后面我在Higress官网用媒体查询来做的移动端适配: [Fix] Use media queries to address video issues on iOS devices and optimize performance for website loading by LofiSu · Pull Request #298 · higress-group/higress-group.github.io

媒体查询(Media Query)用于检测设备的屏幕宽度,并根据设备类型(如桌面设备和移动设备)来调整显示内容。

什么是媒体查询?

媒体查询是CSS中的一种技术,允许你根据设备的特性(如屏幕宽度、高度、分辨率等)应用不同的样式。在这个案例中,媒体查询用于检测设备的屏幕宽度,以决定是否显示视频或静态图片。

如何应用媒体查询?

1. 检测屏幕宽度:

在代码中,使用了如下媒体查询:

@media only screen and (max-width: 768px) {
    .video-background {
        display: none;
    }

    .image-background {
        display: block;
    }
}

这段代码的作用是在屏幕宽度小于或等于768像素时,调整页面元素的显示方式。这种宽度通常适用于大多数移动设备(如智能手机和小尺寸的平板电脑)。

2. 隐藏视频,显示静态图片:

  • 视频背景:在默认情况下,.video-background 类用于显示一个背景视频,该视频在桌面设备上可以自动播放、循环播放,并且设置了静音(muted)。在移动设备上,当检测到屏幕宽度为768像素或更小时,通过媒体查询将这个视频隐藏,即:

    .video-background {
        display: none;
    }
    
  • 静态图片背景:同时,.image-background 类用于显示一张静态背景图片。默认情况下,这张图片是隐藏的,但在屏幕宽度为768像素或更小时,通过媒体查询将这张图片显示出来:

    .image-background {
        display: block;
    }
    

3. 使用媒体查询的目的:

  • 优化用户体验:由于移动设备通常不支持视频的自动播放(尤其是在iOS设备上),并且视频可能会覆盖其他重要内容,因此在小屏幕设备上隐藏视频而显示静态图片可以确保页面内容的可访问性和可读性。
  • 提升性能:视频文件通常较大,占用大量带宽和计算资源。通过在移动设备上替换为静态图片,减少了页面加载时间和设备资源的消耗,从而提升了网站的性能。

应用总结:

在这个案例中,通过媒体查询来检测设备的屏幕宽度,并根据设备类型调整内容显示方式,实现了响应式设计。这不仅解决了视频在移动端覆盖页面内容的问题,还提高了网站的加载性能,优化了用户体验。