我想创建一个div,它可以随着窗口宽度的变化而改变宽度/高度。
是否有任何CSS3规则允许高度根据宽度变化,同时保持其纵横比?
我知道我可以通过JavaScript做到这一点,但我更喜欢只使用CSS。
我想创建一个div,它可以随着窗口宽度的变化而改变宽度/高度。
是否有任何CSS3规则允许高度根据宽度变化,同时保持其纵横比?
我知道我可以通过JavaScript做到这一点,但我更喜欢只使用CSS。
当前回答
我遇到过这个问题很多次,所以我为它做了一个JS解决方案。这基本上是根据你指定的元素宽度比例来调整domElement的高度。你可以这样使用它:
<格比=“4x3”></div>
请注意,因为它正在设置元素的高度,元素应该是一个display:block或display:inline-block。
https://github.com/JeffreyArts/html-ratio-component
其他回答
感谢大家的贡献,我将在这里添加我的解决方案,这主要是通过重复已接受的答案来实现的。我喜欢这种方法的主要原因是没有不必要的DOM,因为我在填充之前使用:。
@card-standard-line-height: 21px;
@card-standard-title-line-height: 22.5px;
@16to9percentage: 56.25%;
.overflow {
background-color: inherit;
/* stylelint-disable property-no-unknown */
box-orient: vertical;
-moz-box-orient: vertical;
-webkit-box-orient: vertical;
/* stylelint-enable */
color: inherit;
display: box;
display: -webkit-box;
display: -moz-box;
max-width: 100%;
overflow: hidden;
position: relative;
text-overflow: -o-ellipsis-lastline;
text-overflow: ellipsis;
}
* {
box-sizing: border-box;
}
body {
padding: 2rem;
}
.card {
color: #fff;
height: auto;
max-width: 100%;
min-width: unset;
position: relative;
h2 {
font: 18px / 22.5px bold;
}
p {
font: 14px / 21px normal;
}
&-16to9 {
.badge {
color: white;
display:flex;
background-color: red;
justify-content: baseline;
padding: 16px 32px 12px 16px;
position: absolute;
right: 0;
top: 16px;
z-index: 2;
span {
font: 14px / 14px bold;
}
}
// look at this https://css-tricks.com/aspect-ratio-boxes/
.card {
&_description {
max-height: @card-standard-line-height * 1;
// Number of allowable lines in layout
-webkit-line-clamp: 1;
}
&_image,
&_info {
bottom: 0;
height: 100%;
max-height: 100%;
min-height: 100%;
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: 0;
}
&_info {
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 24px;
z-index: 2;
}
&_title {
max-height: @card-standard-title-line-height * 2;
// Number of allowable lines in layout
-webkit-line-clamp: 2;
}
}
&:after,
&:before {
content: "";
display: block;
}
&:after {
background: rgba(0, 0, 0, 0);
background: linear-gradient(0deg, rgba(0, 0, 0, 1) 16%, rgba(0, 0, 0, 0) 100%);
bottom: 0;
height: 100%;
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: 1;
}
&:before {
padding-bottom: @16to9percentage;
}
}
}
https://codepen.io/augur/pen/GRNGLZv?editors=0100
只需创建一个包装器<div>,并为padding-bottom设置一个百分比值,如下所示:
.demoWrapper { 填充:10 px; 背景:白色; box-sizing: border-box; 调整:水平; 边框:1px虚线; 溢出:汽车; max-width: 100%; 高度:calc(100vh - 16px); } div { 宽度:100%; padding-bottom: 75%; 背景:黄金;/** <——用于演示**/ } < 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/vh:
@media (orientation:portrait ) {
.square {
width :100vw;
height:100vw;
}
}
@media (orientation:landscape) {
.square {
width :100vh;
height:100vh;
}
}
保持纵横比的一个简单方法,使用canvas元素。
尝试调整下面的div的大小,看看它的作用。
对我来说,这种方法效果最好,所以我把它分享给其他人,这样他们也能从中受益。
.cont { 边框:5px纯蓝色; 位置:相对; 宽度:300 px; 填充:0; 保证金:5 px; 调整:水平; 溢出:隐藏; } .ratio { 宽度:100%; 保证金:0; 显示:块; } .content { Background-color: rgba(255, 0,0, 0.5); 位置:绝对的; 上图:0; 左:0; 宽度:100%; 高度:100%; 保证金:0; } < div class = "跟" > <canvas class="ratio" width="16" height="9"></canvas> <div class="content">我是16:9</div> < / div >
也适用于动态高度!
.cont { 边框:5px纯蓝色; 位置:相对; 身高:170 px; 填充:0; 保证金:5 px; 调整:垂直; 溢出:隐藏; 显示:inline-block;/*所以div不会自动扩展到最大宽度*/ } .ratio { 高度:100%; 保证金:0; 显示:块; } .content { Background-color: rgba(255, 0,0, 0.5); 位置:绝对的; 上图:0; 左:0; 宽度:100%; 高度:100%; 保证金:0; } < div class = "跟" > <canvas class="ratio" width="16" height="9"></canvas> <div class="content">我是16:9</div> < / div >
新的纵横比标签会很棒,但它打乱了我的divs的定位。 填充包装器div的传统解决方案是有效的,但只能根据父类或视口的宽度调整大小,当高度是限制因素时,这就产生了问题。
我发现min()函数非常有用,并调整了传统的方法,如下所示:
身体{ background-image: linear-gradient(到右上,#FFE6B5, #B3CEBF); 填充:0; 保证金:0自动; overflow-y:隐藏;/*这是为了避免在视口高度小于纵横比要求*/时滚动 } .wrapper { 位置:相对; 宽度:100大众; max-height: 100 vh; } .sixteen-by-nine。宽高比{ 衬底:56.25% /* 9:16比*/ } .content { 位置:绝对的; 上图:0;底部:0;左:0;右:0; 背景颜色:绿色 } .centered { 位置:绝对的; 左:50%; 上图:50%; 转换:翻译(-50%,-50%); 高度:100%; 宽度:min(177.8vh, 100%);/*这总是在视口中保持16:9的比例*/ 字体大小:最小(1.7 3 vh,大众);/*如果你也对缩放字体大小*/感兴趣 背景颜色:蓝色 } 身体< > < div class = "包装" > <div class=" 16x9纵横比"></div> <div class="content" > < div class = "集中" > <!——东西在这里——> < / div > < / div > < / div > 身体< / >