[解決済み] アイコンを円形に配置する
質問
複数の
<img>
要素を配置し、それらの要素をすべてクリック可能なリンクにすることはできますか?下の写真のようにしたいのですが、どうすればそのような効果を得られるのか見当もつきません。
こんなことが可能なのでしょうか?
どのように解決するのですか?
2020年の解決策
私が最近使っている、よりモダンなソリューションを紹介します。
私はまず、画像の配列からHTMLを生成することから始めます。HTMLがPHP、JS、HTMLプリプロセッサなどを使って生成されるかどうかは、背後にある基本的な考え方が同じであるため、あまり重要ではありません。
これを行うPugのコードは以下の通りです。
//- start with an array of images, described by url and alt text
- let imgs = [
- {
- src: 'image_url.jpg',
- alt: 'image alt text'
- } /* and so on, add more images here */
- ];
- let n_imgs = imgs.length;
- let has_mid = 1; /* 0 if there's no item in the middle, 1 otherwise */
- let m = n_imgs - has_mid; /* how many are ON the circle */
- let tan = Math.tan(Math.PI/m); /* tangent of half the base angle */
.container(style=`--m: ${m}; --tan: ${+tan.toFixed(2)}`)
- for(let i = 0; i < n_imgs; i++)
a(href='#' style=i - has_mid >= 0 ? `--i: ${i}` : null)
img(src=imgs[i].src alt=imgs[i].alt)
生成されたHTMLは以下のようになります(もちろん、HTMLを手動で書くこともできますが、後から変更するのが面倒になります)。
<div class="container" style="--m: 8; --tan: 0.41">
<a href='#'>
<img src="image_mid.jpg" alt="alt text"/>
</a>
<a style="--i: 1">
<img src="first_img_on_circle.jpg" alt="alt text"/>
</a>
<!-- the rest of those placed on the circle -->
</div>
CSSでは、画像の大きさを決めて、仮に
8em
. のようにします。
--m
のアイテムは円周上に配置され、それが多角形の端の真ん中にある場合、それは
--m
の辺の中央にあり、その全てが円の接線上にある場合です。
イメージしにくい場合は、次のように遊べます。 インタラクティブデモ で、スライダーをドラッグして辺の数を選ぶと、さまざまな多角形の近円と外接円を作成することができます。
これは、コンテナのサイズは、円の半径の2倍と画像のサイズの半分の2倍でなければならないことを教えてくれます。
私たちはまだ半径を知りませんが、エッジの数を知っていれば計算できます(したがって、ベース角の半分の接線は事前に計算され、カスタム プロパティとして設定されている
--tan
) とポリゴンエッジがわかれば計算できます。ポリゴンの辺は少なくとも画像の大きさにしたいところでしょうが、辺をどれだけ残すかは任意です。例えば、画像の半分の大きさの辺があるとすると、ポリゴンの辺は画像の大きさの2倍になります。そうすると、以下のようなCSSになります。
.container {
--d: 6.5em; /* image size */
--rel: 1; /* how much extra space we want between images, 1 = one image size */
--r: calc(.5*(1 + var(--rel))*var(--d)/var(--tan)); /* circle radius */
--s: calc(2*var(--r) + var(--d)); /* container size */
position: relative;
width: var(--s); height: var(--s);
background: silver /* to show images perfectly fit in container */
}
.container a {
position: absolute;
top: 50%; left: 50%;
margin: calc(-.5*var(--d));
width: var(--d); height: var(--d);
--az: calc(var(--i)*1turn/var(--m));
transform:
rotate(var(--az))
translate(var(--r))
rotate(calc(-1*var(--az)))
}
img { max-width: 100% }
トランスフォームチェーンがどのように機能するかの説明については、古い解答を参照してください。
この方法では、画像の配列から画像を追加または削除すると、自動的に新しい数の画像が等間隔になるように円周上に配置され、コンテナのサイズも調整されます。これをテストするには このデモ .
旧解答 (歴史的な理由で保存されています)
はい、それは非常に可能であり、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軸に沿ってオブジェクトを並進させ、2番目の回転変換はオブジェクトを元の位置に戻す。
この方法の利点は、柔軟性があることです。現在の構造を変更することなく、異なる角度の新しい画像を追加することができます。
コード・スニペット
.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); }
<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>
また、リンクの背景画像に
img
タグを使用する代わりに、リンクに背景画像を使用することで、さらにHTMLを簡素化できます。
EDIT : IE8 およびそれ以前のフォールバックの例 (IE8とIE7でテスト済み)
関連
-
[解決済み】ある要素を別の要素に移動させるには?
-
[解決済み】divの高さを画面の残りスペースで埋めるようにする
-
[解決済み] 横型リストアイテム
-
[解決済み] リスト項目にマウスを置いたときに、カーソルを手の形に変えるには?
-
[解決済み] コンテナの幅に応じたフォントの拡大縮小
-
[解決済み] HTMLにPDFを埋め込むおすすめの方法とは?
-
[解決済み] 入力フィールドに :before や :after 疑似要素を使用できますか?
-
[解決済み] HTML5 CanvasとSVGとdivの比較
-
[解決済み] コンテナに対する要素の相対位置
-
[解決済み] Font Awesomeのアイコンを円形にする?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] BootstrapのCollapse Navbarが動作しない
-
[解決済み] CSS - カーソルを置いたときに塗りつぶしの色を変更する - SVG PATH
-
[解決済み] <button> vs. <input type="button" />. Which to use?
-
[解決済み] HTMLページからのリダイレクト
-
[解決済み] HTMLの "role "属性は何のためにあるのですか?
-
[解決済み] mailto:を使ってメールの件名や内容を設定することはできますか?
-
[解決済み] CSSだけでリンクを無効化する方法
-
[解決済み] HTMLのid属性とname属性の違い
-
[解決済み] HTML5で(非空白の)自己閉鎖タグは有効ですか?
-
[解決済み] 検索エンジンはAngularJSアプリケーションをどのように扱っているのか?