整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTML实战篇:纯css制作二级横向以及竖向菜单导航

本篇文章主要给大家介绍一下如何使用html+css完成二级横向以及竖向菜单导航制作;菜单导航是网站建设中最常用的一块了,基本每个网站内都会有个导航菜单,用鼠标划过还可以有下拉子菜单。

由上图我们可以看出,该图包含一个横向导航条,然后鼠标经过横向导航条之后,子导航显示出来。

1)制作页面所用知识点

我们这里主要用到的知识点就是列表标签(ul、dl)的使用、浮动(float)的使用、绝对定位(absolute)及鼠标经过(hover)的效果。

1、列表标签ul、dl(我们使用ul、dl来创建同类型的导航元素内容,通过设置css样式来达到图片所示效果);

2、浮动元素float(每个导航元素我们需要使用float:left;让其左对齐,这里涉及到了我们之前讲解的如何清除浮动的影响);

3、绝对定位absolute(对于子导航我们要使用绝对定位来让其浮动在上级有定位元素的下方,不占据元素空间)

4、鼠标经过hover(使用css的鼠标经过元素(hover)效果,配合display的none(隐藏)和block(显示)来实现子菜单的显示与隐藏)

具体的实现html代码以及css代码就如下图所示:

2)纵向菜单导航

还有一个纵向菜单导航原理跟横向的类似,只需简单调整一下css代码即可。

html代码跟横向一样,这里就不再贴图,具体的实现图片效果以及css代码就如下图所示:

好了,本篇文章就给大家说到这里,大家自己动手写一下看能不能写出一样的页面效果出来,也可以找一些类似的页面自己练习一下,有需要源码的可以直接私信我即可。

每日金句:每天收获小进步,积累起来就是大进步;每天收获小幸福,积攒起来便成大幸福。喜欢我的文章的小伙伴记得关注一下哦,每天将为你更新最新知识。



情是这样的

  • 早些时候,我接到了一个需求,说要将项目里程碑用甘特图展示,一脸懵逼的我先是搜一下什么是“甘特图” :

From 百度百科:甘特图(Gantt chart)又称为横道图、条状图(Bar chart)。其通过条状图来显示项目,进度,和其他时间相关的系统进展的内在关系随着时间进展的情况。

  • 配合图片感受 :
  • 心想,刚好最近用 echarts 画过许多图表,这货应该也能用 echarts 来实现,历尽千辛和万苦,于是有了:
  • 产品一看,说:“这不是我要的甘特图,重做!”,缓缓地打出一个“好的”,实际上心情如图:
  • 在 github 上一搜,甘特图组件不算多,由于时间紧急,当时还没发现只有413个 的真命天子(dhtmlxGantt),仅试用了前面4款 比较多的:
  • 结果均是以失败告终(不符合业务需求,改造难度大)。



  • 调整一下心情,重新踏上甘特图组件调研之路 ,终于,被我发现了 Top 5 : Best free jQuery and JavaScript Dynamic Gantt Charts for web applications 这个网站,真命天子 dhtmlxGantt 排名TOP1,于是我开始对其进行了试用及研究。
  • 经过一番折腾,终于做出了符合业务方需求的甘特图 :
  • 有一说一,与 echarts 模拟的甘特图一比,dhtmlxGantt 确实功能强大了许多,除了能实现对重要日期(如今日/项目开始时间/项目结束时间等)进行标示、tooltip、里程碑状态区分等功能之外,最重要的是可以实现按时/日/月/年的切换。
  • 由于 dhtmlxGantt 有免费版和付费版,一开始试用也不知道成不成功,所以我下载了免费版的源码进行了一番研究,幸好最后的结果也是可以通过一些配置来实现需求,下面将介绍怎么实现。

通过配置 dhtmlxGantt 实现的功能

在 react 项目中使用

  • dhtmlxGantt 在 github 提供了在 Vue.js/Angular/React 项目中的使用方法入口,本文将对如何在 react 项目中使用进行介绍(经实践)。
  • 下载命令:
