带有双倍高亮照片的Photowall

时间:2017-02-08 13:14:57

标签: css

我们正在开发图片库网站,无法找到解决以下问题的方法。

图片墙包含多张图片。一些图像(n百分比)应突出显示并在墙上显示双倍大小。

sample wall

问题是,我不知道填充大图片左边的空白区域,因为它是一条新线。

任何想法。

我在这里为这个示例创建了一个小提琴:Fiddle

    <body>
  <div class="size1">
  &nbsp;
  </div>
    <div class="size1">
  &nbsp;
  </div>
    <div class="size2">
  &nbsp;
  </div>
    <div class="size1">
  &nbsp;
  </div>
    <div class="size1">
  &nbsp;
  </div>
     <div class="size1">
  &nbsp;
  </div>
    <div class="size1">
  &nbsp;
  </div>
     <div class="size1">
  &nbsp;
  </div>
    <div class="size1">
  &nbsp;
  </div>
      <div class="size1">
  &nbsp;
  </div>
     <div class="size1">
  &nbsp;
  </div>
    <div class="size1">
  &nbsp;
  </div>
     <div class="size1">
  &nbsp;
  </div>
    <div class="size1">
  &nbsp;
  </div>
</body>

    div {
  background-color: #f00;
  float: left;
}

.size1{
  width: 100px;
  height: 100px;
    margin: 5px;
}
.size2{
  width: 210px;
  height: 210px;
    margin: 5px;
}

3 个答案:

答案 0 :(得分:2)

<强>更新

