创建三角菜单
Create Triangle Menu
我正在尝试创建一个菜单,其中包含组合在一起形成正方形的直角三角形。这就是我的设想:
这是我希望实现的:
- 可以通过javascript动态生成。
- 扩展到父级
- 为每个三角形剪下一张图片作为背景(不能是CSS)
- Link 每个三角形一个站点
- 悬停时更新背景和文本颜色
- 支持多种浏览器
我尝试了几种不同的方法,但每一种都遇到了几个问题:
- CSS 破解:
- 无法将文本设置到正确的位置
- 无法单独设置边框
- SVG
- 悬停时无法更新颜色。我得到的最近的是这里:https://jsfiddle.net/71xp6r0s
<div class="menu-box">
<svg id="menu" style="border: black solid 1px" width="100" height="100" viewbox="0, 0, 100, 100">
<polygon class = "top" points='0,0 0,100 100,0' fill="none" stroke="red"/>
<text x="-18" y="68" fill="black" transform="rotate(-45)">Item</text>
<polygon points='100,0 100,100 0,100' fill="none" stroke="red" />
<text x="-18" y="84" fill="black" transform="rotate(-45)">Item</text>
</svg>
</div>
- Canvas
- 难以动态调整到父级
- 剪辑路径:
- 大多数浏览器不支持。
我知道这很有野心,但我们将不胜感激。我也对其他想法持开放态度,但这些是我在网上找到的。
编辑:切换到更好的图像
这里有一个使用倾斜变换的想法:
* {
box-sizing: border-box;
}
.menu {
width: 150px;
border: 1px solid;
overflow: hidden;
display: flex;
justify-content: center;
}
/*maitain ratio*/
.menu:before {
content: "";
padding-top: 100%;
}
.menu a {
position:relative;
width: 100%;
flex-shrink: 0;
border: 3px solid red;
transform: skew(-45deg);
overflow:hidden;
color:#fff;
font-weight:bold;
font-size:18px;
}
.menu a:first-child span {
position: absolute;
bottom:0;
left: 50%;
width: 141%;
display: block;
text-align: center;
transform-origin: 86% 100%;
transform: translate(-50%) skew(45deg) rotate(-45deg) translateX(86%);
}
.menu a:last-child span {
position: absolute;
top:0;
left: 50%;
width: 141%;
display: block;
text-align: center;
transform-origin: 14% 0%;
transform: translateX(-50%) skew(45deg) rotate(-45deg) translateX(-86%);
}
.menu a:before {
content:"";
position:absolute;
top:0;
left:-50%;
right:-50%;
bottom:0;
background:url(https://picsum.photos/id/1069/500/500) center/cover;
transform: skew(45deg);
}
.menu a:last-child:before {
background:url(https://picsum.photos/id/1059/500/500) center/cover;
}
/*Hover */
.menu a:hover {
color:green;
border-color:yellow;
}
.menu a:hover:before {
filter:grayscale(100%);
}
<div class="menu">
<a href="#"><span>Link 1</span></a>
<a href="#"><span>Link 2</span></a>
</div>
<div class="menu" style="width:200px">
<a href="#"><span>Link 1</span></a>
<a href="#"><span>Link 2</span></a>
</div>
<div class="menu" style="width:250px">
<a href="#"><span>Link 1</span></a>
<a href="#"><span>Link 2</span></a>
</div>
也可以直接在HTML代码中指定图片
* {
box-sizing: border-box;
}
.menu {
width: 150px;
border: 1px solid;
overflow: hidden;
display: flex;
justify-content: center;
}
/*maitain ratio*/
.menu:before {
content: "";
padding-top: 100%;
}
.menu a {
position:relative;
width: 100%;
flex-shrink: 0;
border: 3px solid red;
transform: skew(-45deg);
overflow:hidden;
color:#fff;
font-weight:bold;
font-size:18px;
background-size:0 0;
}
.menu a:first-child span {
position: absolute;
bottom:0;
left: 50%;
width: 141%;
display: block;
text-align: center;
transform-origin: 86% 100%;
transform: translate(-50%) skew(45deg) rotate(-45deg) translateX(86%);
}
.menu a:last-child span {
position: absolute;
top:0;
left: 50%;
width: 141%;
display: block;
text-align: center;
transform-origin: 14% 0%;
transform: translateX(-50%) skew(45deg) rotate(-45deg) translateX(-86%);
}
.menu a:before {
content:"";
position:absolute;
top:0;
left:-50%;
right:-50%;
bottom:0;
background-image:inherit;
background-position:center;
background-size:cover;
transform: skew(45deg);
}
/*Hover */
.menu a:hover {
color:green;
border-color:yellow;
}
.menu a:hover:before {
filter:grayscale(100%);
}
<div class="menu">
<a href="#" style="background-image:url(https://picsum.photos/id/1069/500/500)"><span>Link 1</span></a>
<a href="#" style="background-image:url(https://picsum.photos/id/1049/500/500)"><span>Link 2</span></a>
</div>
<div class="menu" style="width:200px">
<a href="#" style="background-image:url(https://picsum.photos/id/1063/500/500)"><span>Link 1</span></a>
<a href="#" style="background-image:url(https://picsum.photos/id/1069/500/500)"><span>Link 2</span></a>
</div>
<div class="menu" style="width:250px">
<a href="#" style="background-image:url(https://picsum.photos/id/109/500/500)"><span>Link 1</span></a>
<a href="#" style="background-image:url(https://picsum.photos/id/1069/500/500)"><span>Link 2</span></a>
</div>
SVG 永远是你最好的选择(根据我的经验)
SVG Cannot update coloring when hovering. Closest I got was here:
https://jsfiddle.net/71xp6r0s
SVG:
<div class="menu-box">
<svg id="menu" style="border: black solid 1px" width="100" height="100" viewbox="0, 0, 100, 100">
<defs>
<pattern id="pattern1" height="100%" width="100%" patternContentUnits="objectBoundingBox">
<image height="1" width="1" preserveAspectRatio="none" xlink:href="https://media.self.com/photos/5b76faf02efd8652915489f5/4:3/w_752,c_limit/4.jpg" />
</pattern>
<pattern id="pattern2" height="100%" width="100%" patternContentUnits="objectBoundingBox">
<image height="1" width="1" preserveAspectRatio="none" xlink:href="https://images2.minutemediacdn.com/image/upload/c_crop,h_2914,w_5184,x_0,y_271/f_auto,q_auto,w_1100/v1566921972/shape/mentalfloss/598021-gettyimages-965401258.jpg" />
</pattern>
</defs>
<a href="https://www.google.com">
<polygon fill="url(#pattern1)" id="poly1" class = "top" points='0,0 0,100 100,0' stroke="red"/>
</a>
<text x="-18" y="68" fill="black" transform="rotate(-45)">Item</text>
<a href="https://www.google.com">
<polygon fill="url(#pattern2)" id="poly2" points='100,0 100,100 0,100' stroke="red" />
</a>
<text x="-18" y="84" fill="black" transform="rotate(-45)">Item</text>
</svg>
</div>
CSS:
.menu {
display: relative;
}
.menu .top {
background-color: black;
}
.menu .item {
clip-path: polygon("0 0, 0 100%, 100% 100%");
}
#poly1:hover{
fill:red;
}
#poly2:hover{
fill:purple
}
我正在尝试创建一个菜单,其中包含组合在一起形成正方形的直角三角形。这就是我的设想:
这是我希望实现的:
- 可以通过javascript动态生成。
- 扩展到父级
- 为每个三角形剪下一张图片作为背景(不能是CSS)
- Link 每个三角形一个站点
- 悬停时更新背景和文本颜色
- 支持多种浏览器
我尝试了几种不同的方法,但每一种都遇到了几个问题:
- CSS 破解:
- 无法将文本设置到正确的位置
- 无法单独设置边框
- SVG
- 悬停时无法更新颜色。我得到的最近的是这里:https://jsfiddle.net/71xp6r0s
<div class="menu-box">
<svg id="menu" style="border: black solid 1px" width="100" height="100" viewbox="0, 0, 100, 100">
<polygon class = "top" points='0,0 0,100 100,0' fill="none" stroke="red"/>
<text x="-18" y="68" fill="black" transform="rotate(-45)">Item</text>
<polygon points='100,0 100,100 0,100' fill="none" stroke="red" />
<text x="-18" y="84" fill="black" transform="rotate(-45)">Item</text>
</svg>
</div>
- Canvas
- 难以动态调整到父级
- 剪辑路径:
- 大多数浏览器不支持。
我知道这很有野心,但我们将不胜感激。我也对其他想法持开放态度,但这些是我在网上找到的。
编辑:切换到更好的图像
这里有一个使用倾斜变换的想法:
* {
box-sizing: border-box;
}
.menu {
width: 150px;
border: 1px solid;
overflow: hidden;
display: flex;
justify-content: center;
}
/*maitain ratio*/
.menu:before {
content: "";
padding-top: 100%;
}
.menu a {
position:relative;
width: 100%;
flex-shrink: 0;
border: 3px solid red;
transform: skew(-45deg);
overflow:hidden;
color:#fff;
font-weight:bold;
font-size:18px;
}
.menu a:first-child span {
position: absolute;
bottom:0;
left: 50%;
width: 141%;
display: block;
text-align: center;
transform-origin: 86% 100%;
transform: translate(-50%) skew(45deg) rotate(-45deg) translateX(86%);
}
.menu a:last-child span {
position: absolute;
top:0;
left: 50%;
width: 141%;
display: block;
text-align: center;
transform-origin: 14% 0%;
transform: translateX(-50%) skew(45deg) rotate(-45deg) translateX(-86%);
}
.menu a:before {
content:"";
position:absolute;
top:0;
left:-50%;
right:-50%;
bottom:0;
background:url(https://picsum.photos/id/1069/500/500) center/cover;
transform: skew(45deg);
}
.menu a:last-child:before {
background:url(https://picsum.photos/id/1059/500/500) center/cover;
}
/*Hover */
.menu a:hover {
color:green;
border-color:yellow;
}
.menu a:hover:before {
filter:grayscale(100%);
}
<div class="menu">
<a href="#"><span>Link 1</span></a>
<a href="#"><span>Link 2</span></a>
</div>
<div class="menu" style="width:200px">
<a href="#"><span>Link 1</span></a>
<a href="#"><span>Link 2</span></a>
</div>
<div class="menu" style="width:250px">
<a href="#"><span>Link 1</span></a>
<a href="#"><span>Link 2</span></a>
</div>
也可以直接在HTML代码中指定图片
* {
box-sizing: border-box;
}
.menu {
width: 150px;
border: 1px solid;
overflow: hidden;
display: flex;
justify-content: center;
}
/*maitain ratio*/
.menu:before {
content: "";
padding-top: 100%;
}
.menu a {
position:relative;
width: 100%;
flex-shrink: 0;
border: 3px solid red;
transform: skew(-45deg);
overflow:hidden;
color:#fff;
font-weight:bold;
font-size:18px;
background-size:0 0;
}
.menu a:first-child span {
position: absolute;
bottom:0;
left: 50%;
width: 141%;
display: block;
text-align: center;
transform-origin: 86% 100%;
transform: translate(-50%) skew(45deg) rotate(-45deg) translateX(86%);
}
.menu a:last-child span {
position: absolute;
top:0;
left: 50%;
width: 141%;
display: block;
text-align: center;
transform-origin: 14% 0%;
transform: translateX(-50%) skew(45deg) rotate(-45deg) translateX(-86%);
}
.menu a:before {
content:"";
position:absolute;
top:0;
left:-50%;
right:-50%;
bottom:0;
background-image:inherit;
background-position:center;
background-size:cover;
transform: skew(45deg);
}
/*Hover */
.menu a:hover {
color:green;
border-color:yellow;
}
.menu a:hover:before {
filter:grayscale(100%);
}
<div class="menu">
<a href="#" style="background-image:url(https://picsum.photos/id/1069/500/500)"><span>Link 1</span></a>
<a href="#" style="background-image:url(https://picsum.photos/id/1049/500/500)"><span>Link 2</span></a>
</div>
<div class="menu" style="width:200px">
<a href="#" style="background-image:url(https://picsum.photos/id/1063/500/500)"><span>Link 1</span></a>
<a href="#" style="background-image:url(https://picsum.photos/id/1069/500/500)"><span>Link 2</span></a>
</div>
<div class="menu" style="width:250px">
<a href="#" style="background-image:url(https://picsum.photos/id/109/500/500)"><span>Link 1</span></a>
<a href="#" style="background-image:url(https://picsum.photos/id/1069/500/500)"><span>Link 2</span></a>
</div>
SVG 永远是你最好的选择(根据我的经验)
SVG Cannot update coloring when hovering. Closest I got was here: https://jsfiddle.net/71xp6r0s
SVG:
<div class="menu-box">
<svg id="menu" style="border: black solid 1px" width="100" height="100" viewbox="0, 0, 100, 100">
<defs>
<pattern id="pattern1" height="100%" width="100%" patternContentUnits="objectBoundingBox">
<image height="1" width="1" preserveAspectRatio="none" xlink:href="https://media.self.com/photos/5b76faf02efd8652915489f5/4:3/w_752,c_limit/4.jpg" />
</pattern>
<pattern id="pattern2" height="100%" width="100%" patternContentUnits="objectBoundingBox">
<image height="1" width="1" preserveAspectRatio="none" xlink:href="https://images2.minutemediacdn.com/image/upload/c_crop,h_2914,w_5184,x_0,y_271/f_auto,q_auto,w_1100/v1566921972/shape/mentalfloss/598021-gettyimages-965401258.jpg" />
</pattern>
</defs>
<a href="https://www.google.com">
<polygon fill="url(#pattern1)" id="poly1" class = "top" points='0,0 0,100 100,0' stroke="red"/>
</a>
<text x="-18" y="68" fill="black" transform="rotate(-45)">Item</text>
<a href="https://www.google.com">
<polygon fill="url(#pattern2)" id="poly2" points='100,0 100,100 0,100' stroke="red" />
</a>
<text x="-18" y="84" fill="black" transform="rotate(-45)">Item</text>
</svg>
</div>
CSS:
.menu {
display: relative;
}
.menu .top {
background-color: black;
}
.menu .item {
clip-path: polygon("0 0, 0 100%, 100% 100%");
}
#poly1:hover{
fill:red;
}
#poly2:hover{
fill:purple
}