2012-10-10 79 views
75

如何将几个<img>元素放置在另一个圆圈中并让这些元素都是可点击的链接?我希望它看起来像下面的图片,但我不知道如何实现这种效果。将图标放置到圆圈中

Desired Result

这甚至有可能吗?

回答

148

是的,这是非常可能的,非常简单的使用CSS。你只需要清楚你想要的图像链接的角度(我在最后添加了一段代码,只是为了显示角度,当你将其中的一个悬停时)。

demo

首先,您需要的包装。我把它的直径设置为24emwidth: 24em; height: 24em;这样做),你可以将它设置为任何你想要的。你给它position: relative;

然后,您将链接与包装中心的图像放在一起,包括水平和垂直。你可以通过设置position: absolute;然后top: 50%; left: 50%;margin: -2em;(其中2em是图像链接宽度的一半,我已将其设置为4em - 再次,您可以将其更改为任何您想要的,但不要忘记在这种情况下更改保证金)。

然后,您决定想要与图像建立链接的角度,然后添加类deg{desired_angle}(例如deg0deg45或其他)。然后为每个类等您应用链接CSS转换,就像这样:

.deg{desired_angle} { 
    transform: rotate({desired_angle}) translate(12em) rotate(-{desired_angle}); 
} 

,你替换{desired_angle}045,等等...

第一旋转变换旋转的对象和它的轴平移变换将沿旋转的X轴平移对象,第二次旋转变换将对象带回到位置 - demo to illustrate how this works

这种方法的优点是灵活性。您可以在不改变当前结构的情况下以不同角度添加新图像。

HTML

<div class='circle-container'> 
    <a href='#' class='center'><img src='image.jpg'></a> 
    <a href='#' class='deg0'><img src='image.jpg'></a> 
    <a href='#' class='deg45'><img src='image.jpg'></a> 
    <a href='#' class='deg135'><img src='image.jpg'></a> 
    <a href='#' class='deg180'><img src='image.jpg'></a> 
    <a href='#' class='deg225'><img src='image.jpg'></a> 
    <a href='#' class='deg315'><img src='image.jpg'></a> 
</div> 

相关CSS

.circle-container { 
    position: relative; 
    width: 24em; 
    height: 24em; 
    padding: 2.8em; 
    /*2.8em = 2em*1.4 (2em = half the width of a link with img, 1.4 = sqrt(2))*/ 
    border: dashed 1px; 
    border-radius: 50%; 
    margin: 1.75em auto 0; 
} 
.circle-container a { 
    display: block; 
    position: absolute; 
    top: 50%; left: 50%; 
    width: 4em; height: 4em; 
    margin: -2em; 
} 
.circle-container img { display: block; width: 100%; } 
.deg0 { transform: translate(12em); } /* 12em = half the width of the wrapper */ 
.deg45 { transform: rotate(45deg) translate(12em) rotate(-45deg); } 
.deg135 { transform: rotate(135deg) translate(12em) rotate(-135deg); } 
.deg180 { transform: translate(-12em); } 
.deg225 { transform: rotate(225deg) translate(12em) rotate(-225deg); } 
.deg315 { transform: rotate(315deg) translate(12em) rotate(-315deg); } 

此外,您还可以进一步通过使用背景图片的链接,而不是使用img标签简化HTML 。


编辑example with fallback for IE8 and older(在IE8和IE7测试)

+1

不错,但人们会看到设备/浏览器没有CSS变换访问时支持? – gkond

+1

唯一不支持CSS转换的桌面浏览器是IE8及更高版本。对于这些,可以使用IE矩阵滤波器变换来模拟。至于移动浏览器,Opera Mini是唯一不支持CSS转换的软件,我真的不会使用那些在小屏幕上浪费空间的东西。 – Ana

+0

我已经为IE8和更旧的版本添加了一个回退示例。 – Ana

4

没有办法将可点击的项目神奇地放置在另一个CSS元素的圆周围。 我如何做到这一点的方式是使用容器position:relative;。然后将所有元素与position:absolute;并使用topleft来定位它的位置。

即使您没有在您的代码中放置,也可能最好使用jQuery/javascript。

第一步是使用position:relative;将您的中心图像完美地放在容器的中心。

#centerImage { 
    position:absolute; 
    top:50%; 
    left:50%; 
    width:200px; 
    height:200px; 
    margin: -100px 0 0 -100px; 
} 

之后,你可以通过使用centerImage的offset()减去容器的offset()把它周围的其他元素。为您提供图像的确切topleft

var left = $('#centerImage').offset().left - $('#centerImage').parent().offset().left; 
var top = $('#centerImage').offset().top - $('#centerImage').parent().offset().top; 

$('#surroundingElement1').css({ 
    'left': left - 50, 
    'top': top - 50 
}); 

$('#surroundingElement2').css({ 
    'left': left - 50, 
    'top': top 
}); 

$('#surroundingElement3').css({ 
    'left': left - 50, 
    'top': top + 50 
}); 

我在这里所做的是将相对到centerImage元素。希望这可以帮助。

14

这里是没有绝对定位最简单的办法:

.container .row {margin:20px;text-align:center;} 
.container .row img {margin:0 20px;} 

