如何将图标放置在圆形边缘

8
我希望将图标放在它们的父元素(圆形)的边缘,就像这样:

enter image description here

我尝试了一些方法,但默认情况下绝对定位的子元素会放置在其父元素的起始位置,就像这样:

enter image description here

即使父元素是圆形的(border-radius: 50%;),也可以实现。

我不想为每个子元素使用marginposition,因为它们的数量是动态的。

有没有办法将子元素放置在其父元素的边缘?

.circle {
  position: relative;
  width: 300px;
  height: 300px;
  background: rgba(0, 0, 0, 0.2);
  display: flex;
  align-items: center;
  border-radius: 50%;
}

.menu {
  list-style-type: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0;
  margin: 0;
  position: absolute;
  right: 5px;
}

.menu li {
  margin: 5px 0;
}

.menu li a {
  display: block;
}

.menu li a img {
  width: 50px;
}
<div class="circle">
  <ul class="menu">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
  </ul>
</div>

1个回答

6

考虑使用变换技术。你可以将所有项目放在中心,然后通过旋转/平移它们来放置在边缘。我正在使用CSS变量使代码更易于管理,但这不是必须的。

.circle {
  width: 300px;
  height: 300px;
  background: rgba(0, 0, 0, 0.2);
  display: flex;
  border-radius: 50%;
}

.menu {
  list-style-type: none;
  padding: 0;
  display:grid; /* use grid */
  margin:auto; /* center the menu with all the items */
}

.menu li {
  --d:120px; /* distance from the center */
  grid-area:1/1; /* all of them at the same position (they overlap) */
  /* we rotate then translate to the edge then rotate again using the opposite rotation */
  transform:rotate(var(--r)) translateX(var(--d)) rotate(calc(-1*var(--r)));
}

/* adjust the angle for each icon */
.menu li:nth-child(1) { --r:  0deg} 
.menu li:nth-child(2) { --r: 40deg} 
.menu li:nth-child(3) { --r:-40deg}

.menu li a {
  display: block;
}
.menu li a img {
  width: 50px;
}
<div class="circle">
  <ul class="menu">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
  </ul>
</div>

使用shape-outside的另一个想法:

.circle {
  width: 300px;
  height: 300px;
  background: rgba(0, 0, 0, 0.2);
  display: inline-flex;
  border-radius: 50%;
}

