Расположение иконок в круг


Как я могу разместить несколько <img> элементы в круг вокруг другого и имеют ли эти элементы все кликабельные ссылки? Я хочу, чтобы это выглядело как на картинке ниже, но я понятия не имею, как достичь этого эффекта.

это вообще возможно?

6 83

6 ответов:

Да, это очень возможно и очень просто, используя только CSS. Вам просто нужно иметь в виду углы, под которыми вы хотите, чтобы ссылки с изображениями (я добавил кусок кода в конце только для отображения углов, когда вы наводите один из них).

демо

сначала вам нужна обертка. Я установил его диаметр, чтобы быть 24em (width: 24em; height: 24em; это), вы можете установить его на что угодно. Вы даете его position: relative;.

затем вы размещаете свои ссылки с изображениями в центре этой оболочки, как по горизонтали, так и по вертикали. Вы делаете это, установив position: absolute; а то top: 50%; left: 50%; и margin: -2em; (где 2em это половина ширины ссылки с изображением, которое я установил, чтобы быть 4em - опять же, вы можете изменить его на все, что вы хотите, но не забудьте изменить маржа в этом случае).

затем вы решаете, под каким углом вы хотите иметь свои ссылки с изображениями и вы добавляете класс deg{desired_angle} (например,deg0 или deg45 или что-то еще). Затем для каждого такого класса вы применяете цепные преобразования CSS, например:

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

где вместо {desired_angle} С 0,45 и так далее...

первое преобразование поворота вращает объект и его оси, преобразование перевода переводит объект вдоль повернутой оси X, а второе преобразование поворота возвращает объект в положение -демо проиллюстрируйте, как это работает.

преимущество этого метода заключается в том, что он является гибким. Вы можете добавлять новые изображения под разными углами без изменения текущей структуры.

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); }

кроме того, вы можете дополнительно упростить HTML, используя фоновые изображения для ссылок вместо использования img метить.


EDIT:пример с резервным вариантом для IE8 и старше (проверено в IE8 и IE7)

вот простое решение без абсолютного позиционирования:

.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/

строя отличный ответ @Ana, я создал эту динамическую версию, которая позволяет добавлять и удалять элементы из DOM и поддерживать пропорциональное расстояние между элементами-Проверьте мою скрипку:https://jsfiddle.net/skwidbreth/q59s90oy/

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, -200px) 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);
});
#list {
  background-color: blue;
  height: 400px;
  width: 400px;
  border-radius: 50%;
  position: relative;
}

.list-item {
  list-style: none;
  background-color: red;
  height: 50px;
  width: 50px;
  position: absolute;
  top: 50%;
  left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<ul id="list"></ul>
<button id="add-item">Add item</button>

нет никакого способа волшебным образом разместить кликабельные элементы в круге вокруг другого элемента с помощью CSS. Способ, как я бы сделал это, используя контейнер с position:relative;. А затем поместите все элементы с position:absolute; и с помощью top и left цель это место.

даже если вы не помещается jquery в ваших тегах для этого лучше всего использовать jQuery / javascript.

первым шагом является размещение вашего центрального изображения идеально в центр контейнера с помощью position:relative;.

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

после этого вы можете разместить другие элементы вокруг него с помощью offset() из centerImage минус offset() контейнера. Давая вам точное top и left изображения.

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. Надеюсь, это поможет.

вы, конечно, можете сделать это с помощью чистого css или использовать JavaScript. Мое предложение:

  • если вы уже знаете, что количество изображений никогда не изменится, просто вычислите свои стили и идите с простым css (плюсы: лучшие характеристики, очень надежные)

  • если число может изменяться либо динамически в вашем приложении, либо просто может изменяться в будущем, перейдите к решению Js (плюсы: более надежное будущее)

у меня была похожая работа, поэтому я создал скрипт и открыл егоздесь, на Github для тех, кому это может понадобиться. Он просто принимает некоторые значения конфигурации и просто выводит код CSS, который вам нужен.

если вы хотите пойти на решение Js вот простой указатель, который может быть полезен для вас. Используя этот html в качестве отправной точки #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;
}

вы можете увидеть живой пример здесь

вы могли бы сделать это вот так: скрипка

Не обращайте внимания на позиционирование, его быстрый пример