SVG 矩形在 Firefox 中对 CSS 有响应,但对 Chrome 没有响应
SVG rect is Responsive with CSS in Firefox but not Chrome
我想出了两种方法可以使 SVG 中的元素相对于 SVG 的父元素或 SVG 本身(无论如何 SVG 高度都是 100%)具有响应式调整大小:
-
- 使用 CSS 变量更改 CSS 中的高度
- 在 Firefox 中工作,但在 Chrome 中不工作,我不知道为什么?
-
- 通过获取 SVG 的父级高度来更改 JS 中的高度
- 适用于 Firefox 和 Chrome,但我希望调整大小的逻辑尽可能集中在一个地方(即仅 CSS)
为了便于阅读,这是我想要的简化版本。在我的项目中,我试图构建一个 SVG 导航按钮,它看起来像一个垂直边框,中间有一个箭头,箭头保持相同大小,但它上方和下方的垂直线随着按钮高度的变化而变化,并且按钮高度为 100vh - 100px
,以便为页眉和页脚腾出空间,目前每个高度为 50px
。出于这个原因,除了 SVG 的高度之外,我还需要 viewbox 尺寸响应,所以我不能在 CSS.
中完成这部分
https://codepen.io/Daniel-WR-Hart/pen/PoKPebb
approach1.html
: JS 只处理视图框的大小调整
<html lang="en">
<head>
<title>Responsive SVG Rect</title>
<link rel="shortcut icon" href="data:,">
<style>
:root {
--view-box-half: calc(50%);
--rect-thick: calc(25px);
--end-gap: calc(50px);
--longer-side: calc(var(--view-box-half) - var(--end-gap));
}
body {
margin: 0;
}
rect {
width: var(--rect-thick);
height: var(--longer-side);
}
button {
width: 50px;
margin: var(--end-gap) 0 0 0;
padding: 0;
height: calc(100vh - 100px);
background-color: blue;
cursor: pointer;
border: none;
}
svg {
opacity: 0.7;
transition: opacity 0.4s;
}
svg:hover {
opacity: 1;
}
</style>
<script type="module" defer>
const svg = document.querySelector('svg');
const parent = svg.parentNode; // a button
const rect = document.querySelector('rect');
setResponsiveArrowResizing();
function setResponsiveArrowResizing() {
window.addEventListener('load', updateSizes);
window.addEventListener('resize', updateSizes);
function updateSizes() {
updateViewBoxSize();
updateRectSize();
}
function updateViewBoxSize() {
// (0,0) is in the center of the svg's viewBox
svg.viewBox.baseVal.x = parent.offsetWidth / -2;
svg.viewBox.baseVal.y = parent.offsetHeight / -2;
svg.viewBox.baseVal.width = parent.offsetWidth;
svg.viewBox.baseVal.height = parent.offsetHeight;
}
function updateRectSize() {
// Handled in CSS
}
}
</script>
</head>
<body>
<button>
<svg width="100%" height="100%" viewBox="0 0 0 0" style="background-color: rgb(150, 40, 40)">
<rect/>
</svg>
</button>
</body>
</html>
approach2.html
: 与 approach1.html
相同,但进行了这些更改,以便 JS 处理更改 rect
的高度而不是 CSS:
rect {
width: var(--rect-thick);
/* height: var(--longer-side); */
}
function updateRectSize() {
rect.style.height = parent.offsetHeight / 2 - 50 + 'px';
}
对于您的情况,将 --view-box-half: calc(50%);
替换为 --view-box-half: calc((100vh - 100px) / 2);
应该可以完成工作(并且将是最简单的解决方案)
勾选your updated working example here
我认为百分比高度的问题与 viewBox and preserveAspectRatio
有关
The viewBox attribute defines the position and dimension, in user space, of an SVG viewport.
虽然高度正在更新,但视口保持不变,因此矩形的高度不会更新。
我想出了两种方法可以使 SVG 中的元素相对于 SVG 的父元素或 SVG 本身(无论如何 SVG 高度都是 100%)具有响应式调整大小:
-
- 使用 CSS 变量更改 CSS 中的高度
- 在 Firefox 中工作,但在 Chrome 中不工作,我不知道为什么?
-
- 通过获取 SVG 的父级高度来更改 JS 中的高度
- 适用于 Firefox 和 Chrome,但我希望调整大小的逻辑尽可能集中在一个地方(即仅 CSS)
为了便于阅读,这是我想要的简化版本。在我的项目中,我试图构建一个 SVG 导航按钮,它看起来像一个垂直边框,中间有一个箭头,箭头保持相同大小,但它上方和下方的垂直线随着按钮高度的变化而变化,并且按钮高度为 100vh - 100px
,以便为页眉和页脚腾出空间,目前每个高度为 50px
。出于这个原因,除了 SVG 的高度之外,我还需要 viewbox 尺寸响应,所以我不能在 CSS.
https://codepen.io/Daniel-WR-Hart/pen/PoKPebb
approach1.html
: JS 只处理视图框的大小调整
<html lang="en">
<head>
<title>Responsive SVG Rect</title>
<link rel="shortcut icon" href="data:,">
<style>
:root {
--view-box-half: calc(50%);
--rect-thick: calc(25px);
--end-gap: calc(50px);
--longer-side: calc(var(--view-box-half) - var(--end-gap));
}
body {
margin: 0;
}
rect {
width: var(--rect-thick);
height: var(--longer-side);
}
button {
width: 50px;
margin: var(--end-gap) 0 0 0;
padding: 0;
height: calc(100vh - 100px);
background-color: blue;
cursor: pointer;
border: none;
}
svg {
opacity: 0.7;
transition: opacity 0.4s;
}
svg:hover {
opacity: 1;
}
</style>
<script type="module" defer>
const svg = document.querySelector('svg');
const parent = svg.parentNode; // a button
const rect = document.querySelector('rect');
setResponsiveArrowResizing();
function setResponsiveArrowResizing() {
window.addEventListener('load', updateSizes);
window.addEventListener('resize', updateSizes);
function updateSizes() {
updateViewBoxSize();
updateRectSize();
}
function updateViewBoxSize() {
// (0,0) is in the center of the svg's viewBox
svg.viewBox.baseVal.x = parent.offsetWidth / -2;
svg.viewBox.baseVal.y = parent.offsetHeight / -2;
svg.viewBox.baseVal.width = parent.offsetWidth;
svg.viewBox.baseVal.height = parent.offsetHeight;
}
function updateRectSize() {
// Handled in CSS
}
}
</script>
</head>
<body>
<button>
<svg width="100%" height="100%" viewBox="0 0 0 0" style="background-color: rgb(150, 40, 40)">
<rect/>
</svg>
</button>
</body>
</html>
approach2.html
: 与 approach1.html
相同,但进行了这些更改,以便 JS 处理更改 rect
的高度而不是 CSS:
rect {
width: var(--rect-thick);
/* height: var(--longer-side); */
}
function updateRectSize() {
rect.style.height = parent.offsetHeight / 2 - 50 + 'px';
}
对于您的情况,将 --view-box-half: calc(50%);
替换为 --view-box-half: calc((100vh - 100px) / 2);
应该可以完成工作(并且将是最简单的解决方案)
勾选your updated working example here
我认为百分比高度的问题与 viewBox and preserveAspectRatio
有关The viewBox attribute defines the position and dimension, in user space, of an SVG viewport.
虽然高度正在更新,但视口保持不变,因此矩形的高度不会更新。