我有一张可以改变大小的光盘,并且有一些图标排列在该光盘周围。图标应始终位于光盘的边框上,每个图标之间的间隔应始终保持不变。
这可以在纯css中完成而无需在光盘增大或缩小时计算每个图标的位置吗?
预期结果:
.container:nth-child(1)
{
position: absolute;
top: 20px;
left: 30px;
height: 280px;
width: 280px;
}
.container:nth-child(2)
{
position: absolute;
top: 20px;
right: 30px;
height: 200px;
width: 200px;
}
.container > *
{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.circle
{
height: 90%;
width: 90%;
border-radius: 50%;
border: 1px solid blue;
z-index: 20;
}
.icons
{
height: 100%;
width: 100%;
border: 1px dashed gray;
box-sizing: border-box;
z-index: 10;
}
.icons > *
{
position: absolute;
top: 50%;
left: 50%;
height: 20px;
width: 20px;
margin-top: -10px;
margin-left: -10px;
border: 1px solid red;
}
.container:nth-child(1) span:nth-child(1)
{
transform: rotate(230deg) translate(150px) rotate(-230deg);
}
.container:nth-child(1) span:nth-child(2)
{
transform: rotate(217deg) translate(150px) rotate(-217deg);
}
.container:nth-child(1) span:nth-child(3)
{
transform: rotate(204deg) translate(150px) rotate(-204deg);
}
.container:nth-child(1) span:nth-child(4)
{
transform: rotate(191deg) translate(150px) rotate(-191deg);
}
.container:nth-child(2) span:nth-child(1)
{
transform: rotate(230deg) translate(110px) rotate(-230deg);
}
.container:nth-child(2) span:nth-child(2)
{
transform: rotate(212deg) translate(110px) rotate(-212deg);
}
.container:nth-child(2) span:nth-child(3)
{
transform: rotate(194deg) translate(110px) rotate(-194deg);
}
.container:nth-child(2) span:nth-child(4)
{
transform: rotate(176deg) translate(110px) rotate(-176deg);
}

<div class="container">
<div class="circle"></div>
<div class="icons">
<span>A</span>
<span>B</span>
<span>C</span>
<span>D</span>
</div>
</div>
<div class="container">
<div class="circle"></div>
<div class="icons">
<span>A</span>
<span>B</span>
<span>C</span>
<span>D</span>
</div>
</div>
&#13;
答案 0 :(得分:2)
有一种方法可以通过编程方式完成,但只能使用CSS3。您需要做的是在其内部有一个元素,它占据整个宽度并可以旋转,然后反转旋转元素的内部容器。
因此您必须使用:nth-child
来定义圈子。为了达到正确的效果并且不再应用两次样式,我们必须从最后一个元素倒计数,以便仅吸引某个位置的元素。这是因为:nth-child(2n)
也适用于:nth-child(4n)
,这可能会创建重叠的样式。如果这看起来有点过于复杂,请跳到片段 - 实际上非常简单。
所以你的基本HTML将是:
<wrapper> <!-- This is your disc -->
<rotation> <!-- A rotation element. -->
<counter> <!-- A counter-rotation element. This contains your content. -->
第一个元素必须启用一个位置。第二个元素需要与所有其他次要元素重叠,因此它需要一个绝对的位置,第三个元素,这取决于你。只是在那里反击它再次旋转。
继承人的实施:
/*The following animation shows that the outer frame is resizeable.*/
@-webkit-keyframes sizeBounce { 0% {width: 50vw; height: 50vw; } 50% {width: 20vw; height: 20vw; } 100% {width: 50vw; height: 50vw; }}
@keyframes sizeBounce { 0% {width: 50vw; height: 50vw; } 50% {width: 20vw; height: 20vw; } 100% {width: 50vw; height: 50vw; }}
div {
position: relative;
/* Any height you want here */
width: 20vw;
height: 20vw;
border-radius: 50%;
border: 1px solid #000;
-webkit-animation: sizeBounce 2s infinite;
animation: sizeBounce 2s infinite;
/* You can do anything you want with this circle! */
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
}
div > span {
position: absolute;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
transform: rotateZ(0deg);
transform-origin: 50% 50%;
}
div > span > em {
display: block;
position: absolute;
left: 0;
top: 0;
width: 20%;
height: 20%;
border-radius: 50%;
border: 1px solid #dd0300;
text-align: center;
}
div > span:nth-child(6n-6) {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
}
div > span:nth-child(6n-6) > em {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
}
div > span:nth-child(6n-4) {
-webkit-transform: rotateZ(60deg);
transform: rotateZ(60deg);
}
div > span:nth-child(6n-4) > em {
-webkit-transform: rotateZ(-60deg);
transform: rotateZ(-60deg);
}
div > span:nth-child(6n-3) {
-webkit-transform: rotateZ(120deg);
transform: rotateZ(120deg);
}
div > span:nth-child(6n-3) > em {
-webkit-transform: rotateZ(-120deg);
transform: rotateZ(-120deg);
}
div > span:nth-child(6n-2) {
-webkit-transform: rotateZ(180deg);
transform: rotateZ(180deg);
}
div > span:nth-child(6n-2) > em {
-webkit-transform: rotateZ(-180deg);
transform: rotateZ(-180deg);
}
div > span:nth-child(6n-1) {
-webkit-transform: rotateZ(240deg);
transform: rotateZ(240deg);
}
div > span:nth-child(6n-1) > em {
-webkit-transform: rotateZ(-240deg);
transform: rotateZ(-240deg);
}
div > span:nth-child(6n) {
-webkit-transform: rotateZ(300deg);
transform: rotateZ(300deg);
}
div > span:nth-child(6n) > em {
-webkit-transform: rotateZ(-300deg);
transform: rotateZ(-300deg);
}
&#13;
<div>
<span><em>1</em></span>
<span><em>2</em></span>
<span><em>3</em></span>
<span><em>4</em></span>
<span><em>5</em></span>
<span><em>6</em></span>
</div>
&#13;
有一种自动化方法是SASS,它看起来像这样:
@mixin rotatePiecemeally($pieces:6,$wrapper:span,$container:em){
/* First calculate the angle between each piece */
$degrees : 360 / $pieces;
/* We want to count back from the amount of pieces to 0
* The counting is because simple counting 2n, 3n, 4n, ...
* will result in 4n inheriting from 2n - to keep things clean,
* we want to avoid that. */
@for $i from 0 through ($pieces - 1){
& #{$wrapper}:nth-child(#{$pieces}n-#{$i}){
transform: rotateZ(#{$i * $degrees}deg);
}
& #{$wrapper}:nth-child(#{$pieces}n-#{$i}) > #{$container}{
transform: rotateZ(#{-$i * $degrees}deg);
}
}
}
您可以通过执行以下操作来调用它:
#mycircle {
@include rotatePiecemeally(6);
}
您可以选择包含要用作子项的元素。不要忘记他们都需要一些绝对的定位来实现这个目标。不要忘记添加您需要的任何prefixes
(我将它们添加到代码段中,因为我使用的是Safari)
答案 1 :(得分:2)
如果没有预处理器,我相信你需要一个脚本来实现这一点。在这里,我使用jQuery来计算悬停的间隔。
注意
这也会支持动态数量的.circle
元素
+ function() {
var to;
$(".wrap").on('mouseenter', function() {
var circles = $(this).find(".circle");
var degree = (2 * Math.PI) / circles.length; //calc delta angle
var transforms = [];
// Calculate the position for each circle
circles.each(function(index) {
var x = 100 * Math.cos(-0.5 * Math.PI + degree * (-1 * index - 0.5));
var y = 100 * Math.sin(-0.5 * Math.PI + degree * (-1 * index - 0.5));
transforms.push('translate(' + x + 'px,' + y + 'px)');
});
// Function to moves all the circles
// We'll pop a circle each time and than call this function recursively
function moveCircles() {
var transform = transforms.shift();
circles.css('transform', transform);
circles.splice(0, 1);
if (circles.length) to = setTimeout(moveCircles, 400);
}
moveCircles();
});
$(".wrap").on('mouseleave', function() {
var circles = $(this).children().css('transform', '');
clearTimeout(to);
});
}();
html {
height: 100%;
background: radial-gradient(ellipse at center, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
}
.wrap {
height: 300px;
width: 300px;
position: relative;
transform-origin: center center;
transition: all 0.8s;
}
.circle {
transition: all 0.8s;
position: absolute;
height: 5px;
width: 5px;
text-align: center;
line-height: 15px;
top: calc(50% - 2px);
left: calc(50% - 2px);
border-radius: 50%;
overflow: hidden;
}
.parent {
transition: all 0.8s;
position: absolute;
background: gray;
height: 50px;
width: 50px;
text-align: center;
line-height: 25px;
top: calc(50% - 25px);
left: calc(50% - 25px);
border-radius: 50%;
z-index: 8;
box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}
.parent:before,
.parent:after {
content: "";
position: absolute;
transition: all 0.8s;
height: 5px;
width: 25px;
top: 22px;
left: 12px;
background: black;
opacity: 1;
}
.parent:before {
top: 15px;
box-shadow: 0 14px 0 black;
}
.parent:hover:before,
.parent:hover:after {
transform: translate(0, 20px);
color: gray;
opacity: 0;
box-shadow: 0 14px 0 none;
}
.wrap:hover .parent,
.wrap:hover .parent:before,
.wrap:hover .parent:after {
background: darkgray;
}
.wrap:hover .parent:before {
box-shadow: none;
}
.wrap:hover .circle {
height: 50px;
width: 50px;
line-height: 25px;
top: calc(50% - 25px);
left: calc(50% - 25px);
box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}
.circle img {
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
}
.circle:before {
border-radius: 50%;
transition: all 0.8s;
content: "";
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
z-index: 8;
}
.circle:after,
button:after {
transition: all 0.8s;
border-radius: 50%;
content: "";
position: absolute;
height: 200%;
width: 200%;
top: 50%;
left: 200%;
z-index: 8;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(50%, rgba(255, 255, 255, 0.4)), color-stop(100%, rgba(255, 255, 255, 0)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#00ffffff', endColorstr='#00ffffff', GradientType=1);
}
.circle:hover:after,
button:hover:after {
left: -200%;
top: -50%;
}
.circle:hover:before {
box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="parent"></div>
<div class="circle">
<img src="http://lorempixel.com/300/300" />
</div>
<div class="circle">
<img src="http://placekitten.com/g/200/300" />
</div>
<div class="circle">
<img src="http://cdn.flaticon.com/png/256/56729.png" />
</div>
<div class="circle">
<img src="http://cdn.flaticon.com/png/256/54976.png" />
</div>
<div class="circle">Just Text</div>
<div class="circle">
<img src="http://cdn.flaticon.com/png/256/56582.png" />
</div>
</div>