yarn add dhtmlx-gantt
复制代码
  • 在组件中使用:
import 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
import 'dhtmlx-gantt/codebase/ext/dhtmlxgantt_marker.js';
import 'dhtmlx-gantt/codebase/ext/dhtmlxgantt_tooltip.js';
import 'dhtmlx-gantt/codebase/locale/locale_cn.js';
import * as React from 'react';
import { getGanttConfigByZoomValue } from '../../utils/milestone.lib';
import Toolbar from './components/Toolbar';
import * as styles from './index.module.less';

export default class Gantt extends React.Component<any> {
  state = {
    currentZoom: 'Days', // 默认按日维度展示
    isMount: false,
  };

  private ganttContainer: any;

  componentWillReceiveProps (nextProps: any) {
    this.generateGantt();
    this.setState({ isMount: true });
  }

  handleZoomChange = (zoom: string) => {
    this.setState({ currentZoom: zoom }, () => {
      this.generateGantt();
    });
  }

  async generateGantt () {
    const { ganttData } = this.props;
    if (this.state.isMount) { // 若不加判断,首次使用会报错
      gantt.clearAll(); // 移除所有任务,否则更新时任务会叠加
    }
    this.setConfig(); // 添加配置
    gantt.init(this.ganttContainer); // 初始化 dhtmlxGantt 到 ganttContainer 容器中
    gantt.parse(ganttData); // 将数据注入到甘特图
  }

  setConfig () {
    ...
  }

  setZoom (value: string) {
    gantt.config = {
      ...gantt.config,
      ...getGanttConfigByZoomValue(value), // 根据维度展示不同的日期格式
    };
  }

  renderContent () {
    const { currentZoom } = this.state;
    return (
      <React.Fragment>
        <div className={styles.zoomBar}>
          <Toolbar zoom={currentZoom} onZoomChange={this.handleZoomChange} />
        </div>
        <div className={styles.gantt}}>
          <div
            ref={input => {
              this.ganttContainer = input;
            }}
            style={{ width: '100%', height: '100%' }}
          />
        </div>
      </React.Fragment>
    );
  }
  
  render () {
    return (
      <div className={styles.ganttWrapper}>
        {this.renderContent()}
      </div>
    );
  }
}
复制代码
  • 根据 setConfig 和 setZoom 方法可以看到,我们可以通过对 gantt 实例进行操作来实现不同的功能。

只读模式

  • 在初始化 dhtmlxGantt 之前,通过将 gantt.config.readonly 设置为 true 来限制甘特图为只读模式:
gantt.config.readonly = true;
gantt.init(this.ganttContainer);
复制代码
  • 可以看到,尽管设置了只读模式,表格行被选中后无法取消选中,同时,表格列最右边仍有➕号按钮,虽然点了没有反应:
  • 解决表格行被选中后无法取消选中的问题,可以通过以下设置即可解决:
gantt.config.readonly = true; // 开启只读模式
select_task: false, // 禁止任务被选中,
gantt.init(this.ganttContainer);
复制代码
  • 至于表格列最右边仍有➕号按钮的问题,可以通过自定义表格列来解决 。

自定义表格列

  • 表格列设置如下:
gantt.config.columns = [
  {
    name: 'text',
    label: '里程碑节点',
    width: 280,
    template: function (obj: any) {
      return `节点:${obj.text}`; // 通过 template 回调可以指定返回内容值
    },
  },
];
gantt.init(this.ganttContainer);
复制代码
  • 结果如下:

自定义tooltip

  • 如果我们要自定义鼠标移动到任务上的 tooltip 提示,非常重要的一点是需要引入 dhtmlxgantt_tooltip.js,才可以使用通过 gantt.attachEvent 方法添加 tooltip,然后可以开始进行自定义:
