css实现贝塞尔静态图_使用高级CSS条形图构建静态投资组合

css实现贝塞尔静态图

在上一篇文章中 ,我向您展示了如何构建漂亮的全屏投资组合页面。 在该教程中,我们还学习了如何创建响应式CSS柱形图。 在本教程中,我们将构建另一个吸引人的静态投资组合页面,这次以纯CSS条形图为特色,而无需使用任何外部JavaScript库,SVG或canvas元素!

我们正在建设什么

这是我们将创建的项目:

我们有很多令人兴奋的事情要介绍,所以让我们开始吧!

1.从页面标记开始

页面标记由标题和三个全屏部分组成:

<header class="position-fixed text-lightblue page-header">...</header>
<section class="d-flex justify-content-center align-items-center vh-100">...</section>
<section class="d-flex vh-100 bg-lightwhite">...</section>
<section class="d-flex flex-column justify-content-center align-items-center vh-100 position-relative">...</section>

注意 :除了元素的特定类之外,我们的标记还包含许多实用程序(帮助程序)类。 我们将使用这种方法使CSS尽可能保持DRY 。 但是,出于可读性考虑,在CSS内,我们将不对通用CSS规则进行分组。

2.定义一些基本样式

按照上面刚刚讨论的内容,我们首先指定一些重置规则以及一些帮助程序类:

:root {
  --gray: #cbcfd3;
  --white: white;
  --black: #1a1a1a;
  --lightwhite: whitesmoke;
  --lightblue: #009dd3;
  --peach: #ff9469;
  --transition-delay: 0.3s;
  --transition-delay-step: 0.3s;
  --skills-width: 120px;
}

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

ul {
  list-style: none;
}

a {
  text-decoration: none;
  color: inherit;
}

.d-block {
  display: block;
}

.d-flex {
  display: flex;
}

.flex-column {
  flex-direction: column;
}

.justify-content-center {
  justify-content: center;
}

.justify-content-between {
  justify-content: space-between;
}

.align-items-center {
  align-items: center;
}

.align-items-end {
  align-items: flex-end;
}

.flex-grow-1 {
  flex-grow: 1;
}

.vh-100 {
  height: 100vh;
}

.position-relative {
  position: relative;
}

.position-absolute {
  position: absolute;
}

.position-fixed {
  position: fixed;
}

.text-center {
  text-align: center;
}

.text-gray {
  color: var(--gray);
}

.text-lightblue {
  color: var(--lightblue);
}

.text-peach {
  color: var(--peach);
}

.bg-white {
  background: var(--white);
}

.bg-lightwhite {
  background: var(--lightwhite);
}

.h1 {
  font-size: 2.5rem;
}

.h2 {
  font-size: 2rem;
}

我们的帮助器类的命名约定受Bootstrap 4的类名启发。

3.构建页面标题

页面标题包括:

  • 徽标
  • 主导航

<header class="position-fixed bg-white page-header">
  <nav class="d-flex justify-content-between align-items-center">
    <a href="" class="text-peach logo">
      <strong>DM</strong>
    </a>
    <ul class="d-flex">
      <li>
        <a href="#skills">Skills</a>
      </li>
      <li>
        <a href="#contact">Contact</a>
      </li>
    </ul>
  </nav>
</header>

标头CSS

.page-header {
  left: 0;
  right: 0;
  top: 0;
  padding: 20px;
  z-index: 10;
}

.page-header .logo {
  font-size: 1.7rem;
}

.page-header li:not(:last-child) {
  margin-right: 20px;
}

.page-header a {
  font-size: 1.1rem;
}

4.建立英雄区

我们页面的第一部分包括:

  • 标题
  • 号召性用语

它将是这样的:

第1节HTML

<section class="d-flex justify-content-center align-items-center vh-100">
  <h1 class="text-center h1">...</h1> 
  <div class="position-absolute scroll-down">...</div>  
</section>

第1节CSS

号召性用语包括一条细线,该细线可以无限地进行动画处理,迫使用户向下滚动以查看“首屏”下方的内容( 可能存在或不存在 )。

其样式:

.scroll-down {
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  text-transform: uppercase;
  transition: all 0.5s;
}

.scroll-down.is-hidden {
  opacity: 0;
  visibility: hidden;
}

.scroll-down::after {
  content: '';
  display: block;
  margin: 3px auto 0;
  width: 1px;
  height: 60px;
  background: var(--black);
  transform-origin: bottom;
  animation: pulse 3.5s infinite linear;
}

@keyframes pulse {
  0% {
    transform: scaleY(1);
  }
  50% {
    transform: scaleY(0.65);
  }
  100% {
    transform: scaleY(1);
  }
}

第1节JavaScript

