Css3甜甜圈菜单

时间:2013-03-04 18:14:22

标签: css css3 user-interface

您好我想实现像这样的甜甜圈菜单http://dribbble.com/shots/610433-Wheel-Nav我知道在css3中有一种简单的方法可以做甜甜圈。

.doughnut { 
    border: 50px solid #f00;
    border-radius: 100px;
    height:100px;
    width:100px;
}

但当然这只会使甜甜圈里面没有任何元素。我想知道无论如何只使用css3,任何关于如何开始的想法?如果只有css不可能我会跳进javascript区域......

3 个答案:

答案 0 :(得分:13)

我尝试使用CSS重现该图像:

live demo

<强>结果

result

<强> HTML

<ul class='menu circ-menu'>
  <li class='menu-item'>
    <a href='#'>☊</a>
  </li>
  <li class='menu-item selected'>
    <a href='#'>☁☀</a>
    <ul class='menu submenu'>
      <li><a href='#'>☂</a></li><!--
      --><li><a href='#'>☁</a></li><!--
      --><li><a href='#'>☃</a></li>
    </ul>
  </li>
  <li class='menu-item'>
    <a href='#'>✦</a>
  </li>
</ul>

<强> CSS

.menu { padding: 0; list-style: none; }
.menu a {
  display: block;
  color: #666561;
  font: 900 2em/3.2 monospace;
  text-decoration: none;
  text-shadow: 0 1px white;
}
.circ-menu {
  overflow: hidden;
  position: relative;
  margin: 1em auto;
  padding: 5em 0 0;
  width: 20em; height: 10em;
  box-shadow: 0 .5em .5em -.5em;
}
.menu-item {
  overflow: hidden;
  position: absolute;
  z-index: 0;
  left: -50%; bottom: 0;
  width: 20em; height: 20em;
  transform-origin: 100% 100%;
}

/* === style the menu items (slices) === */

/* three slices making up half a circle mean that a slice is going to have a central_angle = 60deg */
.menu-item:first-child {
  transform: skewX(30deg) /* 90deg - central_angle */;
}
.menu-item:nth-child(2) {
  /* rotate by the value of the central angle multiplied with how many slices are before */
  transform: 
    rotate(60deg) /* 60deg = 1*central angle */
    skewX(30deg) /* 90deg - central_angle */;
}
.menu-item:last-child {
  transform: 
    rotate(120deg) /* 120deg = 2*central angle */
    skewX(30deg) /* 90deg - central_angle */;
}

