【问题标题】:Responsively resize HTML div within parent, both letterbox and pillarbox, CSS only响应式调整父级内的 HTML div 大小,包括信箱和邮筒,仅 CSS
【发布时间】:2020-12-05 22:50:51
【问题描述】:

给定一个可以调整垂直和水平大小的父 HTML div 元素,我希望子 div 保持纵横比(例如,16:9),居中并受父级边缘的约束。请不要JS。

单独使用 CSS 是否可行? (顶部“较宽”的父图像示例为pillarbox,底部“较窄”的父图像示例为letterbox。)

注意:在大多数情况下,父级小于实际的浏览器视口,因此不要根据宽度或高度来判断您的答案(例如)的浏览器视口。这应该能够独立于任何给定的父/子大小。

【问题讨论】:

  • these 都没有按照你的要求做?
  • @ChrisW。据我所知,它们都依赖于响应式 width。这特别要求包含高度和宽度的纵横比缩放。您发布的链接中是否有包含两者的特定响应?
  • 我很确定我在那里看到了一个跟在the basics 后面的东西,但我确实有一个有时会快速浏览的坏习惯。
  • @ChrisW。也许我需要澄清我的问题。您提供的“基础知识”链接没有回答问题。它回答了信箱响应式纵横比维护,但不是邮筒。我两个都需要。 Padding-bottom/-top 仅适用于信箱。

标签: html css


【解决方案1】:

如果您愿意为此使用 iframe,我有一个创造性的解决方案。

字体大小可以相对于视口大小动态更改。您想调整容器而不是窗口的大小,因此为了使其工作,我们必须使用具有自己的视口的 iframe 包装所有内容,并调整 iframe 的大小。

想法是用 em 单位设置元素的宽度和高度,并动态设置字体大小。

我们有 2 个场景,一个更宽的容器或一个更高的容器,我们将使用媒体查询来分隔它:

max-aspect-ratio: 16/9

1.更高的容器

由于我们希望 div 保持 16:9 的比例,我们将 div 的尺寸设置为

width: 16em;
height: 9em;

为了让它占据 100% 的宽度,我们将字体大小设置为 100/9 = 11.111

font-size: 11.111vh

2。更宽的容器

一旦我们的媒体查询启动并且容器变宽了,我们将根据视口宽度更改字体大小,并且我们希望它采用 100% 的宽度,所以 -> 100/16 = 6.25

@media (max-aspect-ratio: 16/9) {
  .ratio-wrapper {
    font-size: 6.25vw;
  }
}

现在我们可以为内容添加另一个 div 并设置我们想要的字体大小。

var iframe = document.getElementById('iframe');
var content = "<html>" +
  "<head>" +
  "<style>" +
  "body," +
"html {" +
"  padding: 0;" +
"  margin: 0;" +
"}" +
".ratio-wrapper {" +
"  background-color: #bada55;" +
"  font-size: 11.111vh;" +
"  width: 16em;" +
"  height: 9em;" +
"}" +
".center {" +
"  width: 100%;" +
"  height: 100%;" +
"  display: flex;" +
"  justify-content: center;" +
"  align-items: center;" +
"}" +
".content {" +
"  height: 100%;" +
"  display: flex;" +
"  justify-content: center;" +
"  align-items: center;" +
"  font-size: 20px;" +
"}" +
"@media (max-aspect-ratio: 16/9) {" +
"  .ratio-wrapper {" +
"    font-size: 6.25vw;" +
"  }" +
"}" +
  "</style>" +
  "</head>" +
  "<body>" +
    "<div class='center'>" +
	    "<div class='ratio-wrapper'>" +
		    "<div class='content'>It Works!</div>" +
	    "</div>" +
    "</div>" +
  "</body>" +
  "</html>";
