Flex 布局和响应式设计面板

Posted

技术标签:

【中文标题】Flex 布局和响应式设计面板【英文标题】:Flex layout and responsive design panels 【发布时间】:2020-01-08 10:35:10 【问题描述】:

我正在尝试设计一个可重用的组件来显示 Web 的产品信息 - 我已经在固定宽度的 div 中进行了模拟,但现在需要使其具有响应性 - 我一直在使用 flex 布局。

创建了一个小提琴来演示问题

https://jsfiddle.net/0sz523Lj/5/

该组件包含整个容器的图像,然后是位于部分照片上的左对齐不透明面板,其中包含产品详细信息。主照片高度应确定不透明度面板的高度,因为主照片将拉伸以填充 100% 宽度,显然高度会调整以保持照片成比例。调整屏幕大小后,不透明度面板现在应该占据照片的高度,并且内容会缩放以适应。

此面板由顶部的产品名称、简介、缩略图、价格和几个按钮组成,用于了解更多信息或购买。

除了简介之外的所有内容都是固定大小的 - 可能产品名称可以分成两行或一行,但简介是主要的。目前,如果您将屏幕变大,则主图像会变大,不透明度面板的宽度是固定的,因此只会更改其高度,但是最终会在简介下方出现大量空白,因为它不足以填充不透明度控制板。如果缩小屏幕,blurb 不适合容器的高度,并且 opacity 容器会溢出图片高度。

我想知道以响应方式执行此操作的最佳方法是什么 - 我只有两个想法。一种是根据屏幕大小更改字体大小,使简介适合左侧容器的相同固定部分。这感觉不对。唯一的其他选择是使不透明度面板本身根据屏幕尺寸改变宽度。

实际上,您希望代码适合标题、缩略图、成本和购买按钮,然后根据您调整屏幕大小的方式说 - 这决定了不透明度面板的高度,然后调整不透明度面板的宽度使内容完美契合。

我怎样才能使它完全响应?

html 代码供参考

<div class="image-container">
                <img src="https://images-na.ssl-images-amazon.com/images/I/71U%2B5KVElqL._SL1500_.jpg"  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>

【问题讨论】:

【参考方案1】:

我通过删除不必要的 div 并让一些部分更具语义性来更改 HTML。我还删除了绝对定位并将主产品图像更改为主容器上的背景。现在左边的内容可以自然地就位了。

实现完全灵活性的一种方法是让左侧容器滚动任何在屏幕较短时溢出的内容。这是通过overflow-y: scroll 实现的。

阅读 CSS 中的 cmets,阐明每一行的作用。我的答案在大多数屏幕尺寸下运行良好,但与所有这种灵活的东西一样,在极端的屏幕尺寸或纵横比下需要进行调整。

*  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>

【讨论】:

非常感谢!您能否在拇指 CSS 中解释一下“flex: 0 0 auto;”是什么?是什么意思? 还有一件事我忘了提 - 如您所见,左侧有一个购买容器。我希望产品交替出现,以便每隔一个产品在右侧有覆盖 div。这就是我使用绝对定位的目的。有没有一种简单的方法可以更改上面的 .image-buy-container-left 类,使其位于图像的右侧而不是左侧? 刚刚尝试过,但效果不佳,左侧菜单似乎保持相对固定 - 溢出从未真正被使用,只有背景图像发生变化,并且随着屏幕变大,它不会不要填满整个屏幕 - 侧面或上方/下方有间隙。更新小提琴来演示:jsfiddle.net/j41eux2q/1 flex: 0 0 autoflex-grow: 0; flex-shrink: 0; flex-basis: auto; 的简写。如果您想使用 flexbox,我强烈建议您查看这个很棒的资源:@​​987654322@ 如果你想要右边的内容,只需给 .image-container 包装器这个:justify-content: flex-end;

以上是关于Flex 布局和响应式设计面板的主要内容,如果未能解决你的问题,请参考以下文章

响应式设计1---响应式布局介绍

媒体查询视口viewport和meta标签flex布局

利用axure进行响应式自适应网站的设计

移动端和pc端,响应式设计布局

实践干货 | 你想知道的响应式设计技巧

实践干货!超实用的响应式设计技巧