我需要显示带有计数的流行红色通知指示器,如下所示。获得跨浏览器看起来不错的东西似乎很棘手。例如,不同的浏览器似乎以不同的方式对待填充,从而导致看起来很奇怪的通知。
确保通知良好显示的最佳跨浏览器方式是什么?不反对使用 javascript,但纯 css 当然更好
实现此目的的最佳方法是使用绝对定位:
/* Create the blue navigation bar */
.navbar {
background-color: #3b5998;
font-size: 22px;
padding: 5px 10px;
}
/* Define what each icon button should look like */
.button {
color: white;
display: inline-block; /* Inline elements with width and height. TL;DR they make the icon buttons stack from left-to-right instead of top-to-bottom */
position: relative; /* All 'absolute'ly positioned elements are relative to this one */
padding: 2px 5px; /* Add some padding so it looks nice */
}
/* Make the badge float in the top right corner of the button */
.button__badge {
background-color: #fa3e3e;
border-radius: 2px;
color: white;
padding: 1px 3px;
font-size: 10px;
position: absolute; /* Position the badge within the relatively positioned button */
top: 0;
right: 0;
}
<!-- Font Awesome is a great free icon font. -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet"/>
<div class="navbar">
<div class="button">
<i class="fa fa-globe"></i>
<span class="button__badge">2</span>
</div>
<div class="button">
<i class="fa fa-comments"></i>
<span class="button__badge">4</span>
</div>
</div>
这是一个包含计数变化时的动画的动画。
http://jsfiddle.net/rahilsondhi/FdmHf/4/
<ul>
<li class="notification-container">
<i class="icon-globe"></i>
<span class="notification-counter">1</span>
</li>
.notification-container {
position: relative;
width: 16px;
height: 16px;
top: 15px;
left: 15px;
i {
color: #fff;
}
}
.notification-counter {
position: absolute;
top: -2px;
left: 12px;
background-color: rgba(212, 19, 13, 1);
color: #fff;
border-radius: 3px;
padding: 1px 3px;
font: 8px Verdana;
}
$counter
.css({opacity: 0})
.text(val)
.css({top: '-10px'})
.transition({top: '-2px', opacity: 1})
$('button').click(function()
{
var $counter = $('.notification-counter')
var val = parseInt $counter.text();
val++;
$counter.css({opacity: 0}).text(val).css({top:'-10px'}).animate({top: '-1px', opacity: 1}, 500);
});
它使用 Font Awesome 作为地球图标,使用 jQuery Transit 作为动画。
上图是运行下面的Live Demo的快照。向下滚动并亲自尝试一下。进一步向下滚动以查看当前接受的答案的演示。
正如其他答案所说,相对定位的父级的绝对定位是将指示器定位在右上角(或您喜欢的任何角)的非常可靠的方法。
但是还有其他非常重要的考虑因素:
按照接受的答案以
px
单位执行上述操作非常混乱、脆弱,而且根本不响应。
以下 CSS 以优雅的响应方式解决了上述所有问题:
.notification {
/* circle shape, size and position */
position: absolute;
right: -0.7em;
top: -0.7em;
min-width: 1.6em; /* or width, explained below. */
height: 1.6em;
border-radius: 0.8em; /* or 50%, explained below. */
border: 0.05em solid white;
background-color: red;
/* number size and position */
display: flex;
justify-content: center;
align-items: center;
font-size: 0.8em;
color: white;
}
关键事项:
具有
.notification
类的元素将显示在包含它的元素的右上角。
例如会显示在右上角 这个邮箱按钮:
<button class="mailbox">📥 Inbox
<div class="notification" role="status">42</div>
</button>
如果它的位置看起来不对,请使用浏览器的调试 开发工具来检查父元素的真实边界。
如果您希望无论计数有多大,指示器都是圆形,请将
min-width
更改为 width
并将 border-radius
设置为 50%
。上面的 CSS 设计为在计数变大时水平拉伸,如下所示(就像很多人的收件箱🤣)。
为了实现可访问性,您应该在通知元素上包含
role="status"
,如上所示。
这是一个现场演示,以及一个滑块,以便您可以看到它如何响应字体大小的变化:
/* IGNORE this Javascript part.
It's just here to let you change the size with
a slider. Press Run and try it. */
var boxes = document.getElementsByClassName("mailbox");
function updateFontSize(size) {
for (var i = 0; i < boxes.length; i++) {
boxes[i].style.fontSize = size + "px";
}
}
var px = getComputedStyle(boxes[0]).fontSize
var label = document.getElementById("label");
label.innerHTML = px
var slider = document.getElementById('slider');
slider.value = px.slice(0, -2)
slider.onchange = () => {
label.innerHTML = slider.value + "px";
updateFontSize(slider.value);
}
.mailbox {
position: relative;
font-size: 16px;
line-height: 2.5em;
margin: 0.3em;
}
.notification {
/* circle shape, size and position */
position: absolute;
right: -0.7em;
top: -0.7em;
min-width: 1.6em; /* or width, explained below. */
height: 1.6em;
border-radius: 0.8em; /* or 50%, explained below. */
border: 0.05em solid white;
background-color: red;
/* number size and position */
display: flex;
justify-content: center;
align-items: center;
font-size: 0.8em;
color: white;
}
<p>Font size:
<span id="label">16</span>
<input id="slider" type="range" min="6" max="66" step="1" value="16"></p>
<button class="mailbox">📨 Unread
<div class="notification" role="status">3</div>
</button>
<button class="mailbox">📥 Inbox
<div class="notification" role="status">42</div>
</button>
<button class="mailbox">🗑 Junk
<div class="notification" role="status">1630</div>
</button>
要查看差异,请运行已接受答案方法的现场演示:
var boxes = document.getElementsByClassName("mailbox");
function updateFontSize(size) {
for (var i = 0; i < boxes.length; i++) {
boxes[i].style.fontSize = size + "px";
}
}
var px = getComputedStyle(boxes[0]).fontSize
var label = document.getElementById("label");
label.innerHTML = px
var slider = document.getElementById('slider');
slider.value = px.slice(0, -2)
slider.onchange = () => {
label.innerHTML = slider.value + "px";
updateFontSize(slider.value);
}
.mailbox {
display: inline-block;
position: relative;
padding: 10px 10px;
font-size: 16px;
}
.notification {
background-color: #fa3e3e;
border-radius: 2px;
color: white;
padding: 1px 3px;
font-size: 10px;
position: absolute;
top: 0;
right: 0;
}
<p>Font size:
<span id="label">16</span>
<input id="slider" type="range" min="6" max="66" step="1" value="16"></p>
<button class="mailbox">📨 Unread
<div class="notification" role="status">3</div>
</button>
<button class="mailbox">📥 Inbox
<div class="notification" role="status">42</div>
</button>
<button class="mailbox">🗑 Junk
<div class="notification" role="status">1630</div>
</button>
大概
absolute
定位:
<div id="globe" style="height: 30px; width: 30px; position: relative;">
<img src="/globe.gif" />
<div id="notification" style="position: absolute; top: 0; right: 0;">1</div>
</div>
类似这样的事情。显然,您想要更改细节并可能使用背景图像。重点是强调绝对定位,它在不同浏览器中确实一致,至少在我的经验中是这样。
标记:
<div id="ContainerDiv">
<div id="MainImageDiv"> //Add the image here or whatever you want </div>
<div id="NotificationDiv"> </div>
</div>
CSS:
#NotificationDiv {
position: absolute;
left: -10 //use negative values to push it above the #MainImageDiv
top: -4
...
}
我确信关于绝对定位的答案是正确的。为了进行实验,我尝试制作一个仅 SVG 的解决方案。结果远非理想,也许有人知道类似 svg 拼图的更优雅的解决方案? :)
http://jsfiddle.net/gLdsco5p/3/
<svg width="64" height="64" viewBox="0 0 91 91">
<rect id="Artboard1" x="0" y="0" width="90.326" height="90.326" style="fill:none;"/>
<g id="Artboard11" serif:id="Artboard1">
<g id="user-circle-o" transform="matrix(2.69327,0,0,2.69327,7.45723,7.45723)">
<path d="M14,0C21.734,0 28,6.266 28,14C28,21.688 21.766,28 14,28C6.25,28 0,21.703 0,14C0,6.266 6.266,0 14,0ZM23.672,21.109C25.125,19.109 26,16.656 26,14C26,7.391 20.609,2 14,2C7.391,2 2,7.391 2,14C2,16.656 2.875,19.109 4.328,21.109C4.89,18.312 6.25,16 9.109,16C10.375,17.234 12.093,18 14,18C15.907,18 17.625,17.234 18.891,16C21.75,16 23.11,18.312 23.672,21.109ZM20,11C20,7.687 17.312,5 14,5C10.688,5 8,7.688 8,11C8,14.312 10.688,17 14,17C17.312,17 20,14.312 20,11Z" style="fill:rgb(190,190,190);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,1.36156,0)">
<circle cx="63.708" cy="18.994" r="9.549" style="fill:rgb(255,0,0);"/>
</g>
<g transform="matrix(1.66713,0,0,1.66713,-51.5278,-2.33264)">
<text id="counter" x="68.034px" y="15.637px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:7.915px;fill:white;">1</text>
</g>
</g>
</svg>
一个新的简单解决方案。
今天我们有新的 CSS 工具,例如:
基本上我们可以只拥有一个带有“data”属性的 html 元素,其余的由 css 完成。
a[data-badge-count]:after{
color:white;
content: attr(data-badge-count);
display: inline-block;
clip-path: circle(8px at 9.5px 8px);
background-color: #ff4c4c;
vertical-align: middle;
margin-left: 5px;
height: 30px;
width: 20px;
text-align: center;
font-size: 0.8em;
}
<div>
<a data-badge-count="2">my link</a>
</div>