使用Pocket Grid为响应式网格创建CSS Less Mixin

时间:2014-04-11 17:15:19

标签: css less pocketgrid

我有以下HTML代码:

<div class="wrapper">    
  <div><img src="http://placehold.it/400x200"/></div>
  <div><img src="http://placehold.it/400x200"/></div>
  <div><img src="http://placehold.it/400x200"/></div>
  <div><img src="http://placehold.it/400x200"/></div>
</div>

我正在使用PocketGrid来建立响应式网格。我创建了一个Example

我的LESS代码如下:

.wrapper {

  &:extend(.block-group);

  background-color: red;

  div {
    &:extend(.block);

    background-color: green;

    img {
      display: block;
      width: 100%;
      height: auto;
      outline: 0;
    }
  }

}

@media screen and (max-width: 760px) { 
 .wrapper div {
   width: (100% / 2);
  }
 @gutter: 10px;
  .block-group { margin: -@gutter 0 0 -@gutter; }
  .block { padding: @gutter 0 0 @gutter; }
 }

 @media screen and (min-width: 761px) { 
  .wrapper div {
    width: (100% / 4);
  }
  @gutter: 10px;
  .block-group { margin: -@gutter 0 0 -@gutter; }
  .block { padding: @gutter 0 0 @gutter; }
 }

问题

是否可以创建一个LESS Mixin,以便我可以重复使用它来在页面中创建许多网格,并指定colums和gutter的数量作为参数。

我尝试更改代码,但由于Extend,我总是遇到问题。

有人可以帮我把这段代码变成混合物吗?

我希望能够使用这样的东西:

.wrapper_1 {

  @media screen and (max-width: 760px) { make(2, 8px) }

  @media screen and (min-width: 761px) { make(4, 12px) }

  &:extend(.block-group);

  div {
    &:extend(.block);
  }

}

还有同一页面中的另一个包装器并执行类似的操作:

.wrapper_2 {

  @media screen and (max-width: 760px) { make(4, 12px) }

  @media screen and (min-width: 761px) { make(8, 16px) }

  &:extend(.block-group);

  div {
    &:extend(.block);
  }

}

谢谢你, 米格尔

2 个答案:

答案 0 :(得分:1)

我并不是100%肯定你所寻求的确切输出,但我相信以下内容给出了你想要的东西,至少应该为你提供你想要的东西。

.setGrid(
    @maxCols: 2; 
    @maxGutter: 8px; 
    @minCols: 4; 
    @minGutter: 12px; 
    @max-width: 760px
 )  {
    .setMedia(@cols; @gutter) {
        div {
            width: (100% / @cols);
        }
        .block-group { margin: -@gutter 0 0 -@gutter; }
        .block { padding: @gutter 0 0 @gutter; }
    }

    @media screen and (max-width: @max-width) { 
        .setMedia(@maxCols; @maxGutter);
    }

    @media screen and (min-width: (1 + @max-width)) { 
        .setMedia(@minCols; @minGutter);
    }

  &:extend(.block-group);

  div {
    &:extend(.block);
  }
}

.wrapper_1 {
  .setGrid();
}

.wrapper_2 {
  .setGrid(4; 12px; 8; 16px);
}

答案 1 :(得分:1)

如果您在.wrapper的上下文中调用mixin,则不会有.block.block-group个选择器,只有.wrapper .block.wrapper .block-group以及您的:extend与任何内容都不匹配。您可以将选择器作为参数传递给mixin,但extend也不会匹配插值变量。此外,您需要匹配顶级.block.block-group,因此即使它确实匹配变量,它也无论如何都无法正常工作。

您可以按照建议调用mixin,如果您希望将样式应用于嵌套在选择器中的div,则可以在变量中传递选择器的名称。所以你可以这样:

@media screen and (max-width: 760px) {
  .make(2; 8px; wrapper);
}
@media screen and (min-width: 761px) {
  .make(4; 12px; wrapper);
}

就像你建议的那样,但是将选择器名称作为参数传递。由于mixins是在顶层调用的,因此.block选择器也将位于顶级,并且只有div选择器将位于.wrapper上下文中:

.make(@columns; @gutter; @selector) {
  .@{selector} {
    &:extend(.block-group);
    div:extend(.block) {
      width: (100% / @columns);
    }
  }
  .block-group { margin: -@gutter 0 0 -@gutter; }
  .block { padding: @gutter 0 0 @gutter; }
}

上面的mixin存在一个问题。由于您要将内部称为媒体查询,因此extend范围也将仅限于媒体查询。如果您不必扩展任何全局选择器,那就没关系,但在您的情况下,您可以。只要在选择器中使用extend伪元素而不是在mixin中,您仍然可以在媒体查询中使用mixin:

.wrapper:extend(.block-group) {
  background-color: red;
  div:extend(.block) {
    background-color: green;
    img {
      display: block;
    ...

将其从mixin中移除:

.make(@columns; @gutter; @selector) {
  .@{selector} {
    div {
      width: (100% / @columns);
    }
  }
  .block-group { margin: -@gutter 0 0 -@gutter; }
  .block { padding: @gutter 0 0 @gutter; }
}

请参阅CodePen