CSS 关于多级菜单的内边距的处理方式

2019-05-22 admin

clipboard.png

原文地址,排版效果更好

https://blog.codelabo.cn/article/5ce4f0eb8aab210ff34d0150

https://xboxyan.codelabo.cn/post/css-tree-padding/

在平时的项目中会经常碰到这样一种布局,暂且称之为多级菜单吧

clipboard.png

(截图来自于ant-design

这类布局也很容易,大概就是这样ulli嵌套,如下

<ul class="parent">
    <li>
        <div>Navigation01</div>
        <ul>
            <li><div>Option01</div></li>
            <li><div>Option02</div></li>
            <li>
                <div>Submenu</div>
                <ul>
                    <li><div>Option03</div></li>
                    <li><div>Option04</div></li>
                </ul>
            </li>
        </ul>
    </li>
    <li><div>Navigation02</div></li>
</ul>

于是就得到下面一个很原始的样式。

clipboard.png

再经过简单的修饰就可以达到上面的效果了。

当然,这个很容易,一般情况下我们是通过设置内边距来完成的,比如默认为

ul{
    padding-left:40px;
}

然后每一层级跟随父级逐步累积,然后就实现了,层级越深,距离左边的缩进越多的效果。

多级菜单选中范围

通过上面的布局和样式,很显然每一项的选择范围都是逐步缩进的,

clipboard.png

但是,可能设计师觉得不好看,往往会设计成通栏的形式,比如像上面ant-design的设计

clipboard.png

那么,该如何处理呢?

通栏的处理方式

首先,一个很自然的思路就是去除ulpadding,改为每一个子项分别指定padding

ul.parent{
    padding: 0;
}

然后将内边距直接写在html上,如下

<ul  class="parent">
    <li>
        <div style="padding-left:40px">Navigation01</div>
        <ul>
            <li><div style="padding-left:80px">Option01</div></li>
            <li><div style="padding-left:80px">Option02</div></li>
            <li>
                <div style="padding-left:80px">Submenu</div>
                <ul>
                    <li><div style="padding-left:120px">Option03</div></li>
                    <li><div style="padding-left:120px">Option04</div></li>
                </ul>
            </li>
        </ul>
    </li>
    <li><div style="padding-left:40px">Navigation02</div></li>
</ul>

如果菜单层级较多,我们通常使用js来辅助生成,注意每一次循环来指定不同的内边距就可以了

clipboard.png

ant-design也是采取这种方式,可以自行打开控制台去查看。

记得刚入前端的时候就是采取的这种方式,效果实现就好。

不过,在现在看来,在html中使用内联样式始终不雅,而且数量较多时还需要和js扯上关系,能否优化一下呢

下面列举两种css方式

1.子选择器

我们可以在上面的基础上,分别控制每一级的内边距,这里我们可以使用子选择器>

ul.parent>li>div{/**第一级**/
    padding-left: 40px;
}
ul.parent>li>ul>li>div{/**第二级**/
    padding-left: 80px;
}
ul.parent>li>ul>li>ul>li>div{/**第三级**/
    padding-left: 120px;
}
/** ... **/

通常,在层级不是特别多的情况下,我们可以一一罗列出来,只需用选择器ul>li叠加即可,是不是比style方便维护了很多呢?

2.absolute半依赖定位

在讲这个方法之前,首先搞清楚一个问题

absolute在不设置方向属性lefttoprightbottom时,默认位置是哪里?

在我的学习过程中,很多地方讲到的都是说absolute是绝对定位,是相对于第一个有定位属性的父级的,所以基本上都是和relative一起使用,反正不管三七二十一,直接就给父级加上position:relative,有一个可靠的父级,看着比较靠谱,不是吗?

其实,当元素设置了absolute属性,没有方向属性时,元素仍保留在原来位置,只是不占空间而已

比如,我给上面每一项后面加一个角标

ul.parent div:after{
    content:'new';
    font-size: 10px;
    position:absolute;
    margin-top: -5px;
    color: red
}

clipboard.png

可以看到,虽然设置了absolute属性,但元素仍保留在原来位置,一旦设置了left等方位属性,就会查找第一个有定位属性的父级。

现在,我们把css还原为默认的状态,也就是

ul{
    padding-left:40px;
}

现在情况就和初始状态一致,选中范围逐层递减,那么,如何实现选中范围为通栏呢

我们可以给最外层父级设置position:relative,因为通栏的宽度是相对于最外层的,然后给选中元素设置

ul.parent div:hover:before{
    content:'';
    position:absolute;
    left:0;
    right:0;
    height:21px;
    background: violet;
    z-index: -1;
}

clipboard.png

这里只设置了水平方向的leftright,没有设置垂直方向上的属性,所以水平位置会跟随父级定位元素(这里是最外层),而垂直方向位置还是基于当前父级(这里是父级li元素)

注意,这里的高度由于是基于最外层元素,所以,这里不能设置height:100%,那么,如何解决这一个小瑕疵呢,毕竟在这里写一个固定高度实在不怎么合适。

这里有两种方式来优化。

方式一

上面的方式如果不指定高度,由于没有内容,高度自然为0,解决方式也很简单,在content插入一个空字符或者透明字符即可

ul.parent div:hover:before{
    content:'\A0';
}

或者

ul.parent div:hover:before{
    content:'任意字符';
        color:transparent;
}

方式二

通常子项目的高度都是固定的,可以给子项目手动指定一个高度,然后选中项继承该高度即可

ul.parent div{
    height:24px;
    line-height:24px;
}
ul.parent div:hover:before{
    content:'';
        height:inherit
}

注意这里的height:inherit是继承直接父级的高度,有兴趣的可以看张鑫旭的这篇文章

这样也实现了通栏的效果

https://codepen.io/xboxyan/pe…

小节

上面介绍了两种实现通栏的方法,相比而言,absolute效果更好,也易于维护,可能一个并不怎么起眼的属性,有时候也能发挥出意想不到的效果。

下面有一个案例,纯css实现,可以查看一下

clipboard.png

https://codepen.io/xboxyan/pe…

[转载]原文链接:https://segmentfault.com/a/1190000019260176

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-65473.html

文章标题:CSS 关于多级菜单的内边距的处理方式

相关文章
js性能优化 如何更快速加载你的JavaScript页面
确保代码尽量简洁 不要什么都依赖JavaScript。不要编写重复性的脚本。要把JavaScript当作糖果工具,只是起到美化作用。别给你的网站添加大量的JavaScript代码。只有必要的时候用一下。只有确实能改善用户体验的时候用一下。 ...
2015-11-12
10个强大的纯CSS3动画案例分享
我们的网页外观主要由CSS控制,编写CSS代码可以任意改变我们的网页布局以及网页内容的样式。CSS3的出现,更是可以让网页增添了不少动画元素,让我们的网页变得更加生动有趣,并且更易于交互。本文分享了10个非常炫酷的CSS3动画案例,希望大家...
2015-11-16
国内外html5游戏引擎排行
一个好的HTML5游戏引擎,能够大大简化游戏的开发实现。 排名列表: Construct 2 ImpactJS EaselJS pixi.js Phaser GameMaker Three.js PlayCanvas Turbulenz ...
2015-11-12
v-charts | 饿了么团队开源的基于 Vue 和 ECharts 的图表工具
在使用echarts生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,v-charts的出现正是为了解决这个 痛点。基于Vue2.0和echarts封装的v-charts图表组件,只需要统一提供一种对前后端都友好的数据格式 设置简...
2018-05-24
从2014年的发展来展望JS的未来将会如何
&lt;font face=&quot;寰�杞�闆呴粦, Arial, sans-serif &quot;&gt;2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
12个你未必知道的CSS小知识
虽然CSS并不是一种很复杂的技术,但就算你是一个使用CSS多年的高手,仍然会有很多CSS用法/属性/属性值你从来没使用过,甚至从来没听说过。 1.CSS的color属性并非只能用于文本显示 对于CSS的color属性,相信所有Web开发人员...
2015-11-12
ajax为什么令人惊异?ajax的优缺点
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。 Ajax不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。就像DHT...
2015-11-12
HTML5的5个不错的开发工具推荐
HTML5规范终于在今年正式定稿,对于从事多年HTML5开发的人员来说绝对是一个重大新闻。数字天堂董事长,DCloud CEO王安也发表了文章,从开发者和用户两个角度分析了HTML对两个人群的优势。其实,关于HTML5的开发工具,我们以往的...
2015-11-12
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
AJAX的浏览器支持
AJAX 的要点是 XMLHttpRequest 对象。 不同的浏览器创建 XMLHttpRequest 对象的方法是有差异的。 IE 浏览器使用 ActiveXObject,而其他的浏览器使用名为 XMLHttpRequest 的 Jav...
2015-11-12
回到顶部