如何获取CSS中背景SVG的宽高并实现容器宽高比例自适应?
问题:背景图片高度无法随宽度按比例缩放
我遇到的问题是背景图片高度无法按预期随宽度缩放。尝试过background-size: cover、background-size: contain以及object-fit属性,都没能实现让容器高度依赖于容器宽度的效果。
我思路是通过height: calc(currentHeight/currentWidth*100%)设置高度为宽度的百分比,打算用React的useRef结合窗口大小变化事件获取实时数值,但不知道如何定位CSS中加载的SVG文件,看到的示例都是用img标签的。
背景图片CSS代码(styled-components):
const Background = styled.section` border: solid 1px red; background: url(${Donationsvg}) no-repeat center; background-size: contain; width: 100%; height: 100%; `;
页面结构:
<Background> <Grid> <Card> <Button> <h4>title</h4> </Button> <p>Lorem ipsum dolor sit amet consectetur adipisic.</p> </Card> <Card> <Button> <h4>title</h4> </Button> <p>Lorem ipsum dolor sit amet consectetur adipisic.</p> </Card> <Card> <Button> <h4>title</h4> </Button> <p>Lorem ipsum dolor sit amet consectetur adipisic.</p> </Card> </Grid> </Background>
解决方案
方法1:纯CSS实现(无需JS,推荐)
利用padding-top百分比基于容器宽度计算的特性,结合SVG的固有宽高比直接设置:
- 先确定你的SVG宽高比(比如SVG宽1000px、高600px,比例就是
600/1000=60%) - 修改styled-components代码:
const Background = styled.section` border: solid 1px red; background: url(${Donationsvg}) no-repeat center; background-size: contain; width: 100%; padding-top: 60%; /* 替换为你的SVG实际高宽比 */ height: 0; /* 重置高度,避免内容额外撑开高度 */ position: relative; /* 让内部元素可以基于容器定位 */ `; // 调整内部Grid的定位,避免被padding挤走 const Grid = styled.div` position: absolute; top: 0; left: 0; right: 0; bottom: 0; /* 保留原有Grid样式 */ `;
方法2:动态获取SVG尺寸(适合比例不固定场景)
通过创建隐藏的img标签加载SVG,获取尺寸后计算比例:
import { useState, useEffect } from 'react'; import Donationsvg from './path/to/Donationsvg.svg'; import styled from 'styled-components'; const Background = styled.section` border: solid 1px red; background: url(${Donationsvg}) no-repeat center; background-size: contain; width: 100%; height: ${props => props.aspectRatio ? `${props.aspectRatio * 100}%` : '100%'}; `; const YourComponent = () => { const [aspectRatio, setAspectRatio] = useState(null); useEffect(() => { const img = new Image(); img.src = Donationsvg; img.onload = () => { // 计算高宽比:高度/宽度 setAspectRatio(img.height / img.width); }; // 窗口 resize 时复用已获取的比例(SVG是矢量图,尺寸不会变) const handleResize = () => setAspectRatio(img.height / img.width); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return ( <Background aspectRatio={aspectRatio}> <Grid> {/* 你的Card内容 */} </Grid> </Background> ); };
为什么之前的方法无效?
background-size: cover/contain仅调整背景图尺寸,不会改变容器自身高度,容器高度仍由内容或height属性决定object-fit仅对<img>、<video>等替换元素生效,对CSS背景图不适用
内容的提问来源于stack exchange,提问作者Franco Hauva
相关产品推荐
相关产品推荐

