ubuntu窗口有粘性
粘性定价表非常适合显示具有相当功能的一长串产品和服务。 在本教程中,我们将创建带有粘性标题的定价表。 在此过程中,我们将学习如何在滚动一定数量后固定和取消固定元素。
但是,今天,让我们挑战自我,编写自己的代码。
我们正在建立的定价表
在本动手练习中,我们将设计一个定价页面,该页面将在定价表的列中包括不同的订阅计划。 当我们向下滚动时,页眉将变得粘滞以便留在视图中,然后在以后释放。 带有粘性标题组合的定价表是一种流行的UI模式,您可能已经在monday.com等网站上看到了。
请记住,我们的演示触发器的粘性功能适用于宽于779px的视口。 您可能需要查看全屏演示才能完全欣赏它!
什么时候应该使用定价表?
当产品,服务或变体的集合为消费者提供太多选择时,定价表就会发挥作用。 如果消费者发现很难决定选择哪个选项,那么他们更有可能选择什么。 信息过载=转换失败。
浪费时间做出选择会否定首先拥有选择权的任何优势!
“研究[..]显示,一旦我们真正决定,过多的选择通常会使我们感到满足,而不是更多。” –纽约时报的Alina Tugend
定价表的作用是帮助用户直观地理解他们可以使用的选项,甚至有时甚至鼓励他们专注于最具吸引力的选择。
在 Val Geisler的“ 如何设计可在InVision博客上进行转换的定价页面”中 了解更多信息 。
WordPress定价表插件
在深入学习本教程之前,您可能需要看一下Envato Market上可用于WordPress的定价表插件的数组。
话虽如此,让我们现在通过创建供用户选择的超清晰表来帮助我们的用户!
1.从页面标记开始
我们将从三个部分开始:
<section>...</section>
<section>...</section>
<section>...</section>
第一和第三部分将不发挥重要作用; 它们将包含虚拟内容和样式,以确保页面足够长以触发所需的滚动效果。
在第二部分中,我们将放置桌子。 我们将其包装在一个容器中,这将使其在小屏幕上做出响应:
<div class="container">
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>...</th>
<th>...</th>
<th>...</th>
<th>...</th>
</tr>
</thead>
<tbody>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<!-- more rows here -->
</tbody>
</table>
</div>
</div>
该表本身将包含四列,代表产品或服务的定价计划。 在我们的案例中,我们将制定三个订阅计划:入门级,基本级和专业级。
表头
该表的粘性标题将清楚地标识那些计划。 每个计划还将包括一个号召性用语按钮。
这是表标题的标记:
<tr>
<th>
<div>
Select your plan
<div class="svg-wrapper">
<svg viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm1 17v-4h-8v-2h8v-4l6 5-6 5z"/></svg>
</div>
</div>
</th>
<th>
<div class="heading">...</div>
<div class="info">
<div class="amount">...</div>
<div class="billing-msg">...</div>
<button type="button">...</button>
</div>
</th>
<th>
<div class="heading">...</div>
<div class="info">
<div class="popular">...</div>
<div class="amount">...</div>
<div class="billing-msg">...</div>
<button type="button">...</button>
</div>
</th>
<th>
<div class="heading">...</div>
<div class="info">
<div class="amount">...</div>
<div class="billing-msg">...</div>
<button type="button">...</button>
</div>
</th>
</tr>
表格行
每个表格行将描述所有计划中功能的可用性。 如果计划包括此功能,则将显示SVG复选标记图标。 否则,将出现一个灰色的十字图标。
这是所有计划都支持的功能的标记:
<tr>
<td>...</td>
<td>
<svg class="starter" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.959 17l-4.5-4.319 1.395-1.435 3.08 2.937 7.021-7.183 1.422 1.409-8.418 8.591z"/></svg>
</td>
<td>
<svg class="essential" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.959 17l-4.5-4.319 1.395-1.435 3.08 2.937 7.021-7.183 1.422 1.409-8.418 8.591z"/></svg>
</td>
<td>
<svg class="professional" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.959 17l-4.5-4.319 1.395-1.435 3.08 2.937 7.021-7.183 1.422 1.409-8.418 8.591z"/></svg>
</td>
</tr>
这是仅在“专业”计划中可用的功能的标记:
<tr>
<td>...</td>
<td>
<svg class="not-included" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm4.151 17.943l-4.143-4.102-4.117 4.159-1.833-1.833 4.104-4.157-4.162-4.119 1.833-1.833 4.155 4.102 4.106-4.16 1.849 1.849-4.1 4.141 4.157 4.104-1.849 1.849z"/></svg> </td>
<td>
<svg class="not-included" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm4.151 17.943l-4.143-4.102-4.117 4.159-1.833-1.833 4.104-4.157-4.162-4.119 1.833-1.833 4.155 4.102 4.106-4.16 1.849 1.849-4.1 4.141 4.157 4.104-1.849 1.849z"/></svg> </td>
<td>
<svg class="professional" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.959 17l-4.5-4.319 1.395-1.435 3.08 2.937 7.021-7.183 1.422 1.409-8.418 8.591z"/></svg>
</td>
</tr>
2.定义一些基本样式
准备好标记后,我们将继续使用CSS。 我们的第一步是设置一些CSS变量和常见的重置样式。
对于每个计划,我们将定义其相应的变量。 如果需要,这将使我们能够轻松更改其外观。
以下是重置样式:
:root {
--white: white;
--gray: #999;
--lightgray: whitesmoke;
--popular: #ffdd40;
--starter: #f73859;
--essential: #00AEEF;
--professional: #FF7F45;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
button {
background: none;
border: none;
cursor: pointer;
}
table {
border-collapse: collapse;
}
body {
font: 18px/1.5 'Noto Sans', sans-serif;
background: var(--lightgray);
}
注意 :为简单起见,我不会逐步学习本教程中的所有 CSS规则。 这里有将近290行CSS。 我只讨论最重要的部分。 确保通过单击演示项目的CSS选项卡检查所有内容。
3.设置价格表的样式
定价表将具有最大宽度,并在页面内水平居中:
.container {
max-width: 850px;
padding: 0 10px;
margin: 0 auto;
}
table {
width: 100%;
}
这些行将充当弹性容器:
table tr {
display: flex;
}
所有单元格将具有相同的宽度:
table th,
table td {
width: 25%;
min-width: 150px;
}
为了分离计划并提供每个计划属于哪个单元的清晰视图,我们将在目标元素上添加浅灰色边框:
--lightgray: whitesmoke;
table th .info,
table td:not(:first-child) {
border-left: 1px solid var(--lightgray);
}
使定价表具有响应性
正如我们将在接下来的部分中看到的那样,粘滞效果将在大于779px的视口上触发(您可以更改此值以适合)。 在较小的视口上,我们将显示一个可以水平滚动的典型表格。
Bootstrap还对响应表使用类似的功能。 还有其他(更好的?)方法可以用来处理响应表,但是这种方法确实可以在这里完成工作。
4.固定/取消固定表格标题
有了HTML和CSS,我们现在将集中在使用一些JavaScript的滚动效果上。 这将使我们能够使标头保持粘性。
变数
对于我们的第一步,我们将获取所需元素的副本。 我们将把两个类存储在变量中,稍后将使用它们:
const body = document.body;
const firstSection = document.querySelector("section:nth-child(1)");
const lastSection = document.querySelector("section:nth-child(3)");
const table = document.querySelector("table");
const thead = document.querySelector("table thead");
const mq = window.matchMedia("(min-width: 780px)");
const stickyClass = "sticky-table";
const sticky2Class = "sticky2-table";
下一步是执行一些计算。 具体来说,我们要计算以下内容:
- 桌子的宽度。
- 表格相对于视口的顶部位置。
-
thead
的高度。 这是元素将被固定/取消固定。
这是执行此操作所需JavaScript:
let tableWidth = table.offsetWidth;
let tableOffsetTop = table.getBoundingClientRect().top;
let theadHeight = thead.offsetHeight;
注意,我们将上述值存储在let
变量中。 我们故意这样做。 调整页面大小后,我们应该重新计算上述内容,从而将这些新值重新分配给这些变量。
滚动
每次我们向上或向下滚动时,都会执行scrollHandler
函数:
在该函数内,我们将执行以下操作,这些操作仅在窗口宽度至少为780px时才会运行:
- 获取用户从视口顶部滚动的像素数。
- 获取相对于视口的最后一个部分的顶部位置。
- 检查用户是否滚动了大于或等于表格的初始顶部位置。
- 如果发生这种情况,我们将
thead
的宽度设置为表的初始宽度。 - 然后,我们检查步骤2的结果值是否大于
thead
的高度。 - 如果发生这种情况,我们可以通过将
sticky-table
类添加到body
并从同一元素中删除sticky-table2
类来固定thead
元素。 此时,thead
成为固定位置的元素。 然后,将其放置在视口的顶部。 我们还为body
提供等于thead
高度的顶部填充。 - 如果这没有发生,我们将通过在
body
添加sticky-table2
类并从同一元素中删除sticky-table
类来停止固定thead
。 届时,thead
被释放并成为绝对定位的元素。 然后,将其放置在表格的底部。
- 如果用户滚动到的位置小于表格的初始顶部位置(尚未固定
thead
),我们将从body
移除sticky-table
和stick-table2
类。 另外,我们将其顶部填充设置为0。这时,thead
没有任何位置(静态元素),因此我们重置其默认top
位置。 最后,我们将其宽度设置为100%(我们可以跳过它)。
实现所有此行为的代码如下:
window.addEventListener("scroll", scrollHandler);
function scrollHandler() {
if (mq.matches) {
// 1
const scrollY = window.pageYOffset;
// 2
const lastSectionOffsetTop = lastSection.getBoundingClientRect().top;
// 3
if (scrollY >= tableOffsetTop) {
// 4
thead.style.width = `${tableWidth}px`;
// 5
if (lastSectionOffsetTop > theadHeight) {
// 6
body.classList.remove(sticky2Class);
body.classList.add(stickyClass);
thead.style.top = 0;
body.style.paddingTop = `${theadHeight}px`;
} else {
// 7
body.classList.remove(stickyClass);
body.classList.add(sticky2Class);
thead.style.top = `calc(100% - ${theadHeight}px)`;
}
} else {
// 8
body.classList.remove(stickyClass, sticky2Class);
body.style.paddingTop = 0;
thead.style.width = "100%";
thead.style.top = "auto";
}
}
}
以及每个类的相关样式:
table thead {
transition: box-shadow 0.2s;
}
.sticky-table table thead {
position: fixed;
left: 50%;
transform: translateX(-50%);
}
.sticky-table table thead {
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.12);
}
.sticky2-table table thead {
position: absolute;
left: 0;
}
5.调整页面大小
伙计们,我们差不多完成了工作! 到目前为止,页面加载时,粘性标题效果会很好。 但是,页面调整大小后会发生什么? 好吧,如果我们也能使此演示也能进行调整大小,那将是非常好的,对吧? 我们开始做吧!
因此,每次我们调整页面大小时,都会执行resizeHandler
函数。
在该函数内部,我们将首先检查窗口宽度,然后更新上述let
变量的值,或重置thead
和body
内联样式。 注意,我们通过抓住第一部分的高度来检索表格的顶部位置。 您可能想知道为什么我们不使用表的offsetTop
属性? 在测试期间,我注意到它在调整大小时并不总是能提供准确的结果。 另外,由于getBoundingClientRect()
方法也给出了不正确的值(甚至是负值),因此将不起作用。
所需JavaScript代码:
window.addEventListener("resize", resizeHandler);
function resizeHandler() {
if (mq.matches) {
tableWidth = firstSection.offsetHeight;
tableOffsetTop = table.offsetTop;
theadHeight = thead.offsetHeight;
} else {
body.classList.remove(stickyClass, sticky2Class);
body.style.paddingTop = 0;
thead.style.width = "100%";
thead.style.top = "auto";
}
}
结论
就是这样,伙计们! 在本教程中,我们设法建立了有用的滚动效果,而无需使用任何外部库。 我们不仅学习了如何创建粘性元素,而且还学习了如何在滚动一定数量后取消固定(释放)它们。
所有这些加在一起为我们提供了一个非常有用的带有粘性标题的定价表。
我希望这项练习可以帮助您学习新知识,并启发您在即将进行的项目中使用它。
在结束之前,我想强调两件事:
与往常一样,非常感谢您的阅读!
ubuntu窗口有粘性