保持div居中且保持宽高比并能够在垂直或水平方向上调整大小

3
我能找到多个半成品方案,但我正在寻找一个完整的解决方案来解决我的问题。我有一个 div,我想在屏幕中央以固定的纵横比居中显示,该 div 应始终完全可见,因此该 div 始终是最大的,同时保持其宽高比,而不管垂直和水平调整窗口大小。
这里有一个 Codepen 示例:https://codepen.io/william-bang/pen/ZjyWRd ,我创建了这个示例,它只解决了水平方向上的问题,但垂直方向上没有解决。我已经尝试使用和标签让它工作,但大小调整表现不同。我正在寻找一种 CSS 解决方案,虽然我也接受 JS 解决方案,如果有人确信不存在 CSS 解决方案。

body {
  width: 100%;
  height: 100%;
}

.wrapper {
  width: 40%;
  height: 100%;
  margin: auto
}

.img {
  padding-top: 50%;
  width: 100%;
  background: #ccc;
  text-align: center;
}
<div class="wrapper">

  <div class="img">
    **IMG HERE**
  </div>
  
</div>

我将非常感激您的任何建议,这个问题已经让我困扰了很多个小时。提前谢谢:)
更新,div需要在不同页面上保持其纵横比,并始终保持自己的最大尺寸。
@Grenther 感谢您的回答,我尝试修改您给出的答案,以便纯粹使用CSS而不必使用CSS预处理器。这进展得非常顺利,直到我意识到CSS媒体查询不支持标准CSS变量,否则您提出的方法本来可以在不使用SCSS的情况下实现,但也许您已经知道了。

:root {
  --ogW: 1600;
  --ogH: 900;
  --ratio: calc( var(--ogW) / var(--ogH));
}

 body {
  width: 100%;
  height: 100%;
}

.ratio {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  
  @media screen and (max-width: 177vh) {
    width: 90vw; 
    height: calc( 90vw / var(--ratio)); 
  } 

  @media screen and (min-width: 177vh) {
    width: calc( 90vh * var(--ratio));  
    height: 90vh;
  }

}

.div {
  width: 100%;
  height: 100%;
  background: red;
  text-align: center;
}
<div class="ratio">

  <div class="div">
    
    Hello!
    
  </div>
  
</div>


1
可能是重复的问题,参考链接:https://stackoverflow.com/a/51041869/8620333 - Temani Afif
@TemaniAfif 这两个问题是不同的,这个问题旨在在窗口的宽度和高度改变时保持 div 的纵横比。另一个问题是尝试在容器和盒子之间保持比例。这不是这里的目的。 - William Larsen Bang
只需将“容器”替换为“窗口”,然后再读一遍您的句子即可;顺便说一下,我只是标记为可能重复,并没有关闭重复。 - Temani Afif
3个回答

3

最终更新:

这是一个SCSS问题,对于任何输入的变量宽度或高度,可以按如下方式完成:

http://jsfiddle.net/832v5f0L/41

 $div-width : 1600;
 $div-height : 900;

 $ratio: $div-width / $div-height;

  @media screen and (max-width: (100 * $ratio) + vh) {
    width: 100vw; // always 100vw to fill
    height: (100 / $ratio) + vw; // 100 / ratio
  }

  @media screen and (min-width: (100 * $ratio) + vh) {
    width: (100 * $ratio) + vh;  //100 * ratio
    height: 100vh; // always 100vh to fill
  }

更新的答案:

当宽度小于高度时,媒体查询纵向自动激活。这确保我们可以使用vh和vw来获取最大可能的大小,而不会导致溢出。

宽度和高度之间的比例将确保您可以获得固定的宽高比。

    body {
  width: 100%;
  height: 100%;
}
.wrapper {
  position: absolute;
  left: 50%;
  top: 50%;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

/* 
100vh * (100 / height) 
with hright 50:
100vh * 100 / 50 = 200vh
*/

@media screen and (max-width: 200vh) {
  .wrapper {
      width: 100vw;
      height: 50vw;
  }
}
@media screen and (min-width: 200vh) {
  .wrapper {
      width: 200vh;
      height: 100vh;
  }
}

.img {
/*   padding-top: 50%; */
  width: 100%;
  height: 100%;
  background: #ccc;
  text-align: center;
  background-img: url()
}
<div class="wrapper">

  <div class="img">
    **IMG HERE**
  </div>
  
</div>

更新:最小宽度和最大宽度查询


@WilliamLarsenBang 我已经更新了答案。希望这能达到你想要的效果 ;) - Grenther
嘿,这是一个非常酷的技巧,谢谢你回信 :) 然而,这会限制 div 可以达到的最大尺寸。因此,如果 div 很宽,它就无法完全拉伸到最大尺寸。 - William Larsen Bang
我得向@Grenther夸一下,这个真是太棒了。我使用了你的代码并设置了400宽和200高的最大值,它完美地工作了。但我不理解vh的数学计算。所以当我改变我的div比例时,它就出问题了。我已经创建了一个fiddle,请使用我的sass vars并将其编织到您的vh代码中,使用数学计算,这样我就可以看到您如何使用vh大小了吗? https://jsfiddle.net/joshmoto/832v5f0L/ - joshmoto
@Grenther 感谢您的回复,我尝试修改您给出的答案,以便纯粹使用CSS而不必使用CSS预处理器。这一切进行得非常顺利,直到我意识到CSS媒体查询不支持标准CSS变量,否则您提出的方法本来可以在没有SCSS的情况下实现,但也许您已经知道了。您可以查看我的更新帖子。 - William Larsen Bang
是的,CSS 变量有一些限制。 "var() 函数可以用于元素上任何属性的任何部分的替代。var() 函数不能用作属性名称、选择器或除属性值以外的任何其他内容。(这样做通常会产生无效的语法,或者一个与变量没有关联的含义的值。)" 我建议将其标记为已回答并结束今天的工作 @WilliamLarsenBang - Grenther
显示剩余4条评论