<div class="container"> 
    <div class="row"> 
     <img src="https://ssl.gstatic.com/s2/oz/images/faviconr2.ico" alt="" width="64" height="64"> 
     <img src="https://ssl.gstatic.com/s2/oz/images/faviconr2.ico" alt="" width="64" height="64"> 
    </div> 
    <div class="row"> 
     <img src="https://ssl.gstatic.com/s2/oz/images/faviconr2.ico" alt="" width="64" height="64"> 
     <img src="https://ssl.gstatic.com/s2/oz/images/faviconr2.ico" alt="" width="64" height="64"> 
     <img src="https://ssl.gstatic.com/s2/oz/images/faviconr2.ico" alt="" width="64" height="64"> 
    </div> 
    <div class="row"> 
     <img src="https://ssl.gstatic.com/s2/oz/images/faviconr2.ico" alt="" width="64" height="64"> 
     <img src="https://ssl.gstatic.com/s2/oz/images/faviconr2.ico" alt="" width="64" height="64"> 
    </div> 
</div>​ 

http://jsfiddle.net/mD6H6/

0

你可以做这样的:fiddle

不介意的定位,它的一个简单的例子

2

你当然可以用纯CSS做,或使用JavaScript。我的建议:

  • 如果你已经知道,图片数量将永远不变只是计算你的风格,并用纯CSS(优点:更好的性能,非常可靠)去

  • 如果数字可以改变或者动态应用程式或只是可能会在未来改变去与一个JS的解决方案(优点:更面向未来的)

我也有类似的工作要做,所以我创建了一个脚本,开源,开源它here on Github为任何人可能需要它。它只接受一些配置值,并输出您需要的CSS代码。

如果你想去Js的解决方案这里有一个简单的指针,可以帮助你。使用这个网站作为出发点是#box容器和.dot你想要的中间影像/ DIV所有其他图像周围:

开始HTML:

<div id="box"> 
    <div class="dot"></div> 
    <img src="my-img.jpg"> 
    <!-- all the other images you need--> 
</div> 

开始的CSS:

#box{ 
    width: 400px; 
    height: 400px; 
    position: relative; 
    border-radius: 100%; 
    border: 1px solid teal; 
} 

.dot{ 
    position: absolute; 
    border-radius: 100%; 
    width: 40px; 
    height: 40px; 
    left: 50%; 
    top: 50%; 
    margin-left: -20px; 
    margin-top: -20px; 
    background: rebeccapurple; 
} 
img{ 
    width: 40px; 
    height: 40px; 
    position: absolute; 
} 

您可以沿着这些线创建快速功能:

var circle = document.getElementById('box'), 
    imgs = document.getElementsByTagName('img'), 
    total = imgs.length, 
    coords = {}, 
    diam, radius1, radius2, imgW; 

// get circle diameter 
// getBoundingClientRect outputs the actual px AFTER transform 
//  using getComputedStyle does the job as we want 
diam = parseInt(window.getComputedStyle(circle).getPropertyValue('width')), 
radius = diam/2, 
imgW = imgs[0].getBoundingClientRect().width, 
// get the dimensions of the inner circle we want the images to align to 
radius2 = radius - imgW 

var i, 
    alpha = Math.PI/2, 
    len = imgs.length, 
    corner = 2 * Math.PI/total; 

// loop over the images and assign the correct css props 
for (i = 0 ; i < total; i++){ 

    imgs[i].style.left = parseInt((radius - imgW/2) + (radius2 * Math.cos(alpha))) + 'px' 
    imgs[i].style.top = parseInt((radius - imgW/2) - (radius2 * Math.sin(alpha))) + 'px' 

    alpha = alpha - corner; 
} 

你可以看到一个活生生的例子here

4

建设关@安娜的出色答卷,我创造了这个动力版本,可以让你的元素之间添加和删除的DOM元素,并保持适度的间距 - 检查出我的小提琴:https://jsfiddle.net/skwidbreth/q59s90oy/

html

<!DOCTYPE html> 
<html> 
<head> 
    <link rel="stylesheet" href="style.css" /> 
</head> 
<body> 
    <ul id="list"></ul> 
    <button id="add-item">Add item</button> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
    <script src="main.js"></script> 
</body> 
</html> 

style.css

#list{ 
    background-color: blue; 
    height: 30vw; 
    width: 30vw; 
    border-radius: 50%; 
    position: relative; 
} 

.list-item{ 
    list-style: none; 
    background-color: red; 
    height: 5vw; 
    width: 5vw; 
    position: absolute; 
    top: 50%; 
    left: 50%; 
} 

main.js

var list = $("#list"); 

var updateLayout = function(listItems){ 
    for(var i = 0; i < listItems.length; i ++){ 
     var offsetAngle = 360/listItems.length; 
     var rotateAngle = offsetAngle * i; 
     $(listItems[i]).css("transform", "rotate(" + rotateAngle + "deg) translate(0, -15vw) rotate(-" + rotateAngle + "deg)") 
    }; 
}; 

$(document).on("click", "#add-item", function(){ 
    var listItem = $("<li class='list-item'>Things go here<button class='remove-item'>Remove</button></li>"); 
    list.append(listItem); 
    var listItems = $(".list-item"); 
    updateLayout(listItems); 
}); 

$(document).on("click", ".remove-item", function(){ 
    $(this).parent().remove(); 
    var listItems = $(".list-item"); 
    updateLayout(listItems); 
}); 
+1

工作很好,并且如果可以的话,我会加倍努力。我遇到的一个问题是,如果我将360更改为其他任何内容(我想要一个半圈),那么事情就会变得非常糟糕。我将它跟踪到旋转角度的声明并将其更改为'var rotateAngle = zero_start +(offsetAngle * i || 0);'我还为zero_start添加了一个变量,因此如果您想从270开始而不是0开始,或类似的东西。 https://jsfiddle.net/q59s90oy/13/。最后,我更改了列表项的css以使用负边距。 **尽管如此,感谢分享这项工作,帮了我很多。** –

+0

这是rad,很高兴你可以根据需要调整它。很好的变化! – skwidbreth