quiz
quiz copied to clipboard
CSS基础测试2
本期小测题目如下图:
完全CSS实现,尝试考虑一些边界场景,以及其它一些可以对体验有帮助的处理。
大家的CSS代码注意顶边缩进,github自带代码高亮,可以使用下面的格式:
```css /* 你的CSS代码在这里 */ ```
.icon-delete {
margin-top: 2em;
display: inline-block;
display: flex;
flex-wrap: nowrap;
max-width: 2em;
position: relative;
}
.icon-delete::before {
display: inline-block;
visibility: hidden;
content: attr(data-title);
background: #000;
color: white;
max-width: 2em;
white-space: nowrap;
border-radius: 5px;
padding: 4px;
position: absolute;
top: -2em;
left: 50%;
transform: translateX(-50%)
}
.icon-delete::after {
display: inline-block;
visibility: hidden;
content: '';
width: 0;
height: 0;
border: .5em solid;
border-color: #000 transparent transparent;
position: absolute;
top: calc(-0.5em + 4px);
left: 50%;
transform: translateX(-50%)
}
a:hover::before, a:hover::after {
visibility: visible;
}
绞尽脑汁也没想到怎么用 css 去做边界的问题.....
body{
padding: 30px;
}
.icon-delete::after{
content:"\27F0";
font-size: initial;
}
.css-tips{
position: relative;
font-size: 0;
cursor: pointer;
}
.css-tips:hover::before{
content:attr(data-title);
position: absolute;
margin-left: 50%;
transform: translate(-50%,-2.5em);
padding: 4px 4px 10px;
color: #fff;
font-size: 12px;
white-space: nowrap;
background: #000;
clip-path:
polygon(
0 0,
100% 0,
100% calc(100% - 6px),
calc(50% + 4px ) calc(100% - 6px),
50% 100%,
calc(50% - 4px ) calc(100% - 6px),
0 calc(100% - 6px)
);
}
.css-tips:hover::before {
content: attr(data-title);
position: absolute;
transform: translateY(-100%) translateY(-0.3em) translateX(-0.5em);
width: 2em;
padding: 0.2em 0.5em;
border-radius:0.2em;
background: #000;
color: #fff;
}
.css-tips:hover::after {
content: '';
position: absolute;
transform: translateY(-50%) translateX(-1.5em);
border: 0.5em solid;
border-color: #000 transparent transparent transparent;
}
.css-tips{
position: relative;
}
目前归类了如下几种场景(可补充)
- 方向(上右下左)
- 多文本
- 类型(警示,温馨,危险)
属性 | 描述 | 用法 |
---|---|---|
data-title-dir |
规定提示的方向,可以取值top (默认)、right 、bottom 、left |
<span class="css-tips" data-title="删除删除删除" data-title-dir="up">提示上</span> |
data-title-muti |
适用于提示文本较多的情况,自动换行 | <span class="css-tips" data-title="删除删除删除删除删除删除删除删除删除" data-title-dir="right" data-title-muti>多行提示</span> |
data-title-type |
选择提示的类型,即不同的背景颜色,默认为暗灰色,可以取值success 、error 、warn |
<span class="css-tips" data-title="删除删除删除删除" data-title-type="warn">警告提示</span> |
以上不同属性可以组合使用
<span class="css-tips"
data-title="删除删除删除删除删除删除删除删除删除"
data-title-dir="right"
data-title-type="warn"
data-title-muti
>
多行提示
</span>
源码
[data-title] {
position: relative;
overflow: visible;
}
.css-tips[data-title]:before,
.css-tips[data-title]:after {
display: block;
position: absolute;
z-index: 1;
left: 50%;
bottom: 100%;
transform: translate(-50%, -20px);
opacity: 0;
transition: .15s .15s;
color: #373c42;
visibility: hidden;
}
.css-tips[data-title]:before {
content: attr(data-title);
border-radius: 3px;
padding: 6px 10px;
line-height: 18px;
text-align: left;
background-color: #373c42;
color: #fff;
font-size: 12px;
font-style: normal;
white-space: nowrap;
}
.css-tips[data-title]:after {
content: '';
width: 0;
height: 0;
margin-bottom: -12px;
overflow: hidden;
border: 6px solid transparent;
border-top-color: currentColor;
}
.css-tips[data-title]:hover:before,
.css-tips[data-title]:hover:after {
visibility: visible;
transform: translate(-50%, -10px);
opacity: 1;
}
/* right */
.css-tips[data-title][data-title-dir="right"]:before,
.css-tips[data-title][data-title-dir="right"]:after{
left: 100%;
top: 50%;
bottom: auto;
transform: translate(20px, -50%);
}
.css-tips[data-title][data-title-dir="right"]:after {
margin: 0;
margin-left: -12px;
border-color: transparent;
border-right-color: currentColor;
}
.css-tips[data-title][data-title-dir="right"]:hover:before,
.css-tips[data-title][data-title-dir="right"]:hover:after {
visibility: visible;
transform: translate(10px, -50%);
opacity: 1;
}
/* bottom */
.css-tips[data-title][data-title-dir="bottom"]:before,
.css-tips[data-title][data-title-dir="bottom"]:after{
left: 50%;
top: 100%;
bottom: auto;
transform: translate(-50%, 20px);
}
.css-tips[data-title][data-title-dir="bottom"]:after {
margin: 0;
margin-top: -12px;
border-color: transparent;
border-bottom-color: currentColor;
}
.css-tips[data-title][data-title-dir="bottom"]:hover:before,
.css-tips[data-title][data-title-dir="bottom"]:hover:after {
visibility: visible;
transform: translate(-50%, 10px);
opacity: 1;
}
/* left */
.css-tips[data-title][data-title-dir="left"]:before,
.css-tips[data-title][data-title-dir="left"]:after{
left: auto;
right: 100%;
top: 50%;
bottom: auto;
transform: translate(-20px, -50%);
}
.css-tips[data-title][data-title-dir="left"]:after {
margin: 0;
margin-right: -12px;
border-color: transparent;
border-left-color: currentColor;
}
.css-tips[data-title][data-title-dir="left"]:hover:before,
.css-tips[data-title][data-title-dir="left"]:hover:after {
visibility: visible;
transform: translate(-10px, -50%);
opacity: 1;
}
/* muti */
.css-tips[data-title][data-title-muti]:before {
width: 150px;
white-space: normal;
}
/* success */
.css-tips[data-title][data-title-type="success"]:before {
background-color: #52c41a;
}
.css-tips[data-title][data-title-type="success"]:after {
color:#52c41a;
}
/* error */
.css-tips[data-title][data-title-type="error"]:before {
background-color: #f5222d;
}
.css-tips[data-title][data-title-type="error"]:after {
color:#f5222d;
}
/* warn */
.css-tips[data-title][data-title-type="warn"]:before {
background-color: #faad14;
}
.css-tips[data-title][data-title-type="warn"]:after {
color:#faad14;
}
预览
.css-tips {
position: relative;
cursor: pointer;
&:hover {
&::before {
position: absolute;
top: -25px;
font-size: 12px;
box-sizing: border-box;
width: max-content;
height: auto;
min-height: 20px;
padding: 0 5px;
content: attr(data-title);
color: #fff;
border-radius: 2px;
background-color: rgba(0, 0, 0, 1);
}
&::after {
position: absolute;
top: -5px;
left: 50%;
width: 0;
height: 0;
content: ' ';
transform: translateX(-50%);
border-top: 3px solid rgba(0, 0, 0, 1);
border-right: 3px solid transparent;
border-left: 3px solid transparent;
}
}
}
body{
margin: 0;
}
a{
position: relative;
text-decoration: none;
width: 1em;
display: inline-block;
/*用margin来限制边界,确报提示框不会超出视野*/
margin: 2em 1em;
}
a::before{
content: "";
width: 0;
border-style: solid;
border-width: 1em 0.5em 0 0.5em;
border-color: #000 transparent transparent transparent;
position: absolute;
top: -1em;
display: none;
}
a::after{
content: attr(data-title);
position: absolute;
top: -2em;
left: -0.9em;
word-break: keep-all;
background-color: #000;
padding: 0.2em 0.4em;
color: #fff;
border-radius: 0.2em;
line-height: 1;
display: none;
}
a:hover::before,a:hover::after{
display: block;
}
.icon-delete {
display: inline-block;
background: url(https://i.loli.net/2019/01/31/5c529425d2a92.png) 0 0/contain no-repeat;
text-indent: -9999px;
}
.css-tips:hover::before, .css-tips:hover::after {
position: absolute;
left: 50%;
bottom: 100%;
}
.css-tips:hover::before {
content: attr(data-title);
padding: .2em .5em;
text-indent: 0;
border-radius: .2em;
background: #000;
white-space: nowrap;
color: #fff;
transform: translate(-50%, -.4em);
}
.css-tips:hover::after {
content: '';
transform: translate(-50%, .35em);
border: 0.5em solid;
border-color: #000 transparent transparent transparent;
}
.css-tips{
position: relative;
font-size: 16px;
}
楼上一些回复忘了隐藏文字的问题,不过出题时保留「删除」二字的必要性何在呢?如果为了 accessibility ,屏幕阅读器应该会读出 <a> 标签的 title 属性的(参考知乎回答),写在那里会方便处理一些。
demo: JSFiddle
/* 一个图标字体,「删」字是图标,「除」字是零宽度字符 */
@font-face {
font-family: shanchu;
src: url('data:application/font-woff;base64,d09GRgABAAAAAAT8AA4AAAAABxgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAE4AAAABwAAAAchpT840dERUYAAATIAAAAGAAAABwAFQAUT1MvMgAAAbgAAABLAAAAYLJNCARjbWFwAAACGAAAAEYAAAFK2r0Rm2N2dCAAAAJgAAAABAAAAAQAOwRvZ2FzcAAABMAAAAAIAAAACP//AANnbHlmAAACcAAAASIAAAGEagP31WhlYWQAAAFEAAAAMQAAADYVj60EaGhlYQAAAXgAAAAdAAAAJAujBQZobXR4AAACBAAAABQAAAAUCmAAO2xvY2EAAAJkAAAADAAAAAwA7gEabWF4cAAAAZgAAAAfAAAAIABNAJluYW1lAAADlAAAAR0AAAH7nk+ALXBvc3QAAAS0AAAADAAAACAAAwAAeJxjYGRgYADi3byprfH8Nl8ZuNkZQOBGhcYNCG2tz8Dwv4EVCIFcDgYmkCgAGkkKAwAAAHicY2BkYGBt+N/AsJC1gYEBxGZgZEAFrABkwAO3AAAAeJxjYGRgYGBlyGBgYwABJiBmZACJOTDogQQADlgA5wB4nGNgYW1gnMDAysDA0sPyjIGB4ReEZo5hiGQ8z8DAxMDKzAAHHAgmQ0CaawrDgSCFaSlsDP8ZGBayNjA0AIUZkZQoMDACAMDLDQAAAosAOwAAAAACVQAABYAAAAAAAAB4nGNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZiCFKal/P/PwACh1z7OXABVDwSMbAxwDiMTkGBiQAWMDMMeAAA34Ao9AAAAOwRvAAAALAAsACwAwgDCeJyFkD1Lw1AUhs+5Nx+0Q8KNbcbW25K0INiSjzokllChg5QuBccSQXB06uCWP+HmXuiW4OBY8F+If8FfYBK9N3uRA4f3PjycFy4QiABIVzkABR0uc4RJXOgKfHu5pn7FBSUiQk4lViUudA3LuEDJfcaZwxmP8LO+x4f6VTn83EVKAAAawG+migET+jARLTfwCICso13gwA1ZMIvQs9V/3meiodNDn3tzRD5yR1zT1a50hDjkUhwO3GsMZj6/mkvP7qNYBCwjMaxm4YmclZlhUppQ06hSPE71dv3R1umTZaTbRXlcbFMpYrg012NMxmtziaFh0fPqKDlpzpzIVY++lSvbYcxRbnctQlovAperzfNuQ9+b9r0TBM7eEl/1B1oESgcAAHicdY6/SsNQGMXPbdMWl+Lq9oEOLTThJtWhXYsZHaR0FEKIycVyU24ToYuP5GP4MD6CkyfpdXBo4PL9vj855wCY4hMK5+8G954VJnjxPCC/ex7iFl+eA85/PI9wre48jzFRj7xUwRW7pP+rY0WvJ88D8qvnIVJ8eA44//Y8gqiB5zGm6gEb1DjgBAeDEhUaCGbIMWdNoBFjhQV5y52BxRuwqQ8nZ8qqkVk+l0THq4VsK2O5OvIq41XO2rKtMptXhGcUVG+x59axLcp2nxFSult6dtXxouhdI/oK1nz/9c6zJTOF/fvLh7S2TVq7spAk0rIW70taxmEcdhEvZ9vR1XFr+ixCzU416muXA7vCHU1tRes40lrLRalfgcNLWwAAAHicY2BmwAsAAH0ABAAAAAH//wACeJxjYGSAAB4GEQYWIM0ExIwQDAACywAqAAAAAQAAAADVpJjbAAAAANh4KNgAAAAA2Hg7Lw==') format('woff');
}
.icon-delete {
font-family: shanchu;
text-decoration: none;
color: black;
}
.css-tips {
position: relative;
}
.css-tips::before, .css-tips::after {
position: absolute;
display: block;
z-index: 1;
}
.css-tips:hover::before {
content: attr(data-title);
font-family: sans-serif;
font-size: 80%;
color: white;
background-color: black;
white-space: nowrap;
top: -3.5em;
padding: 0.5em 0.8em;
left: -1.25em;
border-radius: 4px;
line-height: 1.4;
}
.css-tips:hover::after {
content: '';
border: 0.5em solid transparent;
border-top-color: black;
top: -1em;
left: 50%;
margin-left: -0.5em;
}
.icon-delete{
position: relative;
display: inline-block;
margin-top: 2em;
font-size: 16px;
}
.css-tips::before{
display: none;
content: attr(data-title);
position: absolute;
top: -2em;
left: 50%;
padding: 0.3em;
background-color: #000;
color: white;
white-space: nowrap;
border-radius: 5px;
transform: translateX(-50%);
}
.css-tips::after{
display: none;
content: "";
position: absolute;
top: -0.2rem;
left: 0;
right: 0;
width: 0;
height: 0.8em;
margin: auto;
border: 0.4em solid transparent;
border-top-color: #000;
}
.css-tips:hover::before,
.css-tips:hover::after{
display: block;
}
body{
padding:20px;
}
.icon-delete{
text-decoration: none;
position: relative;
}
.css-tips::before{
position: absolute;
content: attr(data-title);
border-radius: 6px;
border: 1px solid black;
text-align:center;
width:42px;
height:25px;
color:white;
background-color: black;
top:-42px;
left:-6px;
font-size:10px;
padding-top:6px;
visibility: hidden;
letter-spacing:2px;
}
.css-tips::after{
visibility: hidden;
position:absolute;
content:"";
border-width:5px;
border-style:solid;
border-color:black transparent transparent transparent;
left:12px;
top:-10px;
}
.css-tips:hover::after,.css-tips:hover::before{
visibility:visible;
}
.icon-delete{
position: relative;
display:inline-block;
width:16px;
height: 16px;
color:transparent;
content: '';
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxklEQVQ4T+XTP0oDQRTH8c+SKlVuINglXbRNBI+R2KWwE7EQD5ALBAJB0qmN2OQSFmITDFgFUuUIgoVayMIKy7Czm5gyU83we+/7/sx7iR1PUuI/wlGmv+OiyDYPqOESjcywj8eC+wfG+E61POA4i/JQUVUP93gJAU1M8YyfEkgH11iEgPQ9wQrzCOAAJzj/08MmDjHDWwTQwgA3VYBDrINS2njdFNDFEl+5TE7xtEeAnZv47288wxU+I3NQxy3uYnOw9XL/AlB7OBGPcxK+AAAAAElFTkSuQmCC') no-repeat;
}
/* 上提示 */
.css-tips:hover::after{
position:absolute;
top:-34px;
left:50%;
transform: translate(-50%,0);
display:inline-block;
padding:0 10px;
height:24px;
font-size:12px;
color:#fff;
text-align: center;
line-height: 24px;
border-radius: 3px;
content:attr(data-title);
white-space: nowrap;
background: #000;
}
.css-tips:hover::before{
display: inline-block;
position:absolute;
top:-10px;
left:50%;
transform: translate(-50%,0);
width:0;
height:0;
content:'';
border-width:5px 5px 0;
border-style:solid;
border-color:#000 transparent transparent;
}
/* 下提示 */
.css-tips.bottom:hover::after{
top:26px;
}
.css-tips.bottom:hover::before{
top:21px;
border-width:0 5px 5px;
border-color:transparent transparent #000;
}
/* 左提示 */
.css-tips.left:hover::after{
top:50%;
transform: translate(-100%,-50%);
left:-10px;
}
.css-tips.left:hover::before{
top:50%;
transform: translate(0,-50%);
left:-10px;
border-width:5px 0 5px 5px;
border-color:transparent transparent transparent #000;
}
/* 右提示 */
.css-tips.right:hover::after{
top:50%;
transform: translate(0,-50%);
left:26px;
}
.css-tips.right:hover::before{
top:50%;
transform: translate(0,-50%);
left:21px;
border-width:5px 5px 5px 0;
border-color:transparent #000 transparent transparent;
}
.icon-delete{
position: relative;
}
.icon-delete::before{
visibility: hidden;
content: attr(data-title);
position: absolute;
width: 2em;
top: -3em;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
padding: .5em .8em;
border-radius: 3px;
color: #fff;
background: #000;
}
.icon-delete::after{
visibility: hidden;
position: absolute;
top: -.45em;
left: 50%;
transform: translateX(-50%);
width: 0;
content:'';
border-left: .3em solid transparent;
border-right: .3em solid transparent;
border-top: .3em solid #000;
}
.icon-delete:hover::before,
.icon-delete:hover::after{
visibility:visible;
}
- 考虑各种字号场景,使用bottom定位,calc()或者margin-bottom微调位置;
- transform增加-ms-前缀,兼容IE9;
- 考虑边界场景,例如在浏览器上边缘,或者侧面时候;
- 考虑增加延迟显示,使用visibility+transition,或者pointer-events: none(渐进增强);
- 考虑键盘访问,增加:focus伪类显示。