最初,号召性用语将可见。 但是,当用户开始滚动时,它将消失。 更具体地说,它将收到我们刚刚在上面的样式中定义的is-hidden类。

这是必需JavaScript代码:

const scrollDown = document.querySelector(".scroll-down");

window.addEventListener("scroll", scrollHandler);

function scrollHandler() {
  window.pageYOffset > 0
    ? scrollDown.classList.add("is-hidden")
    : scrollDown.classList.remove("is-hidden");
}

5.建立第2节

页面的第二部分包括:

  • 背景图片
  • 展示网络技能的条形图

看起来是这样的:

第2节HTML

<section class="d-flex vh-100 bg-lightwhite" id="skills">
  <div class="position-relative flex-grow-1 bg-img"></div>
  <div class="d-flex justify-content-center align-items-center flex-grow-1">
    <div class="position-relative chart-wrapper">
      <ul class="d-flex flex-column chart-skills">
        <li class="position-relative">
          <span>CSS</span>
        </li>
        ...
      </ul>
      <ul class="d-flex position-absolute chart-levels">
        <li class="flex-grow-1 position-relative">
          <span class="position-absolute">Novice</span>
        </li>
        ...
      </ul> 
    </div>
  </div>
</section>

设置背景图片的样式

本部分的左侧包含图片摘自Envato Elements上的Wordpress Code Backgrounds 。 这将为我们提供所需的氛围,同时启发我们在设计中其他地方使用的颜色:

一些关键的事情:

  • 图像将出现在大于900px的屏幕上,并且
  • 我们将使用CSS(通过background-image属性)而不是HTML(通过img元素)将图像放置在页面中。 我们选择此方法是因为它使我们可以轻松地增强图像外观。 例如,我们将利用它的::after伪元素来使其倾斜。 您甚至可以使用background-blend-mode: luminosity来播放其颜色background-blend-mode: luminosity例如background-blend-mode: luminosity

注意:默认情况下, img是一个空元素,没有伪元素。

对应的样式:

.bg-img {
  background: #fff url(bg-programming.jpg) no-repeat center / cover;
}

.bg-img::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 7rem;
  background: var(--lightwhite);
  transform: skew(-5deg);
  transform-origin: left bottom;
}

@media screen and (max-width: 900px) {
  .bg-img {
    display: none;
  }
}

设置图表样式

在这一点上,我们将专注于演示中最具挑战性的部分; 如何构建条形图。

图表将有两个轴。 在y轴上,我们将放置网络技能(CSS,HTML,JavaScript,Python,Ruby)。 在另一个x轴上,我们将放置技能级别(新手,初学者,中级,高级,专家)。

y轴

在标记方面,每个技能都是一个放在.chart-skills列表内的列表项。 接下来,每个列表项将其文本保留在span元素内,如下所示:

<ul class="chart-skills">
  <li class="position-relative">
    <span>CSS</span>
  </li>
  ...
</ul>

我们为span元素定义了等于120px的固定宽度。 为了避免重复,我们可以轻松地更改此值(因为其他值将取决于它),让我们将其存储在CSS变量中:

:root {
  --skills-width: 120px;
}

.chart-wrapper .chart-skills span {
  display: inline-block;
  width: var(--skills-width);
  padding: 15px;
}

每个列表项将包含其自己的::before::after伪元素:

/*CUSTOM VARIABLES HERE*/

.chart-wrapper .chart-skills li::before,
.chart-wrapper .chart-skills li::after {
  content: '';
  position: absolute;
  top: 25%;
  left: var(--skills-width);
  height: 50%;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
  z-index: 2;
}

::after伪元素将具有浅灰色和静态宽度,该静态宽度是通过从列表项宽度中减去span宽度来计算的:

.chart-wrapper .chart-skills li::after {
  width: calc(100% - var(--skills-width));
  background: rgba(211, 211, 211, 0.3);
}

外观如下:

所有::before伪元素的初始宽度将为0:

/*CUSTOM VARIABLES HERE*/

.chart-wrapper .chart-skills li::before {
  width: 0;
  background: var(--lightblue);
  transition: width 0.65s ease-out;
}

但是,一旦图表在视口中可见,它们的宽度就会被设置为动画,并接收一个值,该值将由相关的技能级别决定:

在视图中添加类

有多种方法可以检测元素在视口中是否可见。 让我们利用从一个古老而流行的StackOverflow线程中提取的以下便捷功能:

function isElementInViewport(el) {
  var rect = el.getBoundingClientRect();
  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
    rect.right <= (window.innerWidth || document.documentElement.clientWidth)
  );
}

因此,回到工作中! 当图表在当前视口中可见时,我们将其设为in-view类。

这是完成此工作JavaScript代码:

