jac*_*ckb 996 html css aspect-ratio css3 responsive-design
我想创建一个div
可以随着窗口宽度的变化而改变宽度/高度的东西.
是否有任何CSS3规则允许高度根据宽度改变,同时保持其宽高比?
我知道我可以通过JavaScript实现这一点,但我更喜欢只使用CSS.
Web*_*ner 1285
只需创建一个<div>
包含百分比值的包装器padding-bottom
,如下所示:
div {
width: 100%;
padding-bottom: 75%;
background: gold; /** <-- For the demo **/
}
Run Code Online (Sandbox Code Playgroud)
<div></div>
Run Code Online (Sandbox Code Playgroud)
它将导致<div>
高度等于其容器宽度的75%(纵横比为4:3).
这取决于填充的事实:
百分比是根据生成的框的包含块[...] 的宽度计算的(来源:w3.org,强调我的)
其他宽高比和100%宽度的填充底部值:
aspect ratio | padding-bottom value
--------------|----------------------
16:9 | 56.25%
4:3 | 75%
3:2 | 66.66%
8:5 | 62.5%
Run Code Online (Sandbox Code Playgroud)
将内容放在div中:
为了保持div的纵横比并防止其内容被拉伸,您需要添加一个绝对定位的子项并将其拉伸到包装器的边缘:
div.stretchy-wrapper {
position: relative;
}
div.stretchy-wrapper > div {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
Run Code Online (Sandbox Code Playgroud)
web*_*iki 396
vw
单位:您可以使用vw
单位来表示元素的宽度和高度.这允许基于视口宽度保留元素的宽高比.
vw:视口宽度的1/100.[ MDN ]
或者,您也可以使用vh
视口高度,甚至vmin
/ vmax
使用视口尺寸的较小/较大(此处讨论).
div {
width: 20vw;
height: 20vw;
background: gold;
}
Run Code Online (Sandbox Code Playgroud)
<div></div>
Run Code Online (Sandbox Code Playgroud)
对于其他宽高比,您可以使用下表根据元素的宽度计算高度值:
aspect ratio | multiply width by
-----------------------------------
1:1 | 1
1:3 | 3
4:3 | 0.75
16:9 | 0.5625
Run Code Online (Sandbox Code Playgroud)
body {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
div {
width: 23vw;
height: 23vw;
margin: 0.5vw auto;
background: gold;
}
Run Code Online (Sandbox Code Playgroud)
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
Run Code Online (Sandbox Code Playgroud)
这是一个小提琴这个演示,这里是一个解决方案,使一个响应网格的正方形与verticaly和horizontaly居中的内容.
浏览器对vh/vw单元的支持是IE9 +请参阅canIuse以获取更多信息
for*_*rgo 26
我已经找到了使用CSS执行此操作的方法,但您必须小心,因为它可能会根据您自己的网站流量而改变.我已经完成了它,以便在我的网站的流体宽度部分内嵌入具有恒定宽高比的视频.
假设您有这样的嵌入式视频:
<object>
<param ... /><param ... />...
<embed src="..." ...</embed>
</object>
Run Code Online (Sandbox Code Playgroud)
然后,您可以将所有内容放在带有"视频"类的div中.此视频类可能是您网站中的流媒体元素,因此它本身没有直接的高度限制,但是当您调整浏览器大小时,它将根据网站的流量改变宽度.这可能是您在保持视频的某个宽高比时可能尝试获取嵌入视频的元素.
为了做到这一点,我在"视频"类div中的嵌入对象之前放置了一个图像.
!重要的是,图像具有您希望保持的正确宽高比.此外,请确保图像的大小至少与您期望的视频(或任何维持AR的大小)一样大,以便根据您的布局获得.这将避免在调整百分比大小时图像分辨率中的任何潜在问题.例如,如果您想保持3:2的宽高比,请不要只使用3px x 2px图像.它可能在某些情况下有效,但我没有测试过,它可能是一个好主意,可以避免.
您可能应该已经为网站的流体元素定义了这样的最小宽度.如果没有,最好这样做是为了避免在浏览器窗口太小时关闭元素或重叠元素.在某些时候最好有一个滚动条.网页应该获得的最小宽度约为600像素(包括任何固定宽度的列),因为除非您正在处理适合手机的网站,否则屏幕分辨率不会变小.!
我使用了一个完全透明的png,但如果你做得对,我真的认为它最终无关紧要.像这样:
<div class="video">
<img class="maintainaspectratio" src="maintainaspectratio.png" />
<object>
<param ... /><param ... />...
<embed src="..." ...</embed>
</object>
</div>
Run Code Online (Sandbox Code Playgroud)
现在您应该能够添加类似于以下内容的CSS:
div.video { ...; position: relative; }
div.video img.maintainaspectratio { width: 100%; }
div.video object { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; }
div.video embed {width: 100%; height: 100%; }
Run Code Online (Sandbox Code Playgroud)
确保您还删除了通常附带复制/粘贴嵌入代码的对象和嵌入标记中的任何显式高度或宽度声明.
它的工作方式取决于视频类元素的位置属性和您想要保持一定宽高比的项目.它利用了在元素中调整大小时图像保持其正确宽高比的方式.它告诉视频类元素中的任何其他内容,通过强制其宽度/高度为图像调整的视频类元素的100%,充分利用动态图像提供的不动产.
很酷,嗯?
您可能需要稍微使用它来使其与您自己的设计一起工作,但这实际上对我来说效果非常好.一般的概念就在那里.
Flo*_*sch 16
艾略特激励我使用这个解决方案 - 谢谢:
aspectratio.png
是一个完全透明的PNG文件,其大小与首选宽高比相同,在我的情况下为30x10像素.
<div class="eyecatcher">
<img src="/img/aspectratio.png"/>
</div>
Run Code Online (Sandbox Code Playgroud)
.eyecatcher img {
width: 100%;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url(../img/autoresized-picture.jpg);
}
Run Code Online (Sandbox Code Playgroud)
请注意: background-size
css3功能可能无法与目标浏览器配合使用.您可以检查互操作性(fe在caniuse.com上).
Ada*_*iec 16
使用 CSSaspect-ratio
属性
https://caniuse.com/#search=aspect-ratio
如果您有兴趣如何使用它 - 请看下面的超级简单示例
.yourClass {
aspect-ratio: 4/3;
}
Run Code Online (Sandbox Code Playgroud)
nab*_*own 14
要添加到Web_Designer的答案,<div>
将具有75%的包含元素宽度的高度(完全由底部填充组成).这是一个很好的总结:http://mattsnider.com/css-using-percent-for-margin-and-padding/.我不确定为什么会这样,但事实就是如此.
如果您希望div的宽度不是100%,则需要另一个包装div来设置宽度:
div.ar-outer{
width: 60%; /* container; whatever width you want */
margin: 0 auto; /* centered if you like */
}
div.ar {
width:100%; /* 100% of width of container */
padding-bottom: 75%; /* 75% of width of container */
position:relative;
}
div.ar-inner {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
Run Code Online (Sandbox Code Playgroud)
我最近使用类似于Elliot的图像技巧,允许我使用CSS媒体查询根据设备分辨率提供不同的徽标文件,但仍然按比例按比例缩放<img>
(我将徽标设置为背景图像为透明.png具有正确的宽高比).但是Web_Designer的解决方案会为我节省一个http请求.
Tia*_*ago 14
aspect-ratio
CSS 属性(自 Chrome 88、Safari 15 和 Firefox 89 起支持。)
<div class='demo'></div>
Run Code Online (Sandbox Code Playgroud)
.demo {
background: black;
width: 500px;
aspect-ratio: 4/3;
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*c A 12
正如在w3schools.com上所述并在此接受的答案中有所重申,填充值为百分比(强调我的):
以包含元素宽度的百分比指定填充
Ergo,保持16:9宽高比的响应式DIV的正确示例如下:
CSS
.parent {
position: relative;
width: 100%;
}
.child {
position: relative;
padding-bottom: calc(100% * 9 / 16);
}
.child > div {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
Run Code Online (Sandbox Code Playgroud)
HTML
<div class="parent">
<div class="child">
<div>Aspect is kept when resizing</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
wen*_*ner 11
由于@ web-tiki已经显示了使用vh
/的方法vw
,我还需要一种在屏幕中居的方法,这里是9:16肖像的片段代码.
.container {
width: 100vw;
height: calc(100vw * 16 / 9);
transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2));
}
Run Code Online (Sandbox Code Playgroud)
translateY
将这个中心保留在屏幕上.calc(100vw * 16 / 9)
预计9月16日的高度.(100vw * 16 / 9 - 100vh)
是溢出高度,因此,拉起overflow height/2
将使其保持在屏幕中心.
对于风景,并保持16:9,你显示使用
.container {
width: 100vw;
height: calc(100vw * 9 / 16);
transform: translateY(calc((100vw * 9 / 16 - 100vh) / -2));
}
Run Code Online (Sandbox Code Playgroud)
9/16的比例很容易改变,不需要预定义100:56.25
或100:75
.如果你想先确保高度,你应该切换宽度和高度,例如height:100vh;width: calc(100vh * 9 / 16)
9:16的肖像.
如果您想要适应不同的屏幕尺寸,您可能也会感兴趣
@media (orientation: portrait)
/@media (orientation: landscape)
portrait
/ landscape
更改比率.基于你的解决方案,我已经做了一些技巧:
当您使用它时,您的HTML将是唯一的
<div data-keep-ratio="75%">
<div>Main content</div>
</div>
Run Code Online (Sandbox Code Playgroud)
以这种方式使用它:CSS:
*[data-keep-ratio] {
display: block;
width: 100%;
position: relative;
}
*[data-keep-ratio] > * {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
Run Code Online (Sandbox Code Playgroud)
和js(jQuery)
$('*[data-keep-ratio]').each(function(){
var ratio = $(this).data('keep-ratio');
$(this).css('padding-bottom', ratio);
});
Run Code Online (Sandbox Code Playgroud)
有了这个,你只需将attr设置data-keep-ratio
为高度/宽度即可.
这是对已接受答案的改进:
.box {
margin-top: 1em;
margin-bottom: 1em;
background-color: #CCC;
}
.fixed-ar::before {
content: "";
float: left;
width: 1px;
margin-left: -1px;
}
.fixed-ar::after {
content: "";
display: table;
clear: both;
}
.fixed-ar-16-9::before {
padding-top: 56.25%;
}
.fixed-ar-3-2::before {
padding-top: 66.66%;
}
.fixed-ar-4-3::before {
padding-top: 75%;
}
.fixed-ar-1-1::before {
padding-top: 100%;
}
.width-50 {
display: inline-block;
width: 50%;
}
.width-20 {
display: inline-block;
width: 20%;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box fixed-ar fixed-ar-16-9">16:9 full width</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-3-2 width-20">3:2</div>
<div class="box fixed-ar fixed-ar-4-3 width-20">4:3</div>
<div class="box fixed-ar fixed-ar-1-1 width-20">1:1</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>
Run Code Online (Sandbox Code Playgroud)
你可以使用svg.使容器/包装器位置相对,将svg放在静止位置,然后放置绝对定位的内容(顶部:0;左:0;右:0;底部:0;)
16:9比例的示例:
image.svg :(可以在src中内联)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 9" width="16" height="9"/>
Run Code Online (Sandbox Code Playgroud)
CSS:
.container {
position: relative;
}
.content {
position: absolute;
top:0; left:0; right:0; bottom:0;
}
Run Code Online (Sandbox Code Playgroud)
HTML:
<div class="container">
<img style="width: 100%" src="image.svg" />
<div class="content"></div>
</div>
Run Code Online (Sandbox Code Playgroud)
请注意,内联svg似乎不起作用,但您可以对svg进行urlencode并将其嵌入到img src属性中,如下所示:
<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%209%22%20width%3D%2216%22%20height%3D%229%22%2F%3E" style="width: 100%;" />
Run Code Online (Sandbox Code Playgroud)
实际上,高票数的答案是一个非常好的解决方案,但是有一个新的 CSS 功能,名称是aspect-ratio
.
它可以像这样使用:
.someClass {
width: 100%;
aspect-ratio: 4/3;
}
Run Code Online (Sandbox Code Playgroud)
它会自动确定其高度,但请参阅兼容性表:
如果浏览器支持对您的项目很重要,请不要使用它。使用padding-bottom
技术。
虽然大多数答案都非常酷,但大多数答案都要求图像已经正确调整大小......其他解决方案仅适用于宽度并且不关心可用高度,但有时您也希望内容适合特定高度.
我试图将它们结合在一起以带来一个完全可移植和可重新调整大小的解决方案......诀窍是使用自动缩放图像但使用内联 svg 元素而不是使用预渲染的图像或任何形式的第二个 HTTP 请求...
div.holder{
background-color:red;
display:inline-block;
height:100px;
width:400px;
}
svg, img{
background-color:blue;
display:block;
height:auto;
width:auto;
max-width:100%;
max-height:100%;
}
.content_sizer{
position:relative;
display:inline-block;
height:100%;
}
.content{
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
background-color:rgba(155,255,0,0.5);
}
Run Code Online (Sandbox Code Playgroud)
<div class="holder">
<div class="content_sizer">
<svg width=10000 height=5000 />
<div class="content">
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
请注意,我在 SVG 的宽度和高度属性中使用了大值,因为它需要大于最大预期尺寸,因为它只能缩小。该示例使 div 的比例为 10:5
我偶然发现了一个使用<svg>
和的智能解决方案display:grid
。
网格元素允许您使用两个(或多个)元素占据相同的空间,而无需指定哪个元素来设置高度。这意味着,开箱即用的是更高的比例。
这意味着您可以按原样使用它,因为当您知道内容永远不会高到无法填满整个“比例”时,您只是在寻找一种将内容放置在此空间中的方法(即,将内容在两个方向上居中放置)
display:flex; align-items:center; justify-content:center
)。
它与使用<img>
具有display:block
和预定比例的透明胶片几乎相同,除了<svg>
它更轻巧且易于修改(根据需要以响应方式更改比例)。
<div class="ratio">
<svg viewBox="0 0 1 1"></svg>
<div>
I'm square
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
<div class="ratio">
<svg viewBox="0 0 1 1"></svg>
<div>
I'm square
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
您需要做的就是更改<svg>
s的比率:
<svg viewBox="0 0 4 3"></svg>
<svg viewBox="0 0 16 9"></svg>
看到它的工作:
.ratio {
display: grid;
}
.ratio > * {
grid-area: 1/1/1/1;
}
Run Code Online (Sandbox Code Playgroud)
.ratio {
display: grid;
}
.ratio > * {
grid-area: 1/1/1/1;
}
/* below code NOT needed for setting the ratio
* I just wanted to mark it visually
* and center contents
*/
.ratio div {
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
Run Code Online (Sandbox Code Playgroud)
如果您需要一种解决方案,其中不允许content元素设置更高的比例(隐藏或自动溢出),则需要position:relative
在网格和position:absolute; height:100%; overflow-y: auto;
内容上进行设置。例:
<div class="ratio">
<svg viewBox="0 0 7 1"></svg>
<div>
Fixed ratio 7:1
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
.ratio {
display: grid;
position: relative;
}
.ratio > * {
grid-area: 1/1/1/1;
}
.ratio > div {
height: 100%;
overflow-y: auto;
position: absolute;
/* the rest is not needed */
border: 1px solid red;
padding: 0 1rem;
}
Run Code Online (Sandbox Code Playgroud)
就我而言,SCSS是最好的解决方案。使用数据属性:
[data-aspect-ratio] {
display: block;
max-width: 100%;
position: relative;
&:before {
content: '';
display: block;
}
> * {
display: block;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
}
[data-aspect-ratio="3:1"]:before {
padding-top: 33.33%;
}
[data-aspect-ratio="2:1"]:before {
padding-top: 50%;
}
[data-aspect-ratio="16:9"]:before {
padding-top: 56.25%;
}
[data-aspect-ratio="3:2"]:before {
padding-top: 66.66%;
}
[data-aspect-ratio="4:3"]:before {
padding-top: 75%;
}
[data-aspect-ratio="1:1"]:before {
padding-top: 100%;
}
[data-aspect-ratio="3:4"]:before {
padding-top: 133.33%;
}
[data-aspect-ratio="2:3"]:before {
padding-top: 150%;
}
[data-aspect-ratio="9:16"]:before {
padding-top: 177.77%;
}
[data-aspect-ratio="1:2"]:before {
padding-top: 200%;
}
[data-aspect-ratio="1:3"]:before {
padding-top: 300%;
}
Run Code Online (Sandbox Code Playgroud)
例如 :
<div data-aspect-ratio="16:9"><iframe ...></iframe></div>
Run Code Online (Sandbox Code Playgroud)
如果您想在纵向或横向视图的视口内放置一个正方形(尽可能大,但没有任何东西粘在外面),请在使用vw
/ vh
onorientation portrait
/之间切换landscape
:
@media (orientation:portrait ) {
.square {
width :100vw;
height:100vw;
}
}
@media (orientation:landscape) {
.square {
width :100vh;
height:100vh;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过使用 SVG 来实现这一点。
这取决于具体情况,但在某些情况下它确实很有用。作为一个例子-可以设置background-image
不设置固定高度或者用它来嵌入YouTube<iframe>
与比16:9
和position:absolute
等
对于3:2
比率设置viewBox="0 0 3 2"
等。
例子:
div{
background-color:red
}
svg{
width:100%;
display:block;
visibility:hidden
}
.demo-1{width:35%}
.demo-2{width:20%}
Run Code Online (Sandbox Code Playgroud)
<div class="demo-1">
<svg viewBox="0 0 3 2"></svg>
</div>
<hr>
<div class="demo-2">
<svg viewBox="0 0 3 2"></svg>
</div>
Run Code Online (Sandbox Code Playgroud)
我找到了一些更新鲜的方法来解决这个案例。此解决方案是 anypadding-bottom
方法的后代,但没有任何子项position: absolute
,只需使用display: grid;
和伪元素。
这里我们有.ratio::before
good old padding-bottom: XX%
and grid-area: 1 / 1 / 1 / 1;
,它强制伪元素保持在网格中的位置。虽然这里我们width: 0;
要通过这个来防止main元素溢出(z-index
这里我们冷用,但是这个比较短)。
并且我们的主要元素与.ratio > *:first-child
具有相同的位置.ratio::before
,即grid-area: 1 / 1 / 1 / 1;
,因此它们共享相同的网格单元位置。现在我们可以在我们的 div 中放入任何内容,而伪元素就是决定宽高比的元素。更多关于grid-area。
.ratio {
display: grid;
grid-template-columns: 1fr;
max-width: 200px; /* just for instance, can be 100% and depends on parent */
}
.ratio::before {
content: '';
width: 0;
padding-bottom: calc(100% / (16/9)); /* here you can place any ratio */
grid-area: 1 / 1 / 1 / 1;
}
.ratio>*:first-child {
grid-area: 1 / 1 / 1 / 1; /* the same as ::before */
background: rgba(0, 0, 0, 0.1); /* just for instance */
}
Run Code Online (Sandbox Code Playgroud)
<div class="ratio">
<div>16/9</div>
</div>
Run Code Online (Sandbox Code Playgroud)
尽管您可以使用 CSS val 并使用style
属性将比率放在 HTML 中。也适用display: inline-grid
。
.ratio {
display: inline-grid;
grid-template-columns: 1fr;
width: 200px; /* just for instance, can be 100% and depends on parent */
margin-right: 10px; /* just for instance */
}
.ratio::before {
content: '';
width: 0;
padding-bottom: calc(100% / (var(--r))); /* here you can place any ratio */
grid-area: 1 / 1 / 1 / 1;
}
.ratio>*:first-child {
grid-area: 1 / 1 / 1 / 1; /* the same as ::before */
background: rgba(0, 0, 0, 0.1); /* just for instance */
}
Run Code Online (Sandbox Code Playgroud)
<div class="ratio" style="--r: 4/3;">
<div>4/3</div>
</div>
<div class="ratio" style="--r: 16/9;">
<div>16/9</div>
</div>
Run Code Online (Sandbox Code Playgroud)
假设您有 2 个 div,外部 div 是一个容器,内部可以是您需要保持其比例的任何元素(img 或 youtube iframe 或其他)
html 看起来像这样:
<div class='container'>
<div class='element'>
</div><!-- end of element -->
<div><!-- end of container -->
Run Code Online (Sandbox Code Playgroud)
假设您需要保持“元素”比率 => 4 比 1 或 2 比 1 ...
CSS 看起来像这样
.container{
position: relative;
height: 0
padding-bottom : 75% /* for 4 to 3 ratio */ 25% /* for 4 to 1 ratio ..*/
}
.element{
width : 100%;
height: 100%;
position: absolute;
top : 0 ;
bottom : 0 ;
background : red; /* just for illustration */
}
Run Code Online (Sandbox Code Playgroud)
当以 % 指定时,填充是根据宽度而不是高度来计算的。..所以基本上你的宽度是多少并不重要,高度总是根据它来计算的。这将保持比例。
小智 5
我想分享我的解决方案,其中我有一个img
-tag 填充特定的纵横比。background
由于缺乏对 CMS 的支持,我无法使用,而且我不喜欢使用像这样的样式标签:<img style="background:url(...)" />
. 此外,宽度为 100%,因此不需要像在某些解决方案中那样将其设置为固定大小。它将响应扩展!
.wrapper {
width: 50%;
}
.image-container {
position: relative;
width: 100%;
}
.image-container::before {
content: "";
display: block;
}
.image-container img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.ratio-4-3::before {
padding-top: 75%;
}
.ratio-3-1::before {
padding-top: calc(100% / 3);
}
.ratio-2-1::before {
padding-top: 50%;
}
Run Code Online (Sandbox Code Playgroud)
<div class="wrapper"> <!-- Just to make things a bit smaller -->
<p>
Example of an 4:3 aspect ratio, filled by an image with an 1:1 ratio.
</p>
<div class="image-container ratio-4-3"> <!-- Lets go for a 4:3 aspect ratio -->
<img src="https://placekitten.com/1000/1000/" alt="Kittens!" />
</div>
<p>
Just place other block elements around it; it will work just fine.
</p>
</div>
Run Code Online (Sandbox Code Playgroud)