// 自定义tooltip内容
gantt.templates.tooltip_text = function (start: Date, end: Date, task: any) {
  const t = gantt;
  const output = `<b>里程碑:</b>${task.text}<br/><b>状态:</b>${
    MILESTONE_STATE_MAP[task.state]
    }<br/><b>计划开始时间:</b>${t.templates.tooltip_date_format(
    start,
    )}<br/><b>计划结束时间:</b>${t.templates.tooltip_date_format(end)}`;
  return output;
},
// 添加tooltip
gantt.attachEvent('onGanttReady', function () {
  var tooltips = gantt.ext.tooltips;
  tooltips.tooltip.setViewport((gantt as any).$task_data);
});
复制代码
  • 当鼠标移动到项目上是,可以看到我们自定义的 tooltip 内容:

展示今日、项目开始和结束标示线

  • 与 tooltip 功能类似,如果需要使用标示线的功能,需要引入 dhtmlxgantt_marker.js,这样才能通过 gantt.addMarker 方法为一些重要日期的增加标示:
const { online_date, offline_date } = this.props;
// 今日红线
let today = new Date(`${getEndOfDate()}`); // getEndOfDate 为获取今天结束时间的方法
gantt.addMarker({
    start_date: today,
    css: 'today',
    text: '今日',
});

// 项目开始时间
if (online_date) {
  gantt.addMarker({
    start_date: online_date,
    css: 'projectStartDate',
    text: '项目开始',
  });
}

// 项目结束时间
if (offline_date) {
  gantt.addMarker({
    start_date: offline_date,
    css: 'projectEndDate',
    text: '项目结束',
  });
}
复制代码
  • 需要注意 ⚠️:除了今日标示线已经有默认样式以外,新增加的标示线需要指定css类名来增加样式:
.projectStartDate, .projectEndDate {
  background: #00bcd4;
}
复制代码
  • 结果:

自定义任务颜色

  • 可以通过设置 gantt.templates.task_class 实现任务颜色自定义:
task_class: function (start: Date, end: Date, task: any) {
  return `milestone-${task.state}`; // task.state值为default/unfinished/finished/canceled其中一种
},
复制代码
  • css:
.milestone-default {
  border: none;
  background: rgba(0, 0, 0, 0.45);
}
.milestone-unfinished {
  border: none;
  background: #5692f0;
}
.milestone-finished {
  border: none;
  background: #84bd54;
}
.milestone-canceled {
  border: none;
  background: #da645d;
}
复制代码

高亮周末日期颜色

  • 由于公司周末不上班 ,可以将周末日期颜色进行高亮:
// 突出周末颜色
(gantt.templates as any).timeline_cell_class = function (item: any, date: Date): string {
  if (date.getDay() === 0 || date.getDay() === 6) {
    return 'weekend';
  }
  return '';
};
复制代码
  • 结果:
  • 可以看到,由于按月和按年视图展示,会用当前列的时间去做计算,这样会导致整周/整月都被高亮,这明显不是我们想要的结果,那就改造一下吧:
// 突出周末颜色
const disableHighlight =
  this.state.currentZoom === 'Years' || this.state.currentZoom === 'Months';
(gantt.templates as any).timeline_cell_class = function (item: any, date: Date): string {
  if (!disableHighlight && (date.getDay() === 0 || date.getDay() === 6)) {
    return 'weekend';
  }
  return '';
};
复制代码
  • 可以看到,三月这一列变正常了:

切换视图

  • 切换视图的 Toolbar 组件在文档中有详细介绍,这里就不进行复述了,核心是getGanttConfigByZoomValue方法,用于设置不同视图的具体时间格式,代码如下:
