弹性布局和响应式设计面板
Flex layout and responsive design panels
我正在尝试设计一个 re-usable 组件来显示 Web 产品信息 - 我已经在固定宽度的 div 中模拟了它,但现在需要让它响应 - 我一直在使用 flex 布局.
创建了一个 fiddle 来演示问题
https://jsfiddle.net/0sz523Lj/5/
该组件包含整个容器的图像,然后是左对齐的部分照片的不透明面板,其中包含产品详细信息。主照片的高度应决定不透明度面板的高度,因为主照片将拉伸以填充 100% 宽度,显然高度会调整以保持照片的比例。调整屏幕大小后,不透明度面板现在应该占据照片的高度,内容也会缩放以适合。
此面板由顶部的产品名称、简介描述、缩略图照片、价格和几个用于了解更多信息或购买的按钮组成。
除了广告宣传外,所有的都是固定尺寸的——可能产品名称可以分成两行或一行,但广告宣传是主要的。目前如果你把屏幕变大,那么主图像就会变大,不透明度面板的宽度是固定的,所以只会改变它的高度,但是你最终会在宣传语下看到大量的白色 space,因为这还不够填充不透明面板。如果缩小屏幕,广告语不适合容器的高度,不透明容器会溢出图片高度。
我想知道以响应方式执行此操作的最佳方法是什么 - 我想到了两个想法。一种是根据屏幕大小更改字体大小,因此宣传语适合左侧容器的相同固定部分。这感觉不对。唯一的其他选择是让不透明面板本身根据屏幕尺寸改变宽度。
实际上,您希望代码适合标题、缩略图、成本和购买按钮,然后根据您调整屏幕大小的方式说 - 这决定了不透明度面板的高度,然后调整了不透明面板使内容完美契合。
我怎样才能让它完全响应?
HTML代码供参考
<div class="image-container">
<img src="https://images-na.ssl-images-amazon.com/images/I/71U%2B5KVElqL._SL1500_.jpg" width="100%" vspace="0" />
<div class="image-buy-container-left">
<div class="image-container-title">
<p>Product name will go here</p>
</div>
<div class="image-container-blurb">
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
<br /><br />
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
</p>
</div>
<div class="image-container-thumbborder">
<div class="image-container-thumb">
<img src="https://us.coca-cola.com/content/dam/coke2016/page-properties-images/Coke_PageProperties.jpg" width=100% />
</div>
</div>
<div class="image-container-portion">
250ml bottle
</div>
<div class="image-container-portiondescription">
(Two serves)
</div>
<div class="image-container-price">
£13.00
</div>
<div class="image-buy-container-buttons">
<div class="image-container-button home-content__buttons ">
<a href="/ProductDetails.html" class="btn btn--stroke">
Discover
</a>
</div>
</div>
</div>
</div>
我更改了 HTML,删除了不必要的 div,并使一些部分更具语义。我还删除了绝对定位并将主要产品图像更改为主容器上的背景。现在左边的内容可以自然地就位了。
实现完全灵活性的一种方法是让左侧容器滚动屏幕较短时溢出的任何内容。这是通过 overflow-y: scroll
.
实现的
阅读 CSS 中的注释,阐明每行的作用。我的答案在大多数屏幕尺寸下运行良好,但对于所有如此灵活的东西,在极端屏幕尺寸或纵横比下需要进行调整。
* { box-sizing: border-box; } /* makes dealing with padding/width ez */
body { margin: 0; }
.image-container {
display: flex;
width: 100vw; /* fullscreen width */
height: 100vh; /* fullscreen height */
background-image: url('https://images-na.ssl-images-amazon.com/images/I/71U%2B5KVElqL._SL1500_.jpg'); /* main product image as a background */
background-repeat: no-repeat;
background-size: contain;
background-position: center center;
}
.image-buy-container-left {
background: rgba(0,0,0,0.8);
flex: 0 0 370px;
display: flex;
flex-direction: column;
justify-content: space-between; /*helps when the screen gets taller than the content */
padding: 20px; /* padding for the entire left container, no need for padding on every item inside */
text-align: center; /* text align is inherited so only need it on the container, not on every item inside */
overflow-y: auto; /* overflow if screen is shorter than content */
}
.image-container-title {
margin: 0 0 1vw; /* margin based on screen width */
font-size: 5vw; /* size based on the screen width gives a scalable font size */
letter-spacing: .4vw; /* letter-spacing based on width */
line-height: 1.125; /* always use realtive value for line-height if the size will change */
color: #fff;
}
.image-container-blurb {
color: #aaa;
line-height: 1.2;
font-size: 0.8rem;
}
.image-container-thumb {
display: block;
flex: 0 0 auto;
margin: 2vw auto;
width: 40%;
height: auto;
}
.image-container-portion {
color: #ccc;
line-height: 1.3;
font-size: 1.15rem;
}
.image-container-portiondescription {
color: #aaa;
line-height: 1.3;
font-size: .9rem;
}
.image-container-price {
color: #ddd;
line-height: 1.3;
font-size: 1.2rem;
margin: 10px 0 20px;
}
.image-buy-container-buttons {
width: 100%;
display: flex;
flex-direction: column;
}
.home-content__buttons .btn {
border-color: #225;
color: #ccc;
background: #114 !important;
margin: 0;
height: 70px;
line-height: 70px;
vertical-align: middle;
letter-spacing: .25rem;
-webkit-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
.home-content__buttons .btn:last-child {
margin-right: 0;
}
.home-content__buttons .btn:hover,
.home-content__buttons .btn:focus {
background: #ddd !important;
border-color: #888;
color: #333;
}
.btn,
button,
input[type="submit"],
input[type="reset"],
input[type="button"] {
display: inline-block;
font-family: "montserrat-medium", sans-serif;
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: .3rem;
height: 5.4rem;
line-height: calc(5.4rem - .4rem);
padding: 0 3rem;
margin: 0 .3rem 1.2rem 0;
color: #000000;
text-decoration: none;
text-align: center;
white-space: nowrap;
cursor: pointer;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
background-color: #c5c5c5;
border: .2rem solid #c5c5c5;
}
.btn:hover,
button:hover,
input[type="submit"]:hover,
input[type="reset"]:hover,
input[type="button"]:hover,
.btn:focus,
button:focus,
input[type="submit"]:focus,
input[type="reset"]:focus,
input[type="button"]:focus {
background-color: #b8b8b8;
border-color: #b8b8b8;
color: #000000;
outline: 0;
}
/* button primary
* ------------------------------------------------- */
.btn.btn--primary,
button.btn--primary,
input[type="submit"].btn--primary,
input[type="reset"].btn--primary,
input[type="button"].btn--primary {
background: #39b54a;
border-color: #39b54a;
color: #FFFFFF;
}
.btn.btn--primary:hover,
button.btn--primary:hover,
input[type="submit"].btn--primary:hover,
input[type="reset"].btn--primary:hover,
input[type="button"].btn--primary:hover,
.btn.btn--primary:focus,
button.btn--primary:focus,
input[type="submit"].btn--primary:focus,
input[type="reset"].btn--primary:focus,
input[type="button"].btn--primary:focus {
background: #33a242;
border-color: #33a242;
}
/* button modifiers
* ------------------------------------------------- */
.btn.full-width,
button.full-width {
width: 100%;
margin-right: 0;
}
.btn--medium,
button.btn--medium {
height: 5.7rem !important;
line-height: calc(5.7rem - .4rem) !important;
}
.btn--large,
button.btn--large {
height: 6rem !important;
line-height: calc(6rem - .4rem) !important;
}
.btn--stroke,
button.btn--stroke {
background: transparent !important;
border: 0.2rem solid #39b54a;
color: #39b54a;
}
.btn--stroke:hover,
button.btn--stroke:hover {
border: 0.2rem solid #000000;
color: #000000;
}
.btn--pill,
button.btn--pill {
padding-left: 3rem !important;
padding-right: 3rem !important;
border-radius: 1000px !important;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
<div class="image-container">
<div class="image-buy-container-left">
<h2 class="image-container-title">
Product name will go here
</h2>
<div class="image-container-blurb">
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
</p>
</div>
<img class="image-container-thumb" src="https://us.coca-cola.com/content/dam/coke2016/page-properties-images/Coke_PageProperties.jpg" width=100% />
<div class="image-container-portion">
250ml bottle
</div>
<div class="image-container-portiondescription">
(Two serves)
</div>
<div class="image-container-price">
£13.00
</div>
<div class="image-buy-container-buttons image-container-button home-content__buttons">
<a class="btn btn--stroke" href="/ProductDetails.html">
Discover
</a>
</div>
</div>
</div>
我正在尝试设计一个 re-usable 组件来显示 Web 产品信息 - 我已经在固定宽度的 div 中模拟了它,但现在需要让它响应 - 我一直在使用 flex 布局.
创建了一个 fiddle 来演示问题
https://jsfiddle.net/0sz523Lj/5/
该组件包含整个容器的图像,然后是左对齐的部分照片的不透明面板,其中包含产品详细信息。主照片的高度应决定不透明度面板的高度,因为主照片将拉伸以填充 100% 宽度,显然高度会调整以保持照片的比例。调整屏幕大小后,不透明度面板现在应该占据照片的高度,内容也会缩放以适合。
此面板由顶部的产品名称、简介描述、缩略图照片、价格和几个用于了解更多信息或购买的按钮组成。
除了广告宣传外,所有的都是固定尺寸的——可能产品名称可以分成两行或一行,但广告宣传是主要的。目前如果你把屏幕变大,那么主图像就会变大,不透明度面板的宽度是固定的,所以只会改变它的高度,但是你最终会在宣传语下看到大量的白色 space,因为这还不够填充不透明面板。如果缩小屏幕,广告语不适合容器的高度,不透明容器会溢出图片高度。
我想知道以响应方式执行此操作的最佳方法是什么 - 我想到了两个想法。一种是根据屏幕大小更改字体大小,因此宣传语适合左侧容器的相同固定部分。这感觉不对。唯一的其他选择是让不透明面板本身根据屏幕尺寸改变宽度。
实际上,您希望代码适合标题、缩略图、成本和购买按钮,然后根据您调整屏幕大小的方式说 - 这决定了不透明度面板的高度,然后调整了不透明面板使内容完美契合。
我怎样才能让它完全响应?
HTML代码供参考
<div class="image-container">
<img src="https://images-na.ssl-images-amazon.com/images/I/71U%2B5KVElqL._SL1500_.jpg" width="100%" vspace="0" />
<div class="image-buy-container-left">
<div class="image-container-title">
<p>Product name will go here</p>
</div>
<div class="image-container-blurb">
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
<br /><br />
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
lorem ipsum lorem ipsum lorem ipsum lorem ipsum
</p>
</div>
<div class="image-container-thumbborder">
<div class="image-container-thumb">
<img src="https://us.coca-cola.com/content/dam/coke2016/page-properties-images/Coke_PageProperties.jpg" width=100% />
</div>
</div>
<div class="image-container-portion">
250ml bottle
</div>
<div class="image-container-portiondescription">
(Two serves)
</div>
<div class="image-container-price">
£13.00
</div>
<div class="image-buy-container-buttons">
<div class="image-container-button home-content__buttons ">
<a href="/ProductDetails.html" class="btn btn--stroke">
Discover
</a>
</div>
</div>
</div>
</div>
我更改了 HTML,删除了不必要的 div,并使一些部分更具语义。我还删除了绝对定位并将主要产品图像更改为主容器上的背景。现在左边的内容可以自然地就位了。
实现完全灵活性的一种方法是让左侧容器滚动屏幕较短时溢出的任何内容。这是通过 overflow-y: scroll
.
阅读 CSS 中的注释,阐明每行的作用。我的答案在大多数屏幕尺寸下运行良好,但对于所有如此灵活的东西,在极端屏幕尺寸或纵横比下需要进行调整。
* { box-sizing: border-box; } /* makes dealing with padding/width ez */
body { margin: 0; }
.image-container {
display: flex;
width: 100vw; /* fullscreen width */
height: 100vh; /* fullscreen height */
background-image: url('https://images-na.ssl-images-amazon.com/images/I/71U%2B5KVElqL._SL1500_.jpg'); /* main product image as a background */
background-repeat: no-repeat;
background-size: contain;
background-position: center center;
}
.image-buy-container-left {
background: rgba(0,0,0,0.8);
flex: 0 0 370px;
display: flex;
flex-direction: column;
justify-content: space-between; /*helps when the screen gets taller than the content */
padding: 20px; /* padding for the entire left container, no need for padding on every item inside */
text-align: center; /* text align is inherited so only need it on the container, not on every item inside */
overflow-y: auto; /* overflow if screen is shorter than content */
}
.image-container-title {
margin: 0 0 1vw; /* margin based on screen width */
font-size: 5vw; /* size based on the screen width gives a scalable font size */
letter-spacing: .4vw; /* letter-spacing based on width */
line-height: 1.125; /* always use realtive value for line-height if the size will change */
color: #fff;
}
.image-container-blurb {
color: #aaa;
line-height: 1.2;
font-size: 0.8rem;
}
.image-container-thumb {
display: block;
flex: 0 0 auto;
margin: 2vw auto;
width: 40%;
height: auto;
}
.image-container-portion {
color: #ccc;
line-height: 1.3;
font-size: 1.15rem;
}
.image-container-portiondescription {
color: #aaa;
line-height: 1.3;
font-size: .9rem;
}
.image-container-price {
color: #ddd;
line-height: 1.3;
font-size: 1.2rem;
margin: 10px 0 20px;
}
.image-buy-container-buttons {
width: 100%;
display: flex;
flex-direction: column;
}
.home-content__buttons .btn {
border-color: #225;
color: #ccc;
background: #114 !important;
margin: 0;
height: 70px;
line-height: 70px;
vertical-align: middle;
letter-spacing: .25rem;
-webkit-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
.home-content__buttons .btn:last-child {
margin-right: 0;
}
.home-content__buttons .btn:hover,
.home-content__buttons .btn:focus {
background: #ddd !important;
border-color: #888;
color: #333;
}
.btn,
button,
input[type="submit"],
input[type="reset"],
input[type="button"] {
display: inline-block;
font-family: "montserrat-medium", sans-serif;
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: .3rem;
height: 5.4rem;
line-height: calc(5.4rem - .4rem);
padding: 0 3rem;
margin: 0 .3rem 1.2rem 0;
color: #000000;
text-decoration: none;
text-align: center;
white-space: nowrap;
cursor: pointer;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
background-color: #c5c5c5;
border: .2rem solid #c5c5c5;
}
.btn:hover,
button:hover,
input[type="submit"]:hover,
input[type="reset"]:hover,
input[type="button"]:hover,
.btn:focus,
button:focus,
input[type="submit"]:focus,
input[type="reset"]:focus,
input[type="button"]:focus {
background-color: #b8b8b8;
border-color: #b8b8b8;
color: #000000;
outline: 0;
}
/* button primary
* ------------------------------------------------- */
.btn.btn--primary,
button.btn--primary,
input[type="submit"].btn--primary,
input[type="reset"].btn--primary,
input[type="button"].btn--primary {
background: #39b54a;
border-color: #39b54a;
color: #FFFFFF;
}
.btn.btn--primary:hover,
button.btn--primary:hover,
input[type="submit"].btn--primary:hover,
input[type="reset"].btn--primary:hover,
input[type="button"].btn--primary:hover,
.btn.btn--primary:focus,
button.btn--primary:focus,
input[type="submit"].btn--primary:focus,
input[type="reset"].btn--primary:focus,
input[type="button"].btn--primary:focus {
background: #33a242;
border-color: #33a242;
}
/* button modifiers
* ------------------------------------------------- */
.btn.full-width,
button.full-width {
width: 100%;
margin-right: 0;
}
.btn--medium,
button.btn--medium {
height: 5.7rem !important;
line-height: calc(5.7rem - .4rem) !important;
}
.btn--large,
button.btn--large {
height: 6rem !important;
line-height: calc(6rem - .4rem) !important;
}
.btn--stroke,
button.btn--stroke {
background: transparent !important;
border: 0.2rem solid #39b54a;
color: #39b54a;
}
.btn--stroke:hover,
button.btn--stroke:hover {
border: 0.2rem solid #000000;
color: #000000;
}
.btn--pill,
button.btn--pill {
padding-left: 3rem !important;
padding-right: 3rem !important;
border-radius: 1000px !important;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
<div class="image-container">
<div class="image-buy-container-left">
<h2 class="image-container-title">
Product name will go here
</h2>
<div class="image-container-blurb">
<p>Lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
</p>
</div>
<img class="image-container-thumb" src="https://us.coca-cola.com/content/dam/coke2016/page-properties-images/Coke_PageProperties.jpg" width=100% />
<div class="image-container-portion">
250ml bottle
</div>
<div class="image-container-portiondescription">
(Two serves)
</div>
<div class="image-container-price">
£13.00
</div>
<div class="image-buy-container-buttons image-container-button home-content__buttons">
<a class="btn btn--stroke" href="/ProductDetails.html">
Discover
</a>
</div>
</div>
</div>