响应式单位 vw() 详细解析

418 阅读2分钟
  • vw()是一个自定义SCSS函数,可将设计稿的像素值(px)转换为响应式的vw单位。可确保页面在不同屏幕尺寸下保持一致的视觉效果。
// sytles/mixins.scss

// 设计稿宽度(默认1920px)
$design-width: 1920;

// px转vw函数
@function vw($px) {
    @return calc($px * 100 / $design-width) + vw;
}

// 最小宽度限制
@mixin max-width($width: 1920px) {
    @media screen and (min-width: $width) {
        width: $width
    }
}

// 最大宽度限制
@mixin max-width($width: 1920px) {
    @media screen and (min-width: $width) {
        width: $width;
    }
}

// 响应式范围限制
@media responsive-range($minWidth: 1366px, $maxWidth: 1920px) {
    @include min-width($minWidth);
    @include max-width($maxWidth);
}
  • 在vue、scss模板中使用:
<template>  
  <div class="container">  
    <div class="card">  
      <h2 class="title">响应式标题</h2>  
      <p class="content">响应式内容</p>  
    </div>  
  </div>  
</template>  

<style lang="scss" scoped>  
@import '@/styles/mixins.scss';

.container {  
  // 容器宽度在 1366px - 1920px 之间自适应  
  @include responsive-range();  
  margin: 0 auto;  
  padding: vw(20);  
}  

.card {  
  width: vw(400);  // 设计稿上 400px 转换为 vw 单位  
  padding: vw(16);  
  border-radius: vw(8);  
  background: #fff;  
  box-shadow: 0 vw(2) vw(8) rgba(0, 0, 0, 0.1);  
}  

.title {  
  font-size: vw(24);  // 24px -> vw  
  margin-bottom: vw(16);  
}  

.content {  
  font-size: vw(16);  // 16px -> vw  
  line-height: 1.5;  
}  
</style>
  • 计算原理:

    1. vw 是视窗宽度的1/100,即 1vw = 视窗宽度的1%
    2. 转换公式:vw = (像素值 * 100)/ 设计稿宽度
    3. 如,在 1920px设计稿中的 24px:
      • vw(24) = (24 * 100) / 1920 = 1.25vw
  • 优化建议:创建一个完整的响应式工具集

// styles/responsive.scss

// 基础配置
$design-width: 1920;
$min-width: 1366;
$max-width: 1920;

// px转vw
@function vw($px) {
    @return calc($px * 100 / $design-width) + vw;
}

// px 转 rem 
@function rem($px) {
    @return calc($px / 16) + rem;
}

// 响应式混入
@mixin responsive($property, $value) {
    #{$property}: $value;
    #{$property}: vw($value);
}

// 媒体查询
@mixin mobile {
    @media screen and (max-width: 767px) {
        @content;
    }
}

@mixin tablet {
    @media screen and (min-width: 768px) and (max-width: 1024px){
        @content;
    }
}

@mixin desktop {
    @media screen and (min-width: 1025px) {
        @content;
    }
}

@mixin font-size($size) {
    font-size: $size;
    font-size: vw($size);
}
  • 在项目中使用:
<style lang="scss" scoped>  
@import '@/styles/responsive.scss';  

.component {  
  // 基础响应式  
  width: vw(200);  
  padding: vw(16);  
  
  // 使用混入  
  @include responsive('margin', 20);  
  @include font-size(16);  
  
  // 媒体查询  
  @include mobile {  
    width: 100%;  
    padding: vw(8);  
  }  
  
  @include tablet {  
    width: vw(300);  
  }  
  
  @include desktop {  
    width: vw(400);  
  }  
}  
</style>
  • vite中配置导入:
// vite.config.ts  
export default defineConfig({  
  css: {  
    preprocessorOptions: {  
      scss: {  
        additionalData: `  
          @import "@/styles/responsive.scss";  
        `  
      }  
    }  
  }  
})
  • 使用中设置合理断点:
$breakpoints: (  
  'sm': 576px,  
  'md': 768px,  
  'lg': 992px,  
  'xl': 1200px,  
  'xxl': 1600px  
);
  • 创建响应式工具类:
.responsive-container {  
  width: 100%;  
  margin: 0 auto;  
  padding: 0 vw(16);  
  
  @include min-width(1366px) {  
    max-width: 1366px;  
  }  
}
  • 处理特殊场景:
// 最小字体大小限制  
@function vw-min($px, $min-px) {  
  @return max(vw($px), $min-px + px);  
}  

// 使用  
.text {  
  font-size: vw-min(16, 12);  // 最小不小于 12px  
}

总结

  • 该响应式方案优势:

    1. 保持设计稿的视觉比例
    2. 适应不同屏幕尺寸
    3. 避免在极端尺寸下的显示问题
    4. 提供统一的开发体验
  • 注意:vw 单位在移动端想要特别注意处理,可能需要配合其他单位(如 rem)使用。