javascript 最简单的CSS“红色通知徽章”与计数

gj3fmq9x  于 2023-04-28  发布在  Java
关注(0)|答案(6)|浏览(168)

我需要显示流行的红色通知指示器与计数,如下面所示。得到的东西,看起来不错跨浏览器似乎棘手。例如,不同的浏览器似乎对填充的处理方式不同,导致通知看起来怪异。
什么是最好的跨浏览器方式来确保通知显示得很好?并不反对使用JavaScript,但纯CSS当然更好

uajslkp6

uajslkp61#

最好的方法是使用绝对定位

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

4szc88ey2#

这里有一个包含计数变化时的动画。
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作为动画。

ql3eal8s

ql3eal8s3#

responsive字体相关大小整形解决方案

  • 上图是运行下面的 Live Demo 的快照。向下滚动,自己试试。向下滚动查看当前接受的答案的演示。*

正如其他答案所说,相对定位的父项的绝对定位是将指示器定位在右上角(或您喜欢的任何角落)的非常可靠的方法。
但还有其他非常重要的考虑因素:
1.大小:不仅仅是相对于它所标记的内容,还包括如果数字变长会发生什么?
1.形状:理想情况下是圆形,但如果数字变长会发生什么?
1.浮动外观:它应该看起来漂浮在角落之上,而不是在里面。
1.边框:可选地,根据所涉及的颜色,您可能需要一个微妙的边界或阴影。
1.可访问性:对通知进行适当的标记,以便视力受损者可访问该通知。
像公认的答案那样以px为单位执行上述操作非常混乱、脆弱,而且根本不是responsive
下面的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>

如果它的位置看起来不对,请使用浏览器的开发工具来检查父元素的真实边界。
1.如果您希望无论计数多大,指示器都是圆形,请将min-width更改为width,并将border-radius设置为50%。上面的CSS被设计为在计数变大时水平拉伸,如下所示(就像许多人的收件箱一样🤣)。
1.对于可访问性,您应该在notification元素中包含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>

比较the accepted answer

要查看差异,请运行以下接受答案方法的现场演示:

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>
tv6aics1

tv6aics14#

可能是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>

差不多吧显然,您可能希望更改细节,并可能使用背景图像。重点是强调绝对定位,它在浏览器中确实是一致的,至少在我的经验中是这样。

oyjwcjzk

oyjwcjzk5#

标记:

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

ulmd4ohb6#

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

相关问题