export function getGanttConfigByZoomValue (value: string) {
  switch (value) {
    case 'Hours':
      return {
        scale_unit: 'day',
        scale_height: 50,
        min_column_width: 30,
        date_scale: '%Y-%m-%d',
        subscales: [
          {
            unit: 'hour',
            step: 1,
            date: '%H',
          },
        ],
      };
    case 'Days':
      return {
        scale_unit: 'week',
        scale_height: 50,
        min_column_width: 70,
        date_scale: '%Y年 %W周',
        subscales: [
          {
            unit: 'day',
            step: 1,
            date: '%m-%d',
          },
        ],
      };
    case 'Months':
      return {
        scale_unit: 'month',
        scale_height: 50,
        min_column_width: 70,
        date_scale: '%Y-%m',
        subscales: [
          {
            unit: 'week',
            step: 1,
            date: '%W周',
          },
        ],
      };
    case 'Years':
      return {
        scale_unit: 'year',
        scale_height: 50,
        min_column_width: 70,
        date_scale: '%Y年',
        subscales: [
          {
            unit: 'month',
            step: 1,
            date: '%M',
          },
        ],
      };
    default:
      return {};
  }
}
复制代码
  • 通过上面介绍的配置,即可实现符合业务方需求的甘特图 :

总结

  • 本文记录了我是为何弃用 echarts,转而改用 dhtmlxGantt 完成甘特图的过程,对一些功能的具体配置进行了详细的介绍。
  • 通过这次的需求我学到了很多,有时候应该转换思路,先找找有没有现成的开源库,看看在原来已有的功能基础上,能如何进行改造使其满足需求,这样能避免走很多弯路。正如牛顿所说:“如果说我看得比别人更远些,那是因为我站在巨人的肩膀上。”

以上内容如有遗漏错误,欢迎留言 ✍️指出,一起进步

如果觉得本文对你有帮助,留下你宝贵的


转载链接:https://juejin.im/post/5e7ffd56f265da794e526102

这里是云端源想IT,帮你轻松学IT”

嗨~ 今天的你过得还好吗?

睡眠等同于希望

每次醒来都是一个新的开始

一个新的希望


- 2024.03.22 -


在Web开发的世界中,CSS(层叠样式表)是构建视觉吸引力和定义网页布局的不可或缺的工具。

掌握如何恰当地引入CSS样式以及理解它们的优先级规则,对于前端开发者来说至关重要。今天,我们就来深入探讨CSS的四种引入方式,以及选择器的优先级之谜,了解常用的CSS样式及使用方法!



一、CSS四种样式引入方式

CSS(层叠样式表)为网页提供了丰富的样式定义,允许开发者通过多种方式将样式应用到HTML文档中。以下是四种主要的CSS引入方式:


1.1 行内样式

这是最直接也最简单的方法,通过在HTML元素的style属性中直接编写CSS规则。

示例:

<p style="color: red; font-size: 20px;">这是一段红色的文字。</p>


这种方式的优点是简单快捷,但缺点是它使得HTML代码与样式混合,不够纯净,且不利于样式的复用和维护。


1.2 内嵌样式

在一个HTML文档中使用<style>标签将CSS规则嵌入到HTML的head部分。这种方式适用于定义特定于某一页面的样式。

示例:

<head>
<style>
body {background-color: powderblue;}
h1 {color: blue;}
p {color: red;}
</style>
</head>
<body>
<h1>This is a heading</h1>
<p>This is a paragraph.</p>
</body>



1.3 外部样式

这是最常用的方法,它通过<link>标签将外部的CSS文件链接到HTML文档中。这种方法的优势在于可以在多个页面间共享同一个样式文件,有助于保持代码的整洁和一致性。

示例:

<head>
<link rel="stylesheet" type="text/css" href="mystyle.css">
</head>
<body>
<h1>This is a heading</h1>
<p>This is a paragraph.</p>
</body>
其中,mystyle.css的内容可能如下:
body {background-color: powderblue;}
h1 {color: blue;}
p {color: red;}


1.4 导入样式

使用@import语句在CSS文件中导入另一个CSS文件。尽管这种方法可以分离样式表,但它通常不被推荐使用,因为其加载时序可能会影响页面渲染效率。

示例:

@import url('https://fonts.googleapis.com/css?family=Roboto');
body {
font-family: 'Roboto', sans-serif;
}


