在圆形上放置项目

Avatar of Kitty Giraudel
Kitty Giraudel

使用 CSS 在圆形上放置项目可能颇具挑战性。通常,我们会依赖 JavaScript,因为某些插件可以立即完成所有操作。但是,很多时候,没有充分的理由用 JavaScript 而不是 CSS 来实现。这属于表现目的,让我们采用 CSS 的方式。

混合器

Ana TudorStack Overflow 答案 中解释了她是如何使用链式 CSS 转换来实现这一点的。之后,我将其解决方案转换为 Sass 混合器,使一切变得轻而易举。

/// Mixin to place items on a circle
/// @author Kitty Giraudel
/// @author Ana Tudor
/// @param {Integer} $item-count - Number of items on the circle
/// @param {Length} $circle-size - Large circle size
/// @param {Length} $item-size - Single item size
@mixin on-circle($item-count, $circle-size, $item-size) {
  position: relative;
  width:  $circle-size;
  height: $circle-size;
  padding: 0;
  border-radius: 50%; 
  list-style: none;       
  
  > * {
    display: block;
    position: absolute;
    top:  50%; 
    left: 50%;
    width:  $item-size;
    height: $item-size;
    margin: -($item-size / 2);
  
    $angle: (360 / $item-count);
    $rot: 0;

    @for $i from 1 through $item-count {
      &:nth-of-type(#{$i}) {
        transform: 
          rotate($rot * 1deg) 
          translate($circle-size / 2) 
          rotate($rot * -1deg);
      }

      $rot: $rot + $angle;
    }
  }
}

注意!此代码片段已省略了供应商前缀。如果您不使用 Autoprefix,请确保添加 transform 的前缀。

演示

出于演示目的,我们将考虑一个包含 8 张图像的列表,但基本上任何内容都可以使用。

<ul class='circle-container'>
  <li><img src='http://lorempixel.com/100/100/city' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/nature' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/abstract' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/cats' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/food' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/animals' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/business' alt="..." /></li>
  <li><img src='http://lorempixel.com/100/100/people' alt="..." /></li>
</ul>
.circle-container {
  @include on-circle($item-count: 8, $circle-size: 20em, $item-size: 6em); 
  margin: 5em auto 0;
  border: solid 5px tomato;
  
  img { 
    display: block; 
    max-width: 100%; 
    border-radius: 50%;
    filter: grayscale(100%);
    border: solid 5px tomato;
    transition: .15s;
    
    &:hover,
    &:active {
      filter: grayscale(0);
    }
  }
}