.menu {
  list-style-type: none;
  padding: 0;
  margin:0 0 0 auto;
  width:50%;
  text-align:right;
  word-spacing: 150px;
  line-height:0;
}
.menu::before {
  content:"";
  float:right;
  height:100%;
  width: 100%;
  shape-outside:radial-gradient(100% 50% at left,transparent 98%,#fff)
}

.menu li {
  display:inline-block;
}

.menu li a {
  display: block;
}
.menu li a img {
  width: 50px;
}
<div class="circle">
  <ul class="menu">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
  </ul>
</div>

<div class="circle">
  <ul class="menu">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
  </ul>
</div>

如果元素数量有限,您可以像下面这样优化第一个元素:

.circle {
  width: 300px;
  height: 300px;
  background: rgba(0, 0, 0, 0.2);
  display: inline-flex;
  border-radius: 50%;
}

.menu {
  --d:120px; /* distance from the center */
  --i:30deg; /* the increment */
  list-style-type: none;
  padding: 0;
  display:grid; /* use grid */
  margin:auto; /* center the menu with all the items */
}

.menu li {
  grid-area:1/1; /* all of them at the same position (they overlap) */
  /* we rotate then translate to the edge then rotate again using the opposite rotation */
  transform:rotate(var(--r)) translateX(var(--d)) rotate(calc(-1*var(--r)));
}

/* adjust the angle for each icon */
.menu li:nth-child(1) { --r: calc( 0*var(--i))} 
.menu li:nth-child(2) { --r: calc( 1*var(--i))} 
.menu li:nth-child(3) { --r: calc(-1*var(--i))} 
.menu li:nth-child(4) { --r: calc( 2*var(--i))} 
.menu li:nth-child(5) { --r: calc(-2*var(--i))} 
.menu li:nth-child(6) { --r: calc( 3*var(--i))} 
.menu li:nth-child(7) { --r: calc(-3*var(--i))} 
.menu li:nth-child(8) { --r: calc( 4*var(--i))} 
.menu li:nth-child(9) { --r: calc(-4*var(--i))} 
.menu li:nth-child(10){ --r: calc( 5*var(--i))} 
.menu li:nth-child(11){ --r: calc(-5*var(--i))} 
.menu li:nth-child(12){ --r: calc(-6*var(--i))} 

.menu li a {
  display: block;
}
.menu li a img {
  width: 50px;
}
<div class="circle">
  <ul class="menu" style="--i:50deg">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
  </ul>
</div>

<div class="circle">
  <ul class="menu" style="--i:20deg;--d:130px">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
  </ul>
</div>

<div class="circle">
  <ul class="menu" style="--d:100px">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
     <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li> <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
     <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
     <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
  </ul>
</div>

以上代码可以覆盖最多12个图标,您可以轻松扩展代码以覆盖更多图标。然后你只需要调整变量id即可。

另一种配置:

.circle {
  width: 300px;
  height: 300px;
  background: rgba(0, 0, 0, 0.2);
  display: inline-flex;
  border-radius: 50%;
}

.menu {
  --d:120px; /* distance from the center */
  --i:30deg; /* the increment */
  list-style-type: none;
  padding: 0;
  display:grid; /* use grid */
  margin:auto; /* center the menu with all the items */
}

.menu li {
  grid-area:1/1; /* all of them at the same position (they overlap) */
  /* we rotate then translate to the edge then rotate again using the opposite rotation */
  transform:rotate(var(--r)) translateX(var(--d)) rotate(calc(-1*var(--r)));
}

/* adjust the angle for each icon */
.menu li:nth-child(1) { --r: calc( 0*var(--i))} 
.menu li:nth-child(2) { --r: calc( 1*var(--i))} 
.menu li:nth-child(3) { --r: calc( 2*var(--i))} 
.menu li:nth-child(4) { --r: calc( 3*var(--i))} 
.menu li:nth-child(5) { --r: calc( 4*var(--i))} 
.menu li:nth-child(6) { --r: calc( 5*var(--i))} 
.menu li:nth-child(7) { --r: calc( 6*var(--i))} 
.menu li:nth-child(8) { --r: calc( 7*var(--i))} 
.menu li:nth-child(9) { --r: calc( 8*var(--i))} 
.menu li:nth-child(10){ --r: calc( 9*var(--i))} 
.menu li:nth-child(11){ --r: calc(10*var(--i))} 
.menu li:nth-child(12){ --r: calc(11*var(--i))} 

.menu li a {
  display: block;
}
.menu li a img {
  width: 50px;
}
<div class="circle">
  <ul class="menu" style="--i:50deg">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
  </ul>
</div>

<div class="circle">
  <ul class="menu" style="--i:20deg;--d:130px">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
  </ul>
</div>

<div class="circle">
  <ul class="menu" style="--d:100px">
    <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
     <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li> <li>
      <a href="#instagram">
        <img src="https://img.icons8.com/cotton/344/instagram-new.png" />
      </a>
    </li>
    <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
     <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
    <li>
      <a href="#youtube">
        <img src="https://img.icons8.com/cotton/344/youtube.png" />
      </a>
    </li>
     <li>
      <a href="#chrome">
        <img src="https://img.icons8.com/cotton/344/chrome.png" />
      </a>
    </li>
  </ul>
</div>

通过调整nth-child逻辑,您可以控制元素的放置方式。

谢谢,但正如我所说,我不想为每个单独的项目使用CSS属性。因为图标的数量是动态的。 - Abolfazl Panbehkar
1
@AbolfazlPanbehkar 提出了另一个想法。虽然还不完美,但是是一个很好的起点(稍后会进行优化)。 - Temani Afif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接