我想创建一个div
可以随窗口宽度变化而改变其宽度/高度的。
是否有任何CSS3规则可以允许高度根据宽度而改变,同时保持其长宽比?
我知道我可以通过JavaScript来做到这一点,但我宁愿只使用CSS。
我想创建一个div
可以随窗口宽度变化而改变其宽度/高度的。
是否有任何CSS3规则可以允许高度根据宽度而改变,同时保持其长宽比?
我知道我可以通过JavaScript来做到这一点,但我宁愿只使用CSS。
Answers:
只需<div>
使用百分比值创建包装器padding-bottom
,如下所示:
div {
width: 100%;
padding-bottom: 75%;
background: gold; /** <-- For the demo **/
}
/* demonstration purposed only : non-essential */
.demoWrapper {
padding: 10px;
background: white;
box-sizing: border-box;
resize: horizontal;
border: 1px dashed;
overflow: auto;
max-width: 100%;
height: calc(100vh - 16px);
}
<div class="demoWrapper">
<div></div>
</div>
它将导致<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%
将内容放在div中:
为了保持div的长宽比并防止其内容拉伸,您需要添加一个绝对定位的子级,并使用以下方法将其拉伸到包装器的边缘:
div.stretchy-wrapper {
position: relative;
}
div.stretchy-wrapper > div {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
vw
单位:您可以将vw
单位用于元素的宽度和高度。这样可以根据视口宽度保留元素的长宽比。
vw:视口宽度的1/100。[ MDN ]
另外,您也可以使用vh
视口高度,甚至使用vmin
/ vmax
来使用视口尺寸的小/大(此处讨论)。
对于其他长宽比,可以使用下表根据元素的宽度计算高度的值:
aspect ratio | multiply width by
-----------------------------------
1:1 | 1
1:3 | 3
4:3 | 0.75
16:9 | 0.5625
body {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
div {
width: 23vw;
height: 23vw;
margin: 0.5vw auto;
background: gold;
}
<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>
这是此演示的小提琴,这是一种使响应的正方形网格具有垂直和水平居中内容的解决方案。
IE9 +支持vh / vw单位的浏览器,请参见canIuse了解更多信息
width:50%
且height:50vw
高度比宽度高一点时,并非完全是1:1的比例。有任何想法吗?
我找到了一种使用CSS进行此操作的方法,但是您必须小心,因为它可能会根据您自己的网站的流量而变化。我这样做是为了将具有恒定纵横比的视频嵌入到我的网站的宽度部分中。
假设您有一个这样的嵌入式视频:
<object>
<param ... /><param ... />...
<embed src="..." ...</embed>
</object>
然后,您可以将其全部放入带有“视频”类的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>
现在,您应该能够添加类似于以下内容的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%; }
确保您还删除了对象内的任何明确的高度或宽度声明,并嵌入了通常复制/粘贴嵌入代码随附的标签。
它的工作方式取决于视频类元素的位置属性,并且您想要的项目保持一定的纵横比。它利用了在元素中调整大小时图像将保持其适当纵横比的方式。它通过将动态图像的宽度/高度强制为要由图像调整的视频类别元素的100%,告诉视频类元素中的其他内容充分利用动态图像提供的空间。
很酷吧?
您可能需要尝试一下才能使其与您自己的设计一起使用,但这实际上对我来说效果很好。这里有一般概念。
Elliot启发了我这个解决方案-感谢:
aspectratio.png
是一个完全透明的PNG文件,具有您喜欢的长宽比的大小,在我的情况下为30x10像素。
<div class="eyecatcher">
<img src="/img/aspectratio.png"/>
</div>
.eyecatcher img {
width: 100%;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url(../img/autoresized-picture.jpg);
}
请注意:这 background-size
是css3功能,可能无法与您的目标浏览器一起使用。您可以检查互操作性(位于caniuse.com上)。
为了增加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;
}
我最近使用了类似于Elliot的图像技巧的方法,使我可以使用CSS媒体查询根据设备分辨率提供不同的徽标文件,但仍然可以像<img>
自然地那样按比例缩放(我将徽标作为背景图像设置为透明的.png具有正确的宽高比)。但是Web_Designer的解决方案可以为我节省一个http请求。
如在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;
}
的HTML
<div class="parent">
<div class="child">
<div>Aspect is kept when resizing</div>
</div>
</div>
由于@ web-tiki已经显示了使用vh
/ 的方式vw
,因此我也需要在屏幕上居中的方式,这是9:16人像的代码段。
.container {
width: 100vw;
height: calc(100vw * 16 / 9);
transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2));
}
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));
}
9/16的比例很容易更改,无需预定义100:56.25
或设置100:75
。如果要首先确保高度,则应切换宽度和高度,例如height:100vh;width: calc(100vh * 9 / 16)
9:16纵向。
如果您想适应不同的屏幕尺寸,您可能也会感兴趣
这是对已接受答案的改进:
.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%;
}
<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>
我偶然发现了一个使用<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>
.ratio {
display: grid;
}
.ratio > * {
grid-area: 1/1/1/1;
}
您需要做的就是更改<svg>
s的比率:
<svg viewBox="0 0 4 3"></svg>
<svg viewBox="0 0 16 9"></svg>
看到它的工作:
如果您需要一种解决方案,其中不允许content元素设置更高的比例(隐藏或自动溢出),则需要position:relative
在网格和position:absolute; height:100%; overflow-y: auto;
内容上进行设置。例:
根据您的解决方案,我做了一些技巧:
使用它时,HTML仅
<div data-keep-ratio="75%">
<div>Main content</div>
</div>
要以这种方式使用它,请执行以下操作:CSS:
*[data-keep-ratio] {
display: block;
width: 100%;
position: relative;
}
*[data-keep-ratio] > * {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
和js(jQuery)
$('*[data-keep-ratio]').each(function(){
var ratio = $(this).data('keep-ratio');
$(this).css('padding-bottom', ratio);
});
有了这个,您只需将attr设置data-keep-ratio
为height / width即可。
data-keep-ratio
不keep-ratio
使用得到它的价值$(this).data('keep-ratio');
您可以使用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"/>
CSS:
.container {
position: relative;
}
.content {
position: absolute;
top:0; left:0; right:0; bottom:0;
}
HTML:
<div class="container">
<img style="width: 100%" src="image.svg" />
<div class="content"></div>
</div>
请注意,内联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%;" />
就我而言,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%;
}
例如 :
<div data-aspect-ratio="16:9"><iframe ...></iframe></div>
[data-aspect-ratio]
属性选择器提供给您的CSS。
虽然大多数答案都很酷,但是大多数答案都需要正确调整图像大小……其他解决方案仅适用于宽度,并不关心可用的高度,但有时您也希望将内容调整为一定的高度。
我试图将它们结合在一起以提供一个完全可移植且可调整大小的解决方案...诀窍是用于自动缩放图像,但使用嵌入式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);
}
<div class="holder">
<div class="content_sizer">
<svg width=10000 height=5000 />
<div class="content">
</div>
</div>
</div>
请注意,我在SVG的width和height属性中使用了较大的值,因为它必须大于最大预期大小,因为它只能收缩。该示例使div的比例为10:5
只是想法或技巧。
div {
background-color: blue;
width: 10%;
transition: background-color 0.5s, width 0.5s;
font-size: 0;
}
div:hover {
width: 20%;
background-color: red;
}
img {
width: 100%;
height: auto;
visibility: hidden;
}
<div>
<!-- use an image with target aspect ratio. sample is a square -->
<img src="http://i.imgur.com/9OPnZNk.png" />
</div>
html看起来像这样:
<div class='container'>
<div class='element'>
</div><!-- end of element -->
假设您需要保持“元素”的比例
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 */
}
当以百分比指定填充时,填充基于宽度而不是高度计算。..所以基本上你都不会以此为基础计算宽度和高度的大小。这将保持比率。
我想分享我的解决方案,其中有一个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%;
}
<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>
您可以使用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%}
<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>
您可以使用磁通布局(FWD)。
https://zh.wikipedia.org/wiki/Adaptive_web_design
它将缩放和维护布局,这有点复杂,但允许页面调整大小而无需推送(RWD)之类的内容。
看起来像是响应式的,但它正在扩展。https://www.youtube.com/watch?v=xRcBMLI4jbg
您可以在此处找到CSS缩放公式:
对我来说,这种方法效果最好,因此我正在与他人共享它,以便他们也可以从中受益。
.cont {
border: 5px solid blue;
position: relative;
width: 300px;
padding: 0;
margin: 5px;
resize: horizontal;
overflow: hidden;
}
.ratio {
width: 100%;
margin: 0;
display: block;
}
.content {
background-color: rgba(255, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
margin: 0;
}
<div class="cont">
<canvas class="ratio" width="16" height="9"></canvas>
<div class="content">I am 16:9</div>
</div>
.cont {
border: 5px solid blue;
position: relative;
height: 170px;
padding: 0;
margin: 5px;
resize: vertical;
overflow: hidden;
display: inline-block; /* so the div doesn't automatically expand to max width */
}
.ratio {
height: 100%;
margin: 0;
display: block;
}
.content {
background-color: rgba(255, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
margin: 0;
}
<div class="cont">
<canvas class="ratio" width="16" height="9"></canvas>
<div class="content">I am 16:9</div>
</div>
我使用了新的解决方案。
.squares{
width: 30vw
height: 30vw
与主要纵横比
.aspect-ratio
width: 10vw
height: 10vh
但是,这是相对于整个视口而言的。因此,如果需要的div是视口宽度的30%,则可以改用30vw,由于知道了宽度,因此可以使用calc和vw单位在高度上重复使用它们。
好吧,我们最近获得了aspect-ratio
在CSS中使用该属性的功能。
https://twitter.com/Una/status/1260980901934137137345/photo/1
注意:支持还不是最好的...