1
看下面的代码片段。当您调整包装器宽度时,img将按比例缩放以适合,并保持其纵横比。 img还将在.wrapper元素内垂直居中和水平居中。

* {
  box-sizing:border-box;
}

html,
body {
  width: 100%;
  height: 100%;
}

.wrapper {
  width: 50%;
  height: 100%;
  margin: auto;
  position: relative;
}

.img {
  max-width: 100%;
  max-height: 100%;
  padding:20px 40px;
  background:grey;
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: fit-content;
  width: fit-content;
  margin: auto;
  transform: translateY(-50%);
}

.img img {
  max-width: 100%;
  height: auto;
  max-height: 100%;
}
<div class="wrapper">
  <div class="img">
    <img src="https://cdn.pixabay.com/photo/2013/01/29/00/47/search-engine-76519_960_720.png">
  </div>
</div>


是的,我已经用img标签实现了效果,但我只想要一个div解决方案。如果有一种方法可以在img下面放置一个div,那就太好了,但这并不能解决我的问题。不过还是谢谢你的帮助 :) - William Larsen Bang
@WilliamLarsenBang 我已经使用 transform 属性编辑了示例。个人不太喜欢使用它,但更新后的示例应该可以解决你在 CSS 中遇到的问题。 - Rylee
注意:此仅适用于div具有子元素的情况。否则它没有东西来缩放宽度。 - Rylee
抱歉,我没有正确地尝试代码,我不知道有一个名为“fit-content”的Height方法。这非常巧妙。 - William Larsen Bang

0

这是一个很棒的问题,我已经尝试了很长时间才解决,但不使用 flex 在垂直高度上进行调整似乎是一项艰巨的任务。

但是@Grenther 的答案似乎实际有效,而且没有使用图像。他的 1x2 比例 div 在调整窗口宽度和高度时保持不变。

然后,我修改了他的代码,使 div 上有 max-heightmax-width。我只能通过他的 200px x 400px 比例来做到这一点。

如果@Grenther可以更新我的 jsfiddle 代码,以便任何设置的 div 大小/比例变量都可以使用他聪明的 vh 方法大小调整,那将会很棒。就算我也难以看出他的版本是如何工作的。但如果每个 vh 维度中的数学都在 sass 代码中,我们可能能够理解他的魔法。

@Grenther 这里有一个版本: https://jsfiddle.net/joshmoto/jndmoz6v/

 /* div size vars and div ratio3 */
 $div-width : 400;
 $div-height : 200;

 body {
  width: 100%;
  height: 100%;
}

.ratio {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);

  /* set your div max-size here  */
  max-width: $div-width + px;
  max-height: $div-height + px;

  @media screen and (max-width: 200vh) {
    width: 100vw;
    height: 50vw;

  }

  @media screen and (min-width: 200vh) {
    width: 200vh;
    height: 100vh;

  }

}

.div {
  width: 100%;
  height: 100%;
  background: red;
  text-align: center;

}

我知道这不是关于Sass的问题,但我只是使用它来展示@Grenther的答案逻辑。


我自己尝试了一下这个数学问题,但当我改变div的大小/比例时,它并不像他的版本那样工作。

可以看到我的失败尝试:https://jsfiddle.net/joshmoto/Lkebpyws/

$div-width : 400;
$div-height : 200;

.ratio {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);

  /* set your div max-size here  */
  max-width: $div-width + px;
  max-height: $div-height + px;

  @media screen and (max-width: $div-height + 'vh') {
    width: ($div-width / 4) + vw;
    height: ($div-height / 4) + vw;

  }

  @media screen and (min-width: $div-height + 'vh') {
    width: ($div-width / 2) + vh;
    height: ($div-height / 2) + vh;

  }

}

...

我的最终更新应该提供一个足够的解决方案,请查看我的更新答案。(我确实留下了 max-height 和 max-width 的注释,但即使您不使用它们,它也能很好地工作) - Grenther

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接