使用position:absolute,同时将其保留在文档流中

时间:2013-09-03 17:21:41

标签: html css css-position

enter image description here

这是我正在构建的页面的屏幕截图。我正在努力确保绿色按钮始终位于容器的底部。这是一段代码:

HTML

<div class="list-product-pat">
  <article>

   <!-- title, image, spec ... -->

   <div class="pricing-pat">

     <!-- the button goes here -->

   </div>
  </article>
</div>

CSS

 .list-product-pat article {
    position: relative;
    min-height: 260px;
 }

 .list-product-pat .pricing-pat {
    position: absolute;
    bottom: 0;
    width: 100%;
 }

到目前为止,没有任何问题......直到产品规格太长并且它突破了绿色按钮。

enter image description here

我想将绿色按钮保持在最底部位置,但同时如果产品标题/产品规格太长,我也希望高度延长。

在理想世界中,它应该是这样的:

enter image description here

所以我的想法是保持绝对定位,同时仍然保持在文档流程中(因此产品规格知道绿色按钮在那里并且没有突破它)。

我只需要扩展,如果规格高度太长。换句话说,如果规格处于正常高度,则不会延伸。我想避免a weird gap between the spec and the green button

有什么想法吗?

这是一个小提琴,看看我是如何做到的: http://jsfiddle.net/xaliber/xrb5U/

4 个答案:

答案 0 :(得分:5)

添加position:absolute会将其从文档流中取出,无法将其保留在文档流中。 但是,您可以将相当于按钮高度的padding-bottom添加到article容器中,这样可以防止长文本超出按钮。

.list-product-pat article {
    position: relative;
    min-height: 260px;
    padding-bottom:80px;
    -moz-box-sizing:border-box;
    box-sizing:border-box; 
}

http://jsfiddle.net/xrb5U/3/

另一个问题是,具有不同文本量的两个容器将具有不同的大小(如果一个大于最小高度集)。在CSS定位中没有简单的解决方法,您必须使用Javascript,Flexbox或display:table-cell来保持所有它们的高度相同,但每个都有自己的问题。

答案 1 :(得分:1)

在(希望不久)将来的某个时候,您将可以使用subgrid feature of CSS GridsCurrently, only Firefox supports this,但其他浏览器应尽快添加支持。

Subgrid使您可以将网格特征与非平面结构一起使用(例如,无序列表)。也就是说,您可以将一个元素的子元素与另一个元素的子元素,或者在这种情况下,将图像,标题,描述和价格按钮对齐。

.list-product-pat {
  /* Create a grid with 5 columns that are 175px wide,
     each with 5 rows that are sized based on the smallest item in the row */
  display: inline-grid;
  grid-template-columns: repeat(5, 175px);
  grid-template-rows: repeat(5, min-content);

  /* Colors and spacing to match design */
  background: #f4f4f4;
  padding: 1em;
  grid-column-gap: 1em;
  border: 1px solid #ddd;
}

.list-product-pat li {
  /* Ensure this item takes up the column */
  grid-row: 1 / -1;

  /* Make children grid items */
  display: grid;

  /* Use parent's grid for children */ 
  grid-template-rows: subgrid;

  /* Styles to match design */
  text-align: center;
  justify-items: center;
  border: 1px solid #ddd;
  background: #fff;
}

/* STYLES TO MATCH DESIGN BELOW */

.list-product-pat > li > img {
  margin-top: 1em;
}

.list-product-pat > li > h1 {
  margin: .8em 0;
  font-size: 1em;
}

.list-product-pat > li > p {
  margin: 0;
  color: #bbb;
  font-size: .8em;
  margin: 0 .5em 1em;
}

.list-product-pat > li > a {
  text-decoration: none;
  color: white;
  font-weight: bold;
  background: linear-gradient(#60bb76, #48b161);
  border-radius: .5em;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, .5);
  padding: .5em;
  min-width: calc(100% - 1em);
  margin-bottom: .5em;
  box-sizing: border-box;
}