iframe.src = 'data:text/html,' + encodeURIComponent(content);
.cont {
  width: 300px;
  height: 300px;
  border: 1px solid black;
  resize: both;
  overflow: hidden;
  padding: 0;
  margin: 0;
}
&lt;iframe id="iframe" src="about:blank" class="cont" scrolling="no"&gt;&lt;/iframe&gt;

请注意,我只是使用 JS 将内容添加到 iframe,所以它可以在这里工作,您只需为您的内部内容设置一个 href,不需要 JS。我使 iframe 可调整大小,因此您可以轻松地使用它,或者您可以给它一个响应大小,它也可以。

【讨论】:

    【解决方案2】:

    您可以仅使用结合媒体查询的 Canvas 使用 CSS:

    <!DOCTYPE html>
    <html>
      <head>
        <style>
          html, body {
            height: 100%;
          }
          .container {
            position: absolute;
            display: inline-block;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
          .container, .aspect-ratio-canvas {
            @media (min-aspect-ratio: 16/9) {
              height: 100%;
            }
            @media (max-aspect-ratio: 16/9) {
              width: 100%;
            }
          }
          .aspect-ratio-canvas {
            padding: 0;
            margin: 0;
          }
          .content {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            border: 1px solid black; // For demonstration
          }
        </style>
      </head>
      <body>
        <div class="container">
          <canvas class="aspect-ratio-canvas" width="16" height="9"/>
          <div class="content">
            Test with anything here
          </div>
        </div>
      </body>
    </html>
    

    如果您愿意,可以将画布替换为具有相同纵横比的图像。

    此解决方案基于另一个线程上的此答案:https://stackoverflow.com/a/14911949/1581466

    【讨论】:

      【解决方案3】:

      经过艰苦的搜索,我发现了this article,它巧妙地使用了vwvh 单位:

      #ratio-16-9 {
        /* constrain to 16:9 ratio */
        width: 100vw; 
        height: calc(9/16 * 100vw);
        max-height: 100vh;
        max-width: calc(16/9 * 100vh);
        
        /* center */
        margin: auto;
        position: absolute;
        top: 0; bottom: 0; left: 0; right: 0;
        
        /* irrelevant */
        background-color: pink;
        text-align: center;
      }
      <div id="ratio-16-9">
        I stay 16:9 at all times while spanning as large as possible!
      </div>

      注意事项:

      1. 出于可读性原因,我将原始代码中的硬编码值替换为 calc 语句。
      2. 此示例适用于16:9 比率。要应用其他比率,只需相应地更改 calc 语句中的 16s 和 9s。

      【讨论】:

        【解决方案4】:

        我相信这可以很简单地为您提供您想要的:

        <!DOCTYPE html>
        <html lang="en-us">
        
        <head>
            <meta charset="UTF-8">
            <title>
                Title
            </title>
        
        </head>
        
        <body>
            <div class="parent">text
            </div>
        
            <style>
                .parent {
                    background-color: green;
                    width: 100%;
                    height: calc(100vw/1.77777);
                }
            </style>
        </body>
        
        </html>
        

        当然,HTML 和 CSS 只是为了展示它的工作原理。重要的是,您只需确定您想要的宽度(例如 100%),然后进行简单计算以获得相应的高度,使其为 16:9。在本例中,即视口宽度的 100% 除以 1.77777 得到 16:9。

        注意:此解决方案只是将高度设置为您选择的宽度的一小部分。如果您不想要 100vw 的宽度,那么您只需替换您用来指定宽度的任何内容(像素、百分比、您有什么)。

        【讨论】:

          【解决方案5】:

          你想要这个 css

          object-fit: contain
          

          https://www.w3schools.com/css/css3_object-fit.asp

          【讨论】:

          • object-fit 仅适用于 &lt;img&gt;&lt;video&gt; 元素。我的问题仅与 &lt;div&gt; 元素(或其他块级标签)有关。
          猜你喜欢
          • 2015-11-27
          • 2016-06-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-28
          • 1970-01-01
          • 2021-12-03
          • 2011-12-11
          相关资源
          最近更新 更多