如何使 div 元素自动调整大小并保持宽高比?

Fra*_*ozo 5 html css

我试图让div屏幕居中。这个 div 应该有一个特定的widthheight当它适合可用的窗口空间时,但是当可用的窗口空间不够时,它应该缩小以适合,但同时保持其原始的宽高比。

我一直在研究许多适用于减小 的示例width,但没有一个适用于同时适用于窗口大小width和变化的示例。height

这是我当前的 CSS:

* {
    border: 0;
    padding: 0;
    margin: 0;
}
.stage_wrapper {
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: gray;
}
.stage {
    width: 960px;
    height: 540px;
    max-width: 90%;
    max-height: 90%;
    display: flex;
    justify-content: center;
    align-items: center;
    background: chocolate;
    object-fit: contain; /* I know this is for images, it's an example of what I'm looking for */
}
Run Code Online (Sandbox Code Playgroud)

而且,我当前的 HTML:

<div class="stage_wrapper">
    <div class="stage">
        <p>Some text</p>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

这显示了居中div,固定width为 960 像素,固定height为 540 像素。它永远不应该比这个更大。

然后,如果我将窗口的大小更改为更小widthheight小于该值,则该div元素将成功缩小 - 除非它不保持原始的纵横比,而这正是我正在寻找的。我希望它能够响应 和 的width变化height

这有可能吗?

Tem*_*fif 7

aspect-ratio ref属性现在得到了很好的支持,因此您可以使用以下内容:

body {
  height: 100vh;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background: gray;
}


.stage {
  --r: 960 / 540;

  aspect-ratio: var(--r);
  width:min(90%, min(960px, 90vh*(var(--r))));
  
  display: flex;
  justify-content: center;
  align-items: center;
  
  
  background: 
    /* this gradient is a proof that the ratio is maintained since the angle is fixed */
    linear-gradient(30deg,red 50%,transparent 50%),
    chocolate;
}
Run Code Online (Sandbox Code Playgroud)
<div class="stage">
  <p>Some text</p>
</div>
Run Code Online (Sandbox Code Playgroud)


旧答案

这是使用视口单位和 的想法clamp()。这是一种if else测试屏幕的宽度是否大于或小于高度(考虑比例),并根据结果进行计算。

在下面的代码中,有两个变量cvandch并且只有其中一个等于1

  • 如果是,cv那么宽度更大,所以我们将高度设置为cv,宽度将基于该高度,因此逻辑上cv/ratio

  • 如果是,ch那么高度更大,所以我们将宽度设置为cv,高度将基于该宽度,因此逻辑上ch/ratio

clamp()我正在使用1vh/中1vw,我乘以它90相当于你90%90vh/90vw

body {
  height: 100vh;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background: gray;
}


.stage {
  --r: calc(960 / 540);
  
  --cv: clamp(0px,(100vw - 100vh*var(--r))*10000,1vh);
  --ch: clamp(0px,(100vh*var(--r) - 100vw)*10000,1vw);

  height: calc((var(--cv) + var(--ch)/var(--r)) * 90 );
  width:  calc((var(--ch) + var(--cv)*var(--r)) * 90 );
  
  max-width: 960px;
  max-height: 540px; /* OR calc(960px/var(--r)) */
  
  display: flex;
  justify-content: center;
  align-items: center;
  
  
  background: 
    /* this gradient is a proof that the ratio is maintained since the angle is fixed */
    linear-gradient(30deg,red 50%,transparent 50%),
    chocolate;
}
Run Code Online (Sandbox Code Playgroud)
<div class="stage">
  <p>Some text</p>
</div>
Run Code Online (Sandbox Code Playgroud)

理论上,夹具可以简化为:

--cv: clamp(0px,(1vw - 1vh*var(--r)),1vh);
--ch: clamp(0px,(1vh*var(--r) - 1vw),1vw);
Run Code Online (Sandbox Code Playgroud)

但为了避免任何舍入问题,并且不要落入像0.x我认为的大值这样的值,以确保它始终被限制为1正数

更新

Firefox 似乎有一个错误,所以这里是相同代码的另一个版本:

--cv: clamp(0px,(1vw - 1vh*var(--r)),1vh);
--ch: clamp(0px,(1vh*var(--r) - 1vw),1vw);
Run Code Online (Sandbox Code Playgroud)
body {
  height: 100vh;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background: gray;
}


.stage {
  --r: calc(960 / 540);
  
  --cv: clamp(0px,(100vw - 100vh*var(--r))*100,90vh);
  --ch: clamp(0px,(100vh*var(--r) - 100vw)*100,90vw);

  height: calc((var(--cv) + var(--ch)/var(--r)) );
  width:  calc((var(--ch) + var(--cv)*var(--r)) );
  
  max-width: 960px;
  max-height: 540px; /* OR calc(960px/var(--r)) */
  
  display: flex;
  justify-content: center;
  align-items: center;
  
  
  background: 
    /* this gradient is a proof that the ratio is maintained since the angle is fixed */
    linear-gradient(30deg,red 50%,transparent 50%),
    chocolate;
}
Run Code Online (Sandbox Code Playgroud)