天,我们将学习如何制作一个在悬停时展开和折叠的侧边栏。它看起来很漂亮,实现比看起来简单得多。我们将逐步完成本教程,并且在此过程中我还将介绍一些值得注意的HTML / CSS技巧。
以下是本文将涉及的提示和技巧列表:
让我们开始!
可以在此笔中找到此步骤的完整代码:https://codepen.io/dalisc/pen/rEjRWo
只使用HTML,您的网页将如下图所示。一些CSS可以做出什么改变!所以我们需要用一些CSS来设置它,使其看起来像上面的gif。
.sidebar { height: 100%; width: 250px; position: fixed; top: 0; left: 0; background-color: #111; padding-top: 60px;
此代码为侧边栏提供250px(width:250px;)的宽度,背景颜色为深色(background-color:#111;),并使其在页面上完全垂直延伸(height:100%;)。在code pen以自定义侧边栏。
.sidebar a { padding: 8px 8px 8px 32px; text-decoration: none; font-size: 25px; color: #818181; display: block; }
在这里,我们使用“text-decoration:none;”删除了文本的下划线和蓝色,并在侧边栏项目周围添加了填充和块显示的一些空格。增强用户体验的部分是当项目颜色从灰色变为白色时,这可以通过以下代码完成:
.sidebar a:hover { color: #f1f1f1; }
此代码表示当您将鼠标悬停在类“侧栏”中用<a>标记的元素上时,元素的颜色将更改为您设置的任何颜色,在本例中为#f1f1f1。
如果您使用Google的素材图标,您会发现一个令人沮丧的问题:默认情况下,图标和相邻文字没有正确垂直对齐。
.material-icons, .icon-text { vertical-align: middle; } .material-icons { padding-bottom: 3px; margin-right: 30px; }
你需要做的是在CSS中垂直对齐它们(vertical-align:middle;)。即使这样,对齐也有点偏离,所以在此之后给你的图标一个3px垂直增强(padding-bottom:3px;)。
现在我们将添加一些Javascript,因为我们将在侧边栏中引入一些功能。可以在此笔中找到此步骤的完整代码
两个非常有用的事件是onmouseover和onmouseout,它们分别检测您的鼠标是否悬停在特定元素之上或之外。对于我们的侧边栏,我们希望检测位于侧边栏的任何部分,因此我们需要将这些事件添加到侧边栏的<div>中,如下所示:
<div id=”mySidebar” class=”sidebar” onmouseover=”somethinghappens” onmouseout=”somethinghappens”>
现在,我们可以决定鼠标悬停在侧边栏上或从边栏悬停的情况。我们需要将“ somethinghappens”替换为我们想要实际发生的事情,但首先,让我们通过向控制台发送消息来检查是否发生了检测。
现在让我们编写两个Javascript函数来确认检测到事件:
function testIn() { console.log(“hovering in sidebar”); } function testOut() { console.log(“hovering outside sidebar”); }
更新我们的侧边栏:
<div id=”mySidebar” class=”sidebar” onmouseover=”testIn()” onmouseout=”testOut()”>
现在进行悬停并检查控制台以查找我们编写的消息。它应该可以工作了!我们已经设置了告诉侧边栏是折叠还是展开所需的检测。
可以在此笔中找到此最终部分的完整代码:https://codepen.io/dalisc/pen/qzRGxQ
我们将折叠边栏称为迷你侧边栏。我们现在想要根据鼠标是否悬停在我的侧边栏上进行两次查找,因此我们需要在javascript部分中创建一个布尔变量mini。
我们还将创建一个函数来切换侧边栏的扩展。该功能的逻辑如下:如果侧边栏处于迷你模式,将鼠标悬停在侧边栏上会将侧边栏扩展为其完整模式(并将变量mini设置为false)。如果侧边栏处于完全模式,将鼠标悬停在侧边栏上会将其折叠为迷你模式(并将变量mini设置为true)。
因此,我们需要更改onmouseover和onmouseout事件,并相应地引入新函数toggleSidebar()。
更改html:
<div id=”mySidebar” class=”sidebar” onmouseover=”toggleSidebar()” onmouseout=”toggleSidebar()”>
添加到JS(我们现在可以删除testIn()和testOut()):
var mini = true; function toggleSidebar() { if (mini) { console.log(“opening sidebar”); document.getElementById(“mySidebar”).style.width = “250px”; document.getElementById(“main”).style.marginLeft = “250px”; this.mini = false; } else { console.log(“closing sidebar”); document.getElementById(“mySidebar”).style.width = “100px”; document.getElementById(“main”).style.marginLeft = “100px”; this.mini = true; } }
从功能中可以看出,它基本上都是改变侧边栏黑色块的宽度。完整模式的宽度为250px,迷你模式的宽度为85px。我们还策略性地定位文本和图标,以便在侧边栏折叠时完全隐藏文本,仅显示图标。
默认情况下,我们希望侧边栏处于迷你模式,因此我们也将侧边栏的宽度(最初未被遮挡时)更改为85px。
.sidebar { height: 100%; width: 85px; position: fixed; z-index: 1; top: 0; left: 0; background-color: #111; transition: 0.5s; padding-top: 60px; }
当前默认外观:
此时,文本溢出仍有一些问题,所以我将介绍一些CSS提示和技巧!
将“white-space:nowrap;”添加到侧栏CSS。
.sidebar { height: 100%; width: 85px; position: fixed; top: 0; left: 0; background-color: #111; padding-top: 60px; white-space: nowrap; }
即使文本大于侧边栏的宽度,这也会阻止文本换行到下一行。但正如你在下面看到的那样,虽然它现在在一行中,它会溢出,你可以看到溢出...所以我们需要找到隐藏它的方法!
s
要隐藏溢出的文本,只需将“overflow-x:hidden;”和“z-index:1;”添加到侧边栏css即可。这将隐藏任何宽于侧边栏宽度的内容。
.sidebar { height: 100%; width: 85px; position: fixed; z-index: 1; top: 0; left: 0; background-color: #111; overflow-x: hidden; padding-top: 60px; white-space: nowrap; }
现在我们的侧边栏看起来非常好!(我也改变了主要内容,但主要内容未在本教程中介绍,它包含在code pen。)
现在我们已经遇到了我们需要修复的最后一个小故障,以使侧边栏顺利移动。目前,随着侧边栏折叠和展开,没有动画添加到它,所以它看起来有点不连贯,像这样:
所以我们想要的是一个非常平滑的过渡,如第一页上的gif所示。现在,变化立即发生。为了顺利,我们需要减缓变化。首先,我们需要让侧边栏扩展得更慢,比方说0.5秒。将其添加到侧边栏CSS。
.sidebar { height: 100%; width: 85px; position: fixed; z-index: 1; top: 0; left: 0; background-color: #111; overflow-x: hidden; transition: 0.5s; padding-top: 60px; white-space: nowrap; }
我们还需要将主要部分同时推到左侧。
#main { transition: margin-left .5s; padding: 16px; margin-left: 85px; }
你有一个漂亮的侧边栏!
在GitHub存储库中找到完整的工作代码:https://github.com/dalisc/hover-collapsible-sidebar
转:https://medium.com/@9cv9official/create-a-beautiful-hover-triggered-expandable-sidebar-with-simple-html-css-and-javascript-9f5f80a908d1
个成功的Web App必须有良好的用户体验。当我们谈及改善用户体验时,你会想到什么?
其实,有一点是很容易被开发者忽视的,那就是CSS。我们可以使用一些CSS技巧来改善网页的表现形式、交互细节和可访问性。
而且这些技巧不需要花费太多时间,也不需要消耗服务器资源。你只需要花两个小时学习,然后就可以把它应用到你所有的项目中,并永远改善用户体验。
有时你的按钮很小,这可能导致用户无法准确点击按钮。这种现象经常发生在移动端上。如果用户点击次数太多,没有点击他们想要的按钮,或者点击错误的按钮,会让他们感到非常沮丧。
那么,如何解决这个问题呢?有些开发者可能会说:把按钮做大点。
但网页中元素的大小往往是固定的,我们不能轻易调整一个元素的大小。而且如果按钮太大,感觉很奇怪。
一个更好的解决方案是在不改变按钮原始尺寸的情况下增加其可点击区域。具体来说:我们可以使用伪元素来增加一个元素的可点击区域。
例如,这里有一个按钮。
<button id="btn">btn</button>
然后我们可以为它添加一个伪类。
#btn::before {
content: "";
position: absolute;
top: -20px;
right: -20px;
bottom: -20px;
left: -20px;
}
这时,如果我们点击按钮周围的区域,我们仍然可以触发按钮的点击事件。
事例地址:
https://codepen.io/bytefishmedium/pen/rNYNoRX
当页面被#链接滚动时,默认效果是这样的。
这种突然的跳跃会让人感到不舒服。为了解决这个问题,我们可以使用这个CSS样式:sroll-behavior: smooth。
事例地址:https://codepen.io/bytefishmedium/pen/NWwWoKL
我们的网页经常需要提供一些内容供用户选择,如电话号码、地址、标题等。而这些文字应该是一个整体,我们希望当用户点击部分文字时,剩余的文字会被自动选择。
要实现这种效果非常简单,只需使用这个CSS样式:user-select: all 。用户选择的CSS属性控制用户是否可以选择文本。如果它的值是 all,意味着一个元素的所有内容都将被原子化地选择。
事例地址:https://codepen.io/bytefishmedium/pen/xxPxMZO
如果你想在文本被选中后添加一些额外的样式,你可以使用::selection 。::selection CSS伪元素将样式应用于文档中被用户突出显示的部分(比如在文本上点击和拖动鼠标)。
但要记住。只有某些CSS属性可以和::selection一起使用。
事例地址:https://codepen.io/bytefishmedium/pen/gOXOqMz
在不同的场景下使用不同的鼠标样式可以帮助读者感知页面的当前状态,从而改善用户的互动体验。
cursor CSS属性设置鼠标指针在一个元素上时要显示的鼠标指针(如果有的话)。
光标设置应该告知用户在当前位置可以进行的鼠标操作,包括文本选择、激活帮助或上下文菜单、复制内容、调整表格大小,等等。你可以用一个关键词来指定光标的类型,或者加载一个特定的图标来使用(有可选的回退图像和强制性的关键词作为最后的回退)。
例如:
事例地址:https://codepen.io/bytefishmedium/pen/bGYGzRz
有很多光标样式,你可以在MDN文档中找到它们。
现在我们来看看 text-overflow 的问题。如果一个文本容器的内容是从服务器返回的,或者是由用户输入的,那么就很难预测这个文本会有多长。
如果没有任何预防措施,你可能会写出这样的代码。
<head>
<style>
.container{
border: 2px solid red;
width: 200px;
height: 60px;
}
</style>
</head>
<body>
<div class="container">
<div class="username">bytefish</div>
<p class="profile">FE, UX Designer</p>
</div>
</body>
这个容器有一个固定的宽度和高度,包裹着名字和介绍。
但如果有些用户的简介太长,就会导致文本溢出容器,使页面看起来很糟糕。
在这一点上,我们可以将溢出的文本折叠起来。做到这一点就像添加三行CSS样式一样简单。
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; 可以使文本不被包起来。然后我们使用overflow: hidden来隐藏溢出的文本。最后,我们使用 text-overflow: ellipsis 在文本的末尾添加一个圆点,向用户表明有一些隐藏的文本。
事例地址:https://codepen.io/bytefishmedium/pen/VwrwgdQ
现在我们来讨论一下图片的风格。网络应用中使用的图片一般由后端提供。你可能已经与后端开发者达成协议,将图片保持在一个固定的尺寸。然后你写下这样的代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.img-list {
display: flex;
flex-direction: row;
list-style: none;
}
</style>
</head>
<body>
<ul class="img-list">
<li>
<img src="https://miro.medium.com/fit/c/128/128/1*TyRLQdZO7NdPATwSeut8gg.png">
</li>
<li>
<img src="https://miro.medium.com/fit/c/128/128/1*pKOfOAOvx-fWzfITATgGRg.jpeg">
</li>
<li>
<img src="https://miro.medium.com/fit/c/128/128/1*mXOVdfMwS0IEcjPXiikJkg.png">
</li>
</ul>
</body>
</html>
而网页看起来是这样的。
图片的排列与我们所期望的一样。
通常情况下是没有问题的。但是当我们写代码时,我们不能假设一切都会按照我们的预期发展。我们需要做好充分的准备。如果后端返回的图片不正常,不符合预期的尺寸,可能大也可能小,那么布局就会被打乱。
你可以用这个替换其中一张图片的链接。
https://miro.medium.com/max/1400/0*zQaS0awtSTOO-JYa.jpg
你会发现,页面突然变得杂乱无章。
为了防止这个问题,使我们的页面更加健壮,我们可以设置图片的宽度和高度。这样,我们就不必担心后端返回的图片的大小。
img {
width: 128px;
height: 128px;
}
但上述写法有一个缺点:如果图像本身的长宽比与我们设定的长宽比不一致,图像将被压缩或拉伸。
为了保持图像的原始长宽比,我们可以使用 object-fit: cover 。
img {
width: 128px;
height: 128px;
object-fit: cover;
}
object-fit 的CSS属性设置一个被替换的元素的内容,如<img>或<video>,应该如何调整大小以适合其容器。
如果该值是 cover,那么被替换的内容的大小将保持其长宽比,同时填充元素的整个内容框。如果对象的长宽比与它的盒子的长宽比不一致,那么该对象将被剪掉以适配。
我们之前讨论的情况都是建立在我们能够得到图片的前提下。但是,在实际应用中,可能由于后端服务的不稳定,或者用户自身的网络信号不好,我们的网页可能无法正确加载图片。
当图片缺失时,浏览器的默认样式是不优雅的,这里我们可以优化它。
我们可以给 img元素添加一个 onerror 事件。如果在加载图片时出现了错误,那么我们可以通过 onerror事件给该元素添加一个样式,并使用404图片。
img 元素:
<img src="https://miro.medium.com/xxx.jpg" alt='fireworks picture' onerror="this.classList.add('error');">
假设这就是我们的404图像:
https://cdn-images-1.medium.com/max/1600/1*we8wfyztsdo12e2Cww6oVA.jpeg
下面是 css 代码
img.error {
display: inline-block;
transform: scale(1);
content: '';
color: transparent;
}
img.error::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #f5f5f5 url('https://cdn-images-1.medium.com/max/1600/1*we8wfyztsdo12e2Cww6oVA.jpeg') no-repeat center / 100% 100%;
}
这样,当 img 元素中的图片链接无法加载图片时,我们的404图片将被使用。
这里还有一点需要优化。在这种情况下,如果原始图片没有被正确加载,用户就不知道这个图片应该是什么。为了方便用户理解,我们可以将 img 元素的 alt 属性显示在页面上。
img.error::after {
content: attr(alt);
position: absolute;
left: 0;
bottom: 0;
width: 100%;
line-height: 2;
background-color: rgba(0, 0, 0, .5);
color: white;
font-size: 12px;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
假设img的 alt 属性是这样的。
<img src="https://miro.medium.com/xxx.jpg" alt='Log of Medium' >
事例地址:https://codepen.io/bytefishmedium/pen/vYWYMxG
当你在设计颜色组合时,你是否考虑过页面的颜色对比?
你需要知道,世界上有很多色盲和色弱用户。如果你的页面的对比度低,可能会导致他们无法正常使用你的产品。无论是出于人文关怀,还是出于留住客户的考虑,你都应该设计出合适的对比度。
WCAG AA规范指出,所有重要的内容需要有4.5:1以上的色彩对比度。
这里有一个对比度检查器的工具。
https://webaim.org/resources/contrastchecker/
事例:
我们也可以使用Chrome DevTool来检查一个元素的颜色对比。然后我们可以发现,Medium的网页也在实践这一原则。
俗话说得好,细节决定成败。如果你的项目有很多可以改善用户体验的细节,你就可以让用户感到舒服,你就有更高的成功概率。
~完,我是刷碗智,新的一年我们一起刷刷刷!
作者:Shadeed 译者:前端小智 来源:medium 原文:https://betterprogramming.pub/10-css-tricks-that-greatly-improve-user-experience-5ee52886ca4b
近做了一个邮件模板功能,就是可以在后台定义各种情况下的发送邮件验证码的模板,如下图所示:
可以定义「注册账号」,「重置密码」,「验证邮箱」等各种情况下的邮件模板的标题和内容。使用 WPJAM Basic 的生成表单功能,实现是非常简单,具体的代码就是生成三个 fieldset 字段组,使用 foreach 简单就能处理:
$fields = [];
foreach(['register'=>'注册账号', 'resetpass'=>'重置密码', 'verify'=>'验证邮箱'] as $type => $title){
$fields[$type] = ['title'=>$title, 'type'=>'fieldset', 'fields'=>[
$type.'_subject' => ['title'=>'标题', 'type'=>'text'],
$type.'_message' => ['title'=>'内容', 'type'=>'textarea', 'rows'=>3],
]];
}
但是感觉这样重复的界面非常占用空间,有没有什么好的优化方式,比如折叠起来,点击展开之后再设置?
我查了一下,其实无需 Javascript,只需用 HTML 的 summary / details 这两个标签就能实现。
所以我增强了一下 WPJAM Basic fieldset 组件的能力,fieldset 组件只需要设定 summary 属性,就能使用 summary / details 实现折叠展开效果,具体代码如下:
$fields = [];
foreach(['register'=>'注册账号', 'resetpass'=>'重置密码', 'verify'=>'验证邮箱'] as $type => $title){
$fields[$type] = ['title'=>$title, 'type'=>'fieldset', 'summary'=>$title.'时邮件设置', 'fields'=>[
$type.'_subject' => ['title'=>'标题', 'type'=>'text'],
$type.'_message' => ['title'=>'内容', 'type'=>'textarea', 'rows'=>3],
]];
}
相比第一段代码,这段代码就是增加了 summary 属性设置,最后的效果如下:
默认情况都只显示摘要,点击摘要时候,就会展开字段组设置,如上图,我点击了第一个 fieldset 字段组的摘要,「注册账号」这个邮件模板就展开了,其他两个则还是没有折叠的状态。
*请认真填写需求信息,我们会在24小时内与您取得联系。