能否同时使用img的width/height与srcset/sizes?附图片裁剪疑问
背景
近期在为个人网站开发响应式图片,图片规范是宽度不超过450像素,也存在更小尺寸的图片。最初使用带width和height属性的img标签,填入图片实际尺寸,但在屏幕宽度小于450像素的响应式场景中表现不佳。
测试时用单张图片,不想提供多版本,使用了以下代码:
<img src="assets/img/software-developer.jpeg" alt="Some Stuff" srcset="assets/img/software-developer.jpeg 450w" sizes="(max-width: 449px) 75vw, (min-width: 450px) 450px">
这段代码在Chrome开发者工具测试中表现正常:屏幕宽度小于450px时图片按75vw缩放,否则按原尺寸显示。
目前正将WordPress网站从付费主机迁移到GitHub Pages的Jekyll上,原因有两点:
- 成本:付费主机对比免费的GitHub Pages
- 性能:99%内容为静态,WordPress性能极差
但用PageSpeed测试页面时,要求指定width和height属性,知道这有助于浏览器快速计算图片尺寸、避免等待图片下载再渲染页面,但担心width/height和响应式环境不兼容。
疑问解答
1. 是否可以同时使用width/height与srcset/sizes?
完全可以同时使用。现在的浏览器已经支持在响应式图片中结合width/height属性,核心是搭配CSS的max-width: 100%; height: auto;实现自适应。
width和height的作用是给浏览器提供图片的原始宽高比,让浏览器提前预留出图片的显示空间,避免布局偏移(CLS);而srcset和sizes负责控制不同屏幕下图片的显示尺寸,两者互不冲突。
你只需要给图片添加基础CSS样式:
img { max-width: 100%; height: auto; }
然后在img标签里加上图片的原始宽高(比如这张450px宽的图片,假设高度是300px,就写width="450" height="300"),再配合已有的srcset和sizes即可,这样既满足PageSpeed的要求,又不影响响应式效果。
2. 用100vw替代75vw时图片被裁剪,是否是padding或margin导致的?
大概率是页面的padding、margin或者box-sizing设置导致的。
100vw代表视口的总宽度,但如果页面容器(比如<body>或外层<div>)设置了左右padding或margin,图片设置为100vw时,宽度会超出容器的可用空间,导致横向溢出被裁剪。另外,如果没有将box-sizing设置为border-box,元素的padding和border会额外增加总宽度,也可能导致图片超出容器范围。
解决方法:
- 改用
100%替代100vw,让图片宽度继承父容器的可用宽度,自动忽略父容器的padding和margin - 如果一定要用
vw单位,可计算好容器内边距,比如父容器有16px左右padding,就设置sizes="(max-width: 449px) calc(100vw - 32px), ...",减去左右padding的总宽度
内容的提问来源于stack exchange,提问作者Salvatore D'angelo