1.5 样式单优先级

作用域范围:外部样式表>内部样式表>行内样式表


优先级:

  • 行内样式表>内部样式表>外部样式表
  • 相同的样式作用在同一个标签上:就近原则;不同的样式作用在同一个标签上:叠加。
  • 加载外部样式表或者内部样式表时候,需要注意加载顺序:加载html文件是从上向下加载的,也就是后面加载的样式会覆盖前面的样式。


二、CSS常用样式

2.1 字体样式

normal - 文字正常显示

italic - 文本以斜体显示

oblique - 文本为“倾斜”(倾斜与斜体非常相似,但支持较少)

font-weight 属性指定字体的粗细

示例:

<!DOCTYPE html>
<html>
<head>
<style>
.sp1{
color: darkorange;
font-size: 20px;
font-weight: bolder; /* bolder 字体是否加粗*/

font-style: italic; /* italic 字体是否倾斜*/

font-family: "宋体"; /* 设置字体样式*/
}

.sp2{
/* 简写 */
/* 顺序不能能变:style-weigth-size-family */
font:italic bolder 15px 宋体 ;
color:rgb(28, 235, 97);
}
</style>
<body>
<span>
编程学习,从云端源想开始!
</span><br>
<span>
让知识触手可及
</span>
<p>让知识触手可及</p>
</body>
</html>



2.2 文本样式

color: 字体颜色

text-align: center; - - 文本对齐方式

text-decoration:none; - - 文本的线

text-shadow: pink 5px 5px 2px; - - 文本的阴影 【阴影颜色-水平方向的偏移量-垂直方向的偏移量-模糊距离】

line-height: - - 行高 (文本在标签内所占的高度)

width:

height:

border: 1px #ffffff solid; - - 盒子边框【边框粗细-颜色-边框线样式】

示例:

<style>
.p{
color: rgb(0, 255, 21); /* 字体颜色 */
text-align: center; /* 文本对齐方式 */
text-decoration:none; /* 文本的线 */
text-shadow: pink 5px 5px 2px; /* 文本的阴影 【阴影颜色-水平方向的偏移量-垂直方向的偏移量-模糊距离】*/
line-height: 400px; /* 行高 (文本在标签内所占的高度)*/
width: 400px;
height: 300px;
border: 1px rgb(76, 14, 223) solid; /* 盒子边框【边框粗细-颜色-边框线样式】 */
}
</style>
</head>

<body>
<p>欢迎来到云端源想!</p>
<a href="https://www.baidu.com"></a>
</body>


2.3 背景样式

width: 500px;

height: 1200px;

background-color: pink; - - 背景颜色

background-image: url(…/img/background.jpg); - - 背景图片

background-repeat: no-repeat; - - 背景图片是否平铺

background-position: left top; - - 指定背景图片的位置

background-attachment: fixed; - - 背景图片是否随着标签滚动 【fixed-固定 scroll-滚动】

示例:

<style>
.d{
width: 500px;
height: 1200px;
background-color: pink; /* 背景颜色 */
background-image: url(../img/background.jpg); /* 背景图片 */
background-repeat: no-repeat; /* 背景图片是否平铺 */
background-position: left top; /* 指定背景图片的位置 */
background-attachment: fixed; /* 背景图片是否随着标签滚动 【fixed-固定 scroll-滚动】 */
}
</style>
</head>
<body>
<div>

</div>


2.4 列表样式

<!DOCTYPE html>
<html>
<head>
<style>
li{
background-color: lemonchiffon;
/*列表样式:常用取值:none-无样式 square-正方形 circle-空心圆 decimal-数字*/
list-style-type: circle;
/*列表样式为自定义图片*/
list-style-image: url(../img/2.jpg);
/*列表样式的放置位置*/
list-style-position: inside;
/*列表样式缩写*/
list-style: square url(../img/2.jpg) inside;
/*常用的列表样式*/
list-style: none;
}
</style>
</head>
<body>
<ul>
<li>列表项1</li>
<li>列表项2</li>
<li>列表项3</li>
</ul>
</body>
</html>