const chartWrapper = document.querySelector(".chart-wrapper");

window.addEventListener("scroll", scrollHandler);

function scrollHandler() {
  if (isElementInViewport(chartWrapper)) chartWrapper.classList.add("in-view");
}

::before伪元素应按顺序进行动画处理。 为了给他们所需的过渡速度,我们将使用另外两个CSS变量以及calc() CSS函数。

以下是负责揭示这些sudo元素CSS样式:

:root {
  ...
  --transition-delay: 0.3s;
  --transition-delay-step: 0.3s;
  --skills-width: 120px;
}

.chart-wrapper.in-view .chart-skills li:nth-child(1)::before {
  width: calc(90% - var(--skills-width));
  transition-delay: var(--transition-delay);
}

.chart-wrapper.in-view .chart-skills li:nth-child(2)::before {
  width: calc(75% - var(--skills-width));
  transition-delay: calc(
    var(--transition-delay) + var(--transition-delay-step)
  );
}

.chart-wrapper.in-view .chart-skills li:nth-child(3)::before {
  width: calc(62% - var(--skills-width));
  transition-delay: calc(
    var(--transition-delay) + var(--transition-delay-step) * 2
  );
}

.chart-wrapper.in-view .chart-skills li:nth-child(4)::before {
  width: calc(49% - var(--skills-width));
  transition-delay: calc(
    var(--transition-delay) + var(--transition-delay-step) * 3
  );
}

.chart-wrapper.in-view .chart-skills li:nth-child(5)::before {
  width: calc(38% - var(--skills-width));
  transition-delay: calc(
    var(--transition-delay) + var(--transition-delay-step) * 4
  );
}

请记住,Microsoft Edge不支持上述数学运算,因此,如果需要支持,只需传递一些静态值即可,如下所示:

.chart-wrapper.in-view .chart-skills li:nth-child(2)::before {
  transition-delay: 0.6s;
}

.chart-wrapper.in-view .chart-skills li:nth-child(3)::before {
  transition-delay: 0.9s;
}
X轴

在标记方面,每个级别都是一个放在.chart-levels列表内的列表项。 接下来,每个列表项将其文本保留在span元素内,如下所示:

<ul class="d-flex position-absolute chart-levels">
  <li class="flex-grow-1 position-relative">
    <span class="position-absolute">Novice</span>
  </li>
  ...
</ul>

注意事项:

  • 我们将列表设置为flex容器。 另外,我们绝对定位它,并为其左填充使其等于第一个列表的span的宽度。
  • 我们给列表项flex-grow: 1增长并占用所有可用空间。
  • span s位于其父级列表项的最底部。

该列表的关联样式:

/*CUSTOM VARIABLES HERE*/

.chart-wrapper .chart-levels {
  left: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  padding-left: var(--skills-width);
}

.chart-wrapper .chart-levels li {
  border-right: 1px solid rgba(211, 211, 211, 0.3);
}

.chart-wrapper .chart-levels li:last-child {
  border-right: 0;
}

.chart-wrapper .chart-levels span {
  bottom: 0;
  transform: translateY(50px) rotate(45deg);
  padding: 10px;
  width: 100%;
}

6.构建第3节

该页面的第三部分包括:

  • 标题
  • mailto链接

看起来是这样的:

第3节HTML

<section class="d-flex flex-column justify-content-center align-items-center vh-100 position-relative" id="contact">
  <h2 class="h1">...</h2>
  <a href="mailto:hello@digitalmonsters.com" class="text-gray h2">...</a> 
</section>

7.响应Swift

我们快完成了! 最后,让我们确保文本在所有屏幕上都有稳定的外观。 我们将应用针对窄屏的规则:

@media screen and (max-width: 600px) {
  html {
    font-size: 12px;
  }
}

这里的一个重要说明是,在我们的样式中,我们使用rem来设置字体大小。 这种方法非常有用,因为字体大小是相对于根元素( html )的。 如果像上面的代码那样减小其字体大小,则与rem相关的字体大小将动态减小。 当然,我们也可以将rem用于其他CSS属性。

我们项目的最终状态:

结论

在本教程中,我们通过学习如何构建吸引人的静态投资组合页面来提高了CSS知识。 我们更进一步,无需使用任何外部JavaScript库,SVG或canvas元素,即可创建响应式条形图。 仅使用普通CSS!

希望本教程能给您足够的启发来构建您的出色组合网站。 我希望看到您的工作,请务必与我们分享!

如果您想进一步增强或扩展此演示,可以做两件事:

一如既往,感谢您的阅读!

翻译自: https://webdesign.tutsplus.com/tutorials/build-a-static-portfolio-with-advanced-css-bar-chart--cms-33050

css实现贝塞尔静态图