以下浏览器现在原生支持CSS网格布局。

  1. Firefox v52

  2. 适用于Linux,macOS,Windows,iOS和Android的Chrome v57

  3. Safari v10.1

  4. iOS Safari v10.3

  5. Opera v44

  6. 这种布局要求是CSS Grid Layout规范旨在解决的问题。该规范的介绍如下:

      

    网格布局是一种新的CSS布局模型,它具有强大的功能来控制框及其内容的大小和位置。与面向单轴的Flexible Box Layout不同,网格布局针对二维布局进行了优化:在两个维度中都需要对齐内容。

    CSS网格布局的原生浏览器支持可能很快就会开始在主要浏览器中着陆(如图所示here,并且目前在一些。对于不支持的浏览器,此JavaScript polyfill将是必需的。

    例如, CSS Grid Layout 语法显示在以下CSS中:

    <强> HTML

    <div class="wrapper">
      <div class="box">1</div>
      <div class="box">2</div>
      <div class="box">3</div>
      <div class="box">4</div>
      <div class="box box--double">5</div>
      <div class="box">7</div>
      <div class="box">8</div>
      ...
    </div>
    </div>
    

    CSS 使用网格布局模型

    .wrapper {
      width: 600px;
      display: grid;
      grid-gap: 10px;
      grid-template-columns: repeat(7, 100px);
      grid-template-rows: 100px 100px 100px;
      grid-auto-flow: row;
    }
    
    .box {
      background-color: #444;
      color: #fff;
      padding: 20px;
      font-size: 150%;
      margin: 5px;
    }
    
    .box--double {
      background-color: red;
      grid-column: 3 / span 2;
      grid-row: 2 / span 2;
    }
    

    <强>样本

    这是一个fiddle,它利用 CSS网格布局语法(包括polyfill)来提供一般性要点。

    或者,Masonry也许可以实现这一点,但是长期而言,这总是取决于JavaScript。

    响应式网页设计(RWD)

    CSS Grid Layout模块包含几个功能,可简化响应式设计的创建。解决评论中提出的问题的两个相关特征是:

    1 Flexible Lengths

    应使用fr单位,而不是将相对列宽指定为百分比。 fr单元的主要好处是,它可以避免在列数通过媒体查询更改时手动重新计算百分比 - (您只需更改列数的值)

    /* Avoid using percentages like this */
    .wrapper {
        grid-template-columns: repeat(7, 14.286%);
        ...
    }
    
    /* Use the 'fr' unit instead */
    .wrapper {
        grid-template-columns: repeat(7, 1fr);
        ...
    }
    

    2 grid-auto-flow-dense

    可以分配给grid-auto-flow属性的三个值,即rowcolumndense

    .wrapper {
        grid-auto-flow: dense;
        ...
    }
    

    在使用rowcolumn值的某些情况下,它会在布局中产生不需要的漏洞/间隙。指定dense时,算法会尝试填充这些孔/间隙,但这有时会改变项目的顺序。此功能与Masonry基于可用垂直空间将项目放置在不同位置的方式非常相似。

    针对RWD的演示

    这是一个响应式fiddle,它使用fr单位和dense值来避免布局中的任何间隙/漏洞。

    编辑(5):更新了支持CSS网格布局的浏览器列表。

    编辑(4):添加了有关实施CSS网格布局规范的Chrome 57的说明。

    编辑(3):添加了有关实施CSS网格布局规范的Firefox 52的说明。

    编辑(2):添加有用的CSS网格布局功能以实现RWD

    编辑(1):将示例代码更改为简洁版本并更新了指向外部小提琴的链接

答案 1 :(得分:1)

这是一个仅基于CSS的解决方案,完全响应,基于CSS columns

.columns >div {
  background-color: #f00;
  float: left;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  break-inside: avoid;
}

.size1{
  width: 100px;
  height: 100px;
  margin: 5px;
}
.size2{
  width: 210px;
  height: 210px;
  margin: 5px;
}
.columns {
  width: 660px;
  margin: 0 auto;
  -webkit-columns: 200px 3;
  -moz-columns: 200px 3;
  columns: 200px 3;
  -webkit-column-gap: 0;
  -moz-column-gap: 0;
  column-gap: 0;
}

@media (max-width: 689px) {
  .columns {
    width: 440px;
    margin: 0 auto;
    -webkit-columns: 200px 2;
    -moz-columns: 200px 2;
    columns: 200px 2;
  } 
}
@media (max-width: 459px) {
  .columns {
    display: flex;
    flex-wrap: wrap;
    max-width: 220px;
  }
  .columns div {
    flex: 1 0 auto;
  }
  .columns .size1 {
    flex-basis: calc(50% - 10px)
  }
  .columns .size2 {
    flex-basis: calc(100% - 10px)
  }
}
body {
  padding: 0;
  text-align: center;
}

@media (min-width: 920px) { /* 4 columns */
  .columns {
    width: 880px;
    -webkit-columns: 200px 4;
    -moz-columns: 200px 4;
    columns: 200px 4;
  }
}
@media (min-width: 1140px) { /* 5 columns */
  .columns {
    width: 1100px;
    -webkit-columns: 200px 5;
    -moz-columns: 200px 5;
    columns: 200px 5;
  }
}
@media (min-width: 1360px) { /* 6 columns */
.columns {
    width: 1320px;
    -webkit-columns: 200px 6;
    -moz-columns: 200px 6;
    columns: 200px 6;
  }
}
@media (min-width: 1580px) { 
  /* respect the principle above to add as many columns as you like */
}
<div class="columns">
  <div class="size2"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size2"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size2"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size2"></div>
  <div class="size1"></div>
  <div class="size1"></div>
</div>

对于手机媒体查询间隔,我使用了flexbox,但这只是为了表明它是可能的。你真的不必,你可以坚持box-model

注意:您可以定义更多媒体间隔。基本思路是拥有220px的倍数,并将其限制为有足够空间容纳所有列的宽度。

这是小提琴(我添加它,因为某些原因,SO不允许我在~480px下调整片段窗口的大小,而jsFiddle。) fiddle here

此解决方案假设您始终将2个小项目组合在一起(因此它们占据1行)。如果您想要一个解决方案,添加内容的人无需满足此条件,并且在single时自动尝试将小项配对,则需要javascript

时间线解决方案(基于评论信息)

我猜这是你需要的吗? (如果您决定更改类名,则需要同时调整jsCSS)。

$('.timeline .size2').each(function(){
  //moving required number of small'uns so they fill the column
  var prevIndex = $(this).prevAll('.size2,.wrap').eq(0).index(), 
      diff = $(this).index() - (prevIndex + 1), 
      toMove = (3 - (diff  % 3)) %3;
  if (toMove) {
    for (var i = 1; i < toMove + 1; i++) {
      $(this).nextAll('.size1').eq(0).addClass('moved').insertBefore($(this))
    }
  }
  var wrap = $('<div />', {
    class:'wrap'
  })

  //wrap 2 small'uns to make a row under a big'un
  for (var i = 0; i < 2; i++) {
    wrap.append($(this).nextAll('.size1').eq(0));
  }
  wrap.insertAfter($(this));
})
.timeline [class^="size"] {
  background-color: red;
}

.size1{
  width: 100px;
  height: 100px;
  margin: 5px;
}
.size2{
  width: 210px;
  height: 210px;
  margin: 5px;
}
.timeline {
  display: flex;
  flex-direction: column;
  align-content: flex-start;
  height: 330px;
  flex-wrap: wrap;
}
.timeline .wrap {
  display: inline-flex;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="timeline">
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size2"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size2"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size2"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size1"></div>
  <div class="size2"></div>
  <div class="size1"></div>
  <div class="size1"></div>
</div>

答案 2 :(得分:1)

我试图缩短RobC的小提琴并用相对宽度(以百分比表示)替换固定宽度(以像素为单位)。所以它反应更敏捷。但是仍然有一些差距你可以通过一些规则来防止,比如“没有两个大盒子并排”等等。

Html

<div class="wrapper">
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" /> 
  <img src="https://dummyimage.com/300x200/333/fff" class="" /> 
  <img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />
  <img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />  
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/600x400/f33/fff" class="box--double" />  
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
  <img src="https://dummyimage.com/300x200/333/fff" class="" />
</div>

CSS

.wrapper {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(6, 16.666%);
  grid-auto-flow: row;
}
@media screen and (max-width: 940px) {
  .wrapper {
    grid-template-columns: repeat(5, 20%);
  }
}
@media screen and (max-width: 540px) {
  .wrapper {
    grid-template-columns: repeat(3, 33.333%);
  }
}

.wrapper > img {
  background-color: #444;
  color: #fff;
  border: solid 1px white;
}
.box::before {
  content: ' ';
  display: block;
  padding-top: 100%;
}

.box--double {
  background-color: red;
  grid-column: auto / span 2;
    grid-row: auto / span 2;
}

The fiddle