2.5 边框样式

<!DOCTYPE html>
<html>
<head>
<style>
.border{
/*边框宽度*/
border-width: 2px;
/*边框颜色*/
border-color: red;
/*边框样式:solid 实线 dotted 点线 dashed 虚线*/
border-style: dashed;
/*边框样式缩写:样式 颜色 宽度*/
border:solid green 5px;
/*边框可以为4个方向分别设置*/
border-top: dashed black 4px;
border-right: dashed #FF00FF 4px;
border-bottom: dotted darkblue 4px;
border-left: solid fuchsia 5px;
/*没有边框*/
border: none;
/*常用的细边框样式*/
border: solid 1px #ccc;
}
</style>
</head>
<body>
<div class="border">这是一个带有边框的元素</div>
</body>
</html>


2.6 盒子模型

所有的html元素可以看做是盒子,在css中,"box model"是用来设计和布局时使用。

CSS盒子模型本质是一个盒子,封装周围的html元素,它包括:边框、边距、填充、实际内容。

盒子模型允许我们在其他元素和周围元素边框之间的空间放置元素。

  • margin:外边距,清除边框外区域,外边距是透明的。
  • border:边框,围绕在内边距和内容外的边框。
  • padding:内边距,清除内容周围区域内边距是透明的。
  • content:内容,显示文字和图像。

想要快速入门前端开发吗?推荐一个前端开发基础课程,这个老师讲的特别好,零基础学习无压力,知识点结合代码,边学边练,可以免费试看试学,还有各种辅助工具和资料,非常适合新手!点这里前往学习哦!云端源想

示例:

<head>
<meta charset="UTF-8">
<title></title>
<style>
/* border:边框,分4个方向,同理margin、padding也分为四个方向
* margin:元素与元素之间对的距离
* padding:内容与边框之间的距离
* 设置的时候顺序:上 右 下 左
*/
.div{
border: solid red 10px;
/*四个方向上的元素与元素之间的距离都是50px*/
margin: 50px;
/*两个值的时候:第一个参数表示上下距离都是50px,第二个参数表示左右距离都是100px*/
margin: 50px 100px;
padding: 50px;
/*
一个元素真正的宽度=width+左右padding值+左右的border值
一个元素的真正高度=height+上下的padding值+上下的border值
* */
}
</style>
</head>
<body>
<div>111111111112222222222223333333333333333</div>
</body>

1)盒子的宽高

元素的实际宽度和高度:

  • 计算一个元素在实际在页面占据的总宽度=元素宽度+左填充+右填充+左边框+右边框+左边距+右边距
  • 元素实际在页面占据的总高度=元素高度+顶部填充+底部填充+上边框+下边框+上边距+下边距



2)设置宽度=元素实际宽度,box-sizing属性。

<head>
<meta charset="UTF-8">
<title></title>
<style>
/* box-sizing:确认元素的大小
content-box: 实际宽度=width+左右的psdding值+上下的border值
实际高度=height+上下的padding值+上下的border值
border-box:实际宽度=width;实际高度=height
padding和border不会影响元素的实际宽高
* */
.box{
width: 100px;
height: 200px;
border: 5px solid;
padding: 5px;
box-sizing: content-box;
}
</style>
</head>
<body>
<div>你好中国</div>
</body>


CSS的世界博大精深,以上只是冰山一角,希望通过这些基础的常用样式可以帮助你快速进入CSS世界的大门。


掌握CSS的引入方式和选择器优先级是构建高效、可维护网站的关键。通过这些知识,你可以更好地管理和优化你的样式代码,创造出既美观又专业的网页设计。现在,准备好迈入CSS的世界,开启你的创意之旅吧!


我们下期再见!


END

文案编辑|云端学长

文案配图|云端学长

内容由:云端源想分享