Css 自动缩放SVG以适应子内容(例如文本)的宽度[无JS]
我发现的一切都是相反的,例如“如何缩放文本以适应SVG”。但我想实现相反的目标: 我的html中的SVG:Css 自动缩放SVG以适应子内容(例如文本)的宽度[无JS],css,svg,Css,Svg,我发现的一切都是相反的,例如“如何缩放文本以适应SVG”。但我想实现相反的目标: 我的html中的SVG: 一些文本 CSS: svg.text{ 字体大小:2.5rem;//不同屏幕大小的更改 高度:0.8em; 宽度:auto;//这不起作用……无论文本的内容如何,宽度都会变得奇怪,总是一样的 } svg.text文本{ transform:translateY(0.8em);//需要这样才能使文本可见 } 我希望增长以匹配文本元素的宽度,就像将普通DOM元素设置为显示:内联块一样或位
一些文本
CSS:
svg.text{
字体大小:2.5rem;//不同屏幕大小的更改
高度:0.8em;
宽度:auto;//这不起作用……无论文本的内容如何,宽度都会变得奇怪,总是一样的
}
svg.text文本{
transform:translateY(0.8em);//需要这样才能使文本可见
}
我希望
增长以匹配文本
元素的宽度,就像将普通DOM元素设置为显示:内联块一样代码>或位置:绝对代码>或<代码>浮动:左侧代码>
有什么想法吗
编辑
多亏了这一点,我想到了这个:
JavaScript:
/**
*将SVG适配到其第一个文本子视图框
*/
fitSvgTextElements(){
const elements=document.querySelectorAll('svg.text');
for(元素常数){
const box=el.querySelector('text').getBBox();
el.setAttribute('viewBox',`${box.x}${box.y}${box.width}${box.height}`);
}
}
这很有效。但是有没有办法用纯CSS/SVG属性来解决这个问题呢?由于SVG格式的基本设计决定,如果没有脚本,您想要实现的大小更改是无法实现的。描述了如下相关概念:
所有SVG内容都在SVG视口中绘制。每个SVG视口定义一个绘图区域,其特征是大小(宽度、高度)和原点
SVG视口的宽度、高度和原点由生成SVG视口的SVG文档片段与该片段的父级(无论是真实的还是隐式的)之间的协商过程确定
这意味着视口的尺寸取决于它们的外部上下文,但与它们的内部内容无关
如果试图按视口元素的内容调整其大小,则会颠倒该逻辑顺序,并且只能在最初完成渲染后才能实现。此时,只有脚本才能更改呈现的DOM
您已经在您的问题中演示了如何使用脚本解决方案,尽管我会用不同的方式编写它。而CSS规则width:auto;高度:1em
应该足够了,一些较旧的浏览器对此有问题。我更愿意明确地计算
元素的宽度。(与CSS样式表规则相比,width
属性的特异性更低。)
fitSvgTextElements(){
const elements=document.querySelectorAll('svg.text');
for(元素常数){
const box=el.querySelector('text').getBBox();
el.setAttribute('viewBox',`${box.x}${box.y}${box.width}${box.height}`);
//元素位于HTML上下文中,
//因此,需要与页面视口相关的尺寸
const viewport=el.getBoundingClientRect();
//保留高度,重新计算相对宽度
常量宽度=viewport.height*box.width/box.height;
el.style.width=`${width}px`;
}
}
事实上,我发现了一种更干净的方法。魔法属性是,如图所示
HTML格式的SVG(在文本元素上带有主基线=“挂起”
):
…现在我可以调整CSS中的文本大小,例如:
svg.text{
显示:block;//或内联块
font size:inherit;//将响应父级的字体大小
}
使用getBBox()方法获取文本元素的边界框,并使用边界框的属性为svg元素构建viewBox属性谢谢!我很想解决这个问题,不用担心,谢谢!实际上,在我的例子中,即使没有明确定义
(在Chrome和FF中测试)的宽度属性,它也可以工作。视口
属性使
的行为类似于普通的
标记,不是吗?So高度:1米;宽度:自动我的CSS中的code>将缩放相对于高度的宽度。无论如何,谢谢你提供的深入信息,它很有效!在将您的答案标记为解决方案之前,我将等待这一点得到澄清。该属性称为viewBox
。Viewport=要显示图形的区域,viewbox=要显示的图形部分。是的,使用CSS规则width:auto
它应该可以工作,但较旧的浏览器可能无法正常工作。
fitSvgTextElements() {
const elements = document.querySelectorAll('svg.text');
for( const el of elements ) {
const box = el.querySelector('text').getBBox();
el.setAttribute('viewBox', `${box.x} ${box.y} ${box.width} ${box.height}`);
// the <svg> element is in HTML context,
// so you need dimensions in relation to the page viewport
const viewport = el.getBoundingClientRect();
// retain height, recompute width in relation
const width = viewport.height * box.width / box.height;
el.style.width = `${width}px`;
}
}
<svg class="text" xmlns='http://www.w3.org/2000/svg'>
<text dominant-baseline="hanging">
My Text
</text>
</svg>