/* === contents of the menu items === */
.menu-item > * {
  position: absolute;
  top: 55%; left: 55%;
  width: 90%; height: 90%;
  text-align: center;
}
.menu-item > a {
  border-radius: 50%;
  box-shadow: 0 0 0 .2em #aaa497, 
    0 0 .5em .2em black;
  transform:
    skewX(-30deg) /* unskew */
    rotate(-60deg);
  background: #f8f4ef;
  background: 
    radial-gradient(transparent 39%, #f7f3ee 40%);
}
.selected > a { z-index: 1; }
.selected > a, .menu a:hover {
  color: #e96429;
}
.selected > a, .menu-item > a:hover {
  box-shadow: 0 0 0 .2em #e96429, 
    0 0 .5em .2em black;
  background: 
    linear-gradient(60deg, #e96429 31%, rgba(247, 243, 238, 0) 33%),
    linear-gradient(-60deg, #e96429 31%, rgba(247, 243, 238, 0) 33%),
    radial-gradient(transparent 39%, #f7f3ee 40%);
  background-size: 100% 26%,  100% 26%, 100% 100%;
}

.submenu {
  z-index: 0;
  transform: 
    skewX(-30deg) /* unskew */
    rotate(-60deg)
    translateY(-5.25em);
}
.submenu li {
  display: inline-block;
  position: relative;
  border-top: solid 1px #666561;
  border-bottom: solid 1px #666561;
  width: 3.2em; height: 3.2em;
  background: #f7f3ee;
}
.submenu li:before {
  position: absolute;
  bottom: 0;
  width: 100%; height: .2em;
  background: #666561;
  content: '';
}
.submenu a {
  line-height: 2
}
.submenu li:first-child {
  border-radius: .3em 0 0 .3em;
  border-left: solid 1px #666561;
}
.submenu:after {
  position: absolute;
  z-index: -1;
  top: 2.5em; left: 50%;
  margin: 0 -.6em;
  width: 1.2em; height: 1.2em;
  transform: rotate(-30deg) skewX(30deg);
  background: #666561;
  content: '';
}
.submenu li:last-child {
  border-radius: 0 .3em .3em 0;
  border-right: solid 1px #666561;
}

.circ-menu:before, .circ-menu:after {
  position: absolute;
  z-index: 1;
  bottom: -7.071em; left: 14.645%;
  width: 14.142em; height: 14.142em;
  border-radius: 50%;
  content: '';
}
.circ-menu:before {
  bottom: -5em; left: 5em;
  width: 10em; height: 10em;
  box-shadow: inset 0 0 .75em black, 
    0 0 .5em .2em #f7f3ee;
}
.circ-menu:after {
  bottom: -1em; left: 9em;
  width: 2em; height: 2em;
  box-shadow: 0 0 .4em dimgrey, 
    0 0 0 .75em #e27447, 
    0 0 .4em .75em dimgrey, 
    0 0 0 2em #f7f3ee, 
    0 0 .4em 2em dimgrey;
  background: #f7a480;
}

这个想法非常简单。您可以从列表结构开始,就像对每个菜单一样。

<ul class='menu-circ'>
  <li class='menu-item'><a href='#'>boo</a></li>
  <!-- the other list items -->
</ul>

解释基本想法

您给容器.menu-circ position: relative,并且您绝对定位其子项(菜单项),使其中一个角位于中心(.menu-circ)。然后将.menu-item的transform-origin设置在该角落。

在这种情况下,我选择了右下角位于中心(transform-origin: right bottom相当于transform-origin: 100% 100%),但这并不重要,你可以选择任何一个角落想放在中心并在那里设置transform-origin

然后,您需要为菜单项形成的每个切片决定central angle的值。在这种情况下,它很容易 - 有半个圆圈的三个切片,半个圆圈意味着180deg,所以假设我想要3个相等的切片,每个切片的中心角度为180deg/3 = 60deg

在决定之后,你现在需要使在父母中心相遇的边(在这种情况下是右边和底边)形成60deg的角度。您可以通过应用倾斜变换来实现,倾斜角度为90deg-60deg = 30deg

transform: skewX(30deg);

但是这仍然将所有菜单项保留在第一个菜单项的位置。因此,对于除第一个菜单项之外的所有菜单项,您还需要旋转中心角的值乘以之前的项数。这意味着你将拥有:

.menu-item:first-child { transform: skewX(30deg); } /* no items before */
.menu-item:nth-child(2) { transform: rotate(60deg) /* 1*60deg */ skewX(30deg); }
.menu-item:nth-child(3) { transform: rotate(120deg) /* 2*60deg */ skewX(30deg); } 

这会将所有菜单项置于它们应有的位置,但现在它们的内容会出现偏差。所以你需要“疏通”他们。通过这个,我的意思是你应用相反角度的倾斜变换。在这种情况下,疏忽意味着应用skewX(-30deg)

尽管如此,内容的角度还是不对的。在这种情况下,您需要将其旋转一半的中心角减去90度。这意味着60deg/2 - 90deg = 30deg - 90deg = -60deg

内容(在这种情况下为链接)也应该绝对定位,使其中心位于您为其父级transform-origin设置.menu-item的位置您想要的大小,但如果您希望它是圆形的,那么您必须给它相等的宽度和高度,并确保它们不超过其父级(.menu-item)的两倍。

最后,您在overflow: hidden上设置了.menu-item并且您有一个饼图菜单。如果要覆盖中心部分,可以在菜单上使用伪元素(.menu-circ)。

答案 1 :(得分:0)

看看其中一些属性:

  • CSS 3转换 - 用于元素轮换 - W3
  • CSS 3过渡 - 平滑地旋转表盘我想 - W3
  • CSS Hover选择器 - 用于弹出窗口 - W3
  • CSS 3 Clip - 塑造元素 - W3

答案 2 :(得分:0)

有关创建css3饼图的教程可以帮助您:http://www.kylejlarson.com/blog/2011/how-to-create-pie-charts-with-css3/

你可以将所有的饼形楔子作为你的按钮,然后在轮子的中心叠加一个较小的圆圈。