带有计数的“红色通知徽章”最简单的CSS

问题描述 投票:0回答:7

我需要显示带有计数的流行红色通知指示器,如下所示。获得跨浏览器看起来不错的东西似乎很棘手。例如,不同的浏览器似乎以不同的方式对待填充,从而导致看起来很奇怪的通知。

确保通知良好显示的最佳跨浏览器方式是什么?不反对使用 javascript,但纯 css 当然更好

enter image description here

javascript html css notifications css-position
7个回答
185
投票

实现此目的的最佳方法是使用绝对定位

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


37
投票

这是一个包含计数变化时的动画的动画。

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

使用 jQuery 制作动画:

$('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 作为动画。


16
投票

使用字体相对大小和形状的响应式解决方案

enter image description here

上图是运行下面的Live Demo的快照。向下滚动并亲自尝试一下。进一步向下滚动以查看当前接受的答案的演示。

正如其他答案所说,相对定位的父级的绝对定位是将指示器定位在右上角(或您喜欢的任何角)的非常可靠的方法。

但是还有其他非常重要的考虑因素:

  1. 大小:不仅与它的标签相关,而且还与数字变长时会发生什么有关?
  2. 形状:理想情况下是圆形,但是如果数字变长会发生什么?
  3. 浮动外观:它应该看起来漂浮在角落上方,而不是在里面。
  4. 边框:可选,根据涉及的颜色,您可能需要微妙的边框或阴影。
  5. 辅助功能:正确标记通知,以便视力障碍者可以访问。

按照接受的答案以

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

关键事项:

  1. 具有

    .notification
    类的元素将显示在包含它的元素的右上角。

    例如会显示在右上角 这个邮箱按钮:

    <button class="mailbox">📥 Inbox
        <div class="notification" role="status">42</div>
    </button>
    

    如果它的位置看起来不对,请使用浏览器的调试 开发工具来检查父元素的真实边界。

  2. 如果您希望无论计数有多大,指示器都是圆形,请将

    min-width
    更改为
    width
    并将
    border-radius
    设置为
    50%
    。上面的 CSS 设计为在计数变大时水平拉伸,如下所示(就像很多人的收件箱🤣)。

  3. 为了实现可访问性,您应该在通知元素上包含

    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>


4
投票

大概

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>

类似这样的事情。显然,您想要更改细节并可能使用背景图像。重点是强调绝对定位,它在不同浏览器中确实一致,至少在我的经验中是这样。


1
投票

标记:

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

1
投票

我确信关于绝对定位的答案是正确的。为了进行实验,我尝试制作一个仅 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>

0
投票

一个新的简单解决方案。

今天我们有新的 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>

© www.soinside.com 2019 - 2024. All rights reserved.