.list-product-pat > li > a > small {
  display: block;
  font-weight: normal;
  font-size: .7em;
  margin-top: .2em;
}
<ul class="list-product-pat">
  <li>
    <img src="https://placehold.it/40x70/">
    <h1>HTC Desire C</h1>
    <p>GSM, GPS, WiFi, kamera 5MP, bluetooth, Android, touchscreen, 600MHz</p>
    <a href="#">1.699.000 <small>6 Produk/4 Website</small></a>
  </li>
  <li>
    <img src="https://placehold.it/40x70/">
    <h1>Samsung 19300 Galaxy S III</h1>
    <p>GSM, GPS, WiFi, kamera 8MP, bluetooth, Android, touchscreen, 1.4GHz</p>
    <a href="#">5.300.000 <small>8 Produk/5 Website</small></a>
  </li>
  <li>
    <img src="https://placehold.it/40x70/">
    <h1>Samsung Galaxy Grand i9082</h1>
    <p>GSM, GPS, WiFi, touchscreen, 1.2GHz</p>
    <a href="#">3.499.000 <small>10 Produk/8 Website</small></a>
  </li>
  <li>
    <img src="https://placehold.it/40x70/">
    <h1>Apple iPhone 5 16GB</h1>
    <p>GSM, GPS, WiFi, kamera 8MP, bluetooth, iOS 6, touchscreen, 1.2GHz</p>
    <a href="#">7.599.000 <small>6 Produk/5 Website</small></a>
  </li>
  <li>
    <img src="https://placehold.it/40x70/">
    <h1>BlackBerry Curve 9360 (Apollo)</h1>
    <p>GSM, GPS, WiFi, kamera 5MP, bluetooth, 800MHz</p>
    <a href="#">225.000 <small>9 Produk/4 Website</small></a>
  </li>
</ul>

答案 2 :(得分:0)

正如@mikel所指出的那样,您不能将position: absolute的元素保留在常规document flow内,但是可以通过模拟解决此问题。

考虑以下示例:

img {
  position: absolute;
}
<img src="https://dummyimage.com/300x400/d9ca29/ffffff">
<span>Lorem Ipsum is simply dummy text of the printing and typesetting industry</span>

<img>元素已用完,这导致<span>被隐藏在其后面。

您可以将绝对元素包装在一个空容器中,然后向容器中添加高度和宽度,使其等于绝对元素的高度和宽度。这样,将在绝对容器周围创建一个不可见的框元素,使其显示为文档常规流的一部分。

如果您已经知道<img>元素的确切尺寸,则可以仅使用css模拟正常流:

div {
  border: 2px dotted grey;
  position: relative;
  width: 300px;
  height: 400px;
}

img {
  position: absolute;
}
<div>
  <img src="https://dummyimage.com/300x400/d9ca29/ffffff">
</div>

<span>Lorem Ipsum is simply dummy text of the printing and typesetting industry</span>

否则,如果您不预先知道绝对元素的尺寸,则必须使用javascript动态模拟正常流:

window.addEventListener('load', function() {
  var div = document.querySelector('div');
  var img = document.querySelector('img');
  var rect = img.getBoundingClientRect();

  div.style.height = rect.height + 'px';
  div.style.width = rect.width + 'px';
});
div {
  border: 2px dotted grey;
  position: relative;
  max-width: 200px;
}

img {
  position: absolute;
  width: 100%;
}
<div>
  <img src="https://dummyimage.com/300x400/d9ca29/ffffff">
</div>

<span>Lorem Ipsum is simply dummy text of the printing and typesetting industry</span>

答案 3 :(得分:0)

解决方案其实很简单。复制绝对定位的页脚,隐藏可见性。

<div style="background: silver; position: relative; height: 100px">
  Height is 100px
  <div style="position: absolute; bottom: 0; left: 0">Footer</div>
  <div style="visibility: hidden">Footer</div>
</div>
<br />
<div style="background: silver; position: relative">
  No height specified
  <div style="position: absolute; bottom: 0; left: 0">Footer</div>
  <div style="visibility: hidden">Footer</div>
</div>