quiz icon indicating copy to clipboard operation
quiz copied to clipboard

CSS基础测试10

Open zhangxinxu opened this issue 6 years ago • 40 comments

本期题目如下,实现一个简单的下拉导航:

请附上对应的CSS代码,注意缩进和代码高亮,可以使用下面语法:

```css
你的代码在这里
```

请提供在线的可访问的demo地址(精力有限,没有demo减1分),如jsbin.com、jsfiddle.net或codepen.io,使用国内的类似工具也可以。

本周六因为有事,所以小测直播答疑为本周日8月11日上午10:00,大约30分钟,直播地址:https://live.bilibili.com/21193211

首位答题者有机会被翻牌,每位答题者都可获得2积分底分。

感谢您的参与!

zhangxinxu avatar Aug 07 '19 11:08 zhangxinxu

css大概就这些吧。

summary

demo

<div class="ui-menu-wrap">
        <details class="ui-menu" open>
            <summary class="ui-menu-summary">布局</summary>
            <div class="ui-menu-list">
                <a class="ui-btn">Flex 布局</a>
                <a class="ui-btn">Grid 布局</a>
                <a class="ui-btn">Shapes 布局</a>
                <a class="ui-btn">Flex 布局</a>
                <a class="ui-btn">Flex 布局</a>
            </div>
        </details>
        <details class="ui-menu" open>
            <summary class="ui-menu-summary">组件</summary>
            <div class="ui-menu-list">
                <a class="ui-btn">按钮</a>
                <a class="ui-btn">输入框</a>
                <a class="ui-btn">下拉列表</a>
                <a class="ui-btn">单选框</a>
            </div>
        </details>
    </div>
::-webkit-details-marker {
    display: none;
}

::-moz-list-bullet {
    font-size: 0;
}

summary {
    outline: 0;
}

.ui-btn {
    line-height: 40px;
    padding: 0 25px;
    font-size: 14px;
    color: #666;
    transition: .3s;
    cursor: pointer;
}

.ui-btn:hover {
    background: #edf9ff;
    color: #33b2ee;
}

.ui-menu-list .ui-btn {
    display: block;
}

.ui-menu-summary {
    position: relative;
    padding:0 10px;
    line-height: 40px;
    color: #333;
    font-size: 14px;
    font-weight: bold;
    cursor: pointer;
}

.ui-menu-summary::after {
    content: '';
    position: absolute;
    right: 10px;
    top: 50%;
    margin-top: 3px;
    width: 6px;
    height: 6px;
    border: 2px solid;
    border-width: 2px 2px 0 0;
    transform: translateY(-8px) rotate(135deg);
    transition: .3s;
}

.ui-menu[open] .ui-menu-summary::after {
    transform: translateY(-8px)  rotate(-45deg);
}

checkbox

demo

<div class="ui-menu-wrap">
        <div class="ui-menu">
            <input type="checkbox" id="menu01" checked>
            <label class="ui-menu-summary" for="menu01">布局</label>
            <div class="ui-menu-list">
                <a class="ui-btn">Flex 布局</a>
                <a class="ui-btn">Grid 布局</a>
                <a class="ui-btn">Shapes 布局</a>
                <a class="ui-btn">Flex 布局</a>
                <a class="ui-btn">Flex 布局</a>
            </div>
        </div>
        ...
    </div>
/*同上*/
.ui-menu-list{
  display:none;
}
.ui-menu>input[type="checkbox"]:checked+.ui-menu-summary::after {
    transform: translateY(-8px)  rotate(-45deg);
}
.ui-menu>input[type="checkbox"]{
  position:absolute;
  clip:rect(0,0,0,0)
}
.ui-menu>input[type="checkbox"]:checked+.ui-menu-summary+.ui-menu-list{
    display:block;
}

tagert

仅支持手风琴效果 demo

<div class="ui-menu-wrap">
        <div class="ui-menu">
            <a class="ui-menu-summary" id="menu01"  href="#menu01">布局</a>
            <div class="ui-menu-list">
                <a class="ui-btn">Flex 布局</a>
                <a class="ui-btn">Grid 布局</a>
                <a class="ui-btn">Shapes 布局</a>
                <a class="ui-btn">Flex 布局</a>
                <a class="ui-btn">Flex 布局</a>
            </div>
        </div>
        ...
    </div>
/*同上*/
.ui-menu-list{
  display:none;
}
.ui-menu-summary:target::after {
    transform: translateY(-8px)  rotate(-45deg);
}
.ui-menu-summary:target+.ui-menu-list{
    display:block;
}

focus, focus-within

demo

仅支持手风琴效果

<div class="ui-menu-wrap">
        <div class="ui-menu">
            <button class="ui-menu-summary">布局</button>
            <div class="ui-menu-list">
                <button class="ui-btn">Flex 布局</button>
                <button class="ui-btn">Grid 布局</button>
                <button class="ui-btn">Shapes 布局</button>
                <button class="ui-btn">Flex 布局</button>
                <button class="ui-btn">Flex 布局</button>
            </div>
        </div>
        ...
    </div>
/*同上*/
.ui-menu-list{
  display:none;
}
.ui-menu:focus-within .ui-menu-summary::after {
    transform: translateY(-8px)  rotate(-45deg);
}
.ui-menu:focus-within .ui-menu-list{
    display:block;
}

XboxYan avatar Aug 07 '19 12:08 XboxYan

在线demo

<div class="container">
  <dl class="list">
    <input type="checkbox" id="box1" class="checkbox" />
    <dt class="list_title">
      <span>布局</span>
      <label for="box1">
        <svg class="icon_up" t="1565179412806" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3378" width="200" height="200"><path d="M935.674 685.582L540.081 286.395c-14.055-14.175-36.936-14.272-51.11-0.22l-0.008 0.007c-0.145 0.145-0.184 0.33-0.32 0.464-0.61 0.574-1.408 0.719-2.02 1.34L87.475 683.551c-14.188 14.069-14.285 36.974-0.219 51.161 14.069 14.189 36.974 14.286 51.162 0.22l375.566-372.197 370.389 373.78c13.84 14.392 36.723 14.838 51.113 1 14.392-13.84 14.838-36.724 0.999-51.114a25.475 25.475 0 0 0-0.81-0.819z" p-id="3379"></path></svg>
      </label>
    </dt>
    <dd class="list_li">Flex布局</dd>
    <dd class="list_li">Grid布局</dd>
    <dd class="list_li">Shapes布局</dd>
    <dd class="list_li">Columns布局</dd>
  </dl>
  <dl class="list">
    <input type="checkbox" id="box2" class="checkbox" />
    <dt class="list_title">
      <span>组件</span>
      <label for="box2">
        <svg class="icon_up" t="1565179412806" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3378" width="200" height="200"><path d="M935.674 685.582L540.081 286.395c-14.055-14.175-36.936-14.272-51.11-0.22l-0.008 0.007c-0.145 0.145-0.184 0.33-0.32 0.464-0.61 0.574-1.408 0.719-2.02 1.34L87.475 683.551c-14.188 14.069-14.285 36.974-0.219 51.161 14.069 14.189 36.974 14.286 51.162 0.22l375.566-372.197 370.389 373.78c13.84 14.392 36.723 14.838 51.113 1 14.392-13.84 14.838-36.724 0.999-51.114a25.475 25.475 0 0 0-0.81-0.819z" p-id="3379"></path></svg>
      </label>
    </dt>
    <dd class="list_li">按钮</dd>
    <dd class="list_li">输入框</dd>
    <dd class="list_li">下拉列表</dd>
    <dd class="list_li">单复选框</dd>
  </dl>
</div>
.container {
  border-left: 2px solid #ccc;
  border-right: 2px solid #ccc;
  width: max-content;
  min-width: 140px;
  min-height: 200px;
  margin: 50px auto; /* 居中 */
}

.list_title {
  font-weight: bold;
  padding-left: 4px;
  padding-right: 4px;
}

.icon_up {
  width: 16px;
  height: 16px;
  float: right;
  cursor: pointer;
}

.checkbox { display: none; }

.list_li {
  margin: 0;
  padding: 4px 20px;
}

.list_li:hover {
  background: lightblue;
  color: rgb(0, 153, 255);
  cursor: pointer;
}

/****** 点击展开的交互效果实现 ******/
#box1:checked ~ .list_li {
  display: none;
}

#box1:checked ~ .list_title .icon_up {
  transform: rotate(180deg);
}

#box2:checked ~ .list_li {
  display: none;
}

#box2:checked ~ .list_title .icon_up {
  transform: rotate(180deg);
}
/****** 点击展开的交互效果实现 ******/

brenner8023 avatar Aug 07 '19 12:08 brenner8023

> 在线 DEMO <

思路:

  • 利用 :checked 伪类,配合 +(临近选择器) 和 ~(兄弟选择器),来实现子导航展开/折叠的交互效果;
  • 利用 max-heightopacity,配合 transition 实现过渡动画效果;
  • 注意 max-height 应根据实际情况设置合适的值,太大会造成“卡顿”现象,太小会剪裁掉内容;
  • 保留 checkbox 的键盘可访问性,即不使用 display: nonevisibility: hidden 的方式隐藏 checkbox;
  • 使用 visibility 来控制元素的可见性,避免元素视觉不可见时(max-height: 0; opacity: 0),被 Tab 键索引。
<main class="container">
  <nav class="navbar">
    <div class="navbar-group">
      <input class="navbar-group-switch" id="switch1" type="checkbox" checked>
      <label class="navbar-group-title" for="switch1">布局</label>
      <ul class="navbar-group-list">
        <li>
          <a href="#" class="navbar-link">Flex布局</a>
        </li>
        <li>
          <a href="#" class="navbar-link is-active">Grid布局</a>
        </li>
        <li>
          <a href="#" class="navbar-link">Shapes布局</a>
        </li>
        <li>
          <a href="#" class="navbar-link">Columns布局</a>
        </li>
      </ul>
    </div>
    <div class="navbar-group">
      <input class="navbar-group-switch" id="switch2" type="checkbox" checked>
      <label class="navbar-group-title" for="switch2">组件</label>
      <ul class="navbar-group-list">
        <li>
          <a href="#" class="navbar-link">按钮</a>
        </li>
        <li>
          <a href="#" class="navbar-link">输入框</a>
        </li>
        <li>
          <a href="#" class="navbar-link">下拉列表</a>
        </li>
        <li>
          <a href="#" class="navbar-link">单复选框</a>
        </li>
      </ul>
    </div>
  </nav>
</main>
body {
  margin: 0;
  font-size: 14px;
  line-height: 1.42858;
}

.container {
  max-width: 1170px;
  padding: 0 15px;
  margin: 0 auto;
}

/* 导航容器 */
.navbar {
  width: 160px;
  height: 100vh;
  overflow: auto;
  color: #353535;
  box-shadow: inset 1px 0 0 #e0e0e0,
              inset -1px 0 0 #e0e0e0;
}

/* 导航分组标题(点击折叠/展开子导航) */
.navbar-group-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  font-weight: 700;
  cursor: pointer;
}
.navbar-group-title::after {
  content: "";
  width: 6px;
  height: 6px;
  transform: rotate(225deg);
  border-style: solid;
  border-width: 2px 0 0 2px;
  transition: transform .3s;
}

/* 子导航列表 */
.navbar-group-list {
  max-height: 0;  /* 用以实现过渡动画 */
  padding: 0;
  margin: 0;
  visibility: hidden;  /* 元素不可见,避免被 tab-index 索引 */
  opacity: 0;  /* 用以实现过渡动画 */
  overflow: hidden;
  transition: all ease-in-out .3s;
  list-style: none;
}

/* 导航链接 */
.navbar-link {
  display: block;
  padding: 0 calc(10px + 1.5em);
  line-height: 40px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-decoration: none;
  color: inherit;
}
.navbar-link:hover,
.navbar-link.is-active {
  color: #36b3ee;
  background: rgb(54, 179, 238, .1);
}

/* 控制子导航展开/折叠的复选框 */
.navbar-group-switch {
  /* 剪切式隐藏,保留键盘可访问性 */
  position: absolute;
  clip: rect(0, 0, 0, 0);
}
.navbar-group-switch:focus + .navbar-group-title {
  background: rgb(54, 179, 238, .1);
}
.navbar-group-switch:checked + .navbar-group-title::after {
  transform: rotate(45deg);
}
.navbar-group-switch:checked ~ .navbar-group-list {
  max-height: 500px;  /* 根据实际情况合理设置其值 */
  visibility: visible;
  opacity: 1;
}

wingmeng avatar Aug 07 '19 13:08 wingmeng

image

JS Bin地址: 点我

能想到的纯 CSS 实现该效果方法:

  1. input:checked: 用 label for 触发对应 id 的 input checked 属性;
  2. details[open]:用 summary 触发 details 的 open「 兼容性要求较高 」;
  3. .acc-bd:target: 用 a的 hash 来触发对应 id 的 target 属性「一次只能展开一个」;

为了更好的兼容性,这里采用了 第一种作为开关触发器,其它两个方式类似。

.box {
	width: 15em;
	padding: 1em;
	float: left;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
	margin-right: 1em;
}

.acc-hd {
	margin: 0;
	padding: 1em 0;
	font-size: 1.1em;
	position: relative;
}

.acc-hd label {
	display: block;
	cursor: pointer;
}

.acc-bd {
	margin: 0;
	max-height: 0;
	overflow: hidden;
	transition: max-height 200ms;
}

.acc-switch {
	position: fixed;
	top: 0;
	left: 0;
	visibility: hidden;
	opacity: 0;
}

.acc-bd a {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	display: block;
	text-decoration: none;
	padding: 1em 1em 1em 2em;
	color: #333;
	transition: background-color 200ms, color 200ms;
}

.acc-bd a:hover, .acc-bd ._selected {
	background-color: #edf9ff;
}

.acc-bd ._selected, .acc-bd a:active {
	color: #41baf1;
}

.acc-bd + .acc-hd {
	margin-top: 1em;
}

.acc-switch:checked + .acc {
	height: auto;
}

/* 这个高度要高于最长的列表高度 */
.acc-switch:checked + .acc-hd + .acc-bd {
	max-height: 300px;
}

/* 三角形 */
.acc-hd label:after, .acc-hd label:before {
	position: absolute;
	content: '';
	top: 50%;
	right: 0;
	border-top: 5px solid;
	border-right: 5px dashed transparent;
	border-left: 5px dashed transparent;
	transition: margin-top 200ms, border-width 200ms;
}

.acc-hd label:after {
	border-top-color: #ffffff;
	margin-top: -2px;
}

.acc-switch:checked + .acc-hd label:after {
	border-bottom: 5px solid #ffffff;
	border-top: none 0;
	margin-top: 2px;
}

.acc-switch:checked + .acc-hd label:before {
	border-bottom: 5px solid;
	border-top: none 0;
}
<div class="box">
    <input id="accSwitch1" type="checkbox" checked class="acc-switch">
    <h3 class="acc-hd"><label for="accSwitch1">布局</label></h3>
    <p class="acc-bd">
        <a href="##" title="Flex布局">Flex布局</a>
        <a href="##" title="Grid布局" class="_selected">Grid布局</a>
        <a href="##" title="Shapes布局">Shapes布局</a>
        <a href="##" title="Columns布局">Columns布局</a>
    </p>
    <input id="accSwitch2" type="checkbox" checked class="acc-switch">
    <h3 class="acc-hd"><label for="accSwitch2">组件</label></h3>
    <p class="acc-bd">
        <a href="##" title="按钮">按钮</a>
        <a href="##" title="输入框">输入框</a>
        <a href="##" title="下拉列表">下拉列表</a>
        <a href="##" title="单复选框">单复选框</a>
    </p>
</div>
<div class="box">
    <input id="accSwitch3" type="checkbox" class="acc-switch">
    <h3 class="acc-hd"><label for="accSwitch3">布局</label></h3>
    <p class="acc-bd">
        <a href="##" title="Flex布局">Flex布局</a>
        <a href="##" title="Grid布局" class="_selected">Grid布局</a>
        <a href="##" title="Shapes布局">Shapes布局</a>
        <a href="##" title="Columns布局">Columns布局</a>
    </p>
    <input id="accSwitch4" type="checkbox" checked class="acc-switch">
    <h3 class="acc-hd"><label for="accSwitch4">组件</label></h3>
    <p class="acc-bd">
        <a href="##" title="按钮">按钮</a>
        <a href="##" title="输入框">输入框</a>
        <a href="##" title="下拉列表">下拉列表</a>
        <a href="##" title="单复选框">单复选框</a>
    </p>
</div>

ziven27 avatar Aug 07 '19 14:08 ziven27

demo

<div class="main">
  <div class="aside">
    <i class="bg"></i>
    <details open>
      <summary><dt>布局</dt></summary>
      <dd><a href="javascript:" role="button">Flex布局</a></dd>
      <dd><a href="javascript:" role="button">Grid布局</a></dd>
      <dd><a href="javascript:" role="button">Shapes布局</a></dd>
      <dd><a href="javascript:" role="button">Columns布局</a></dd>
    </details>
    <details open>
      <summary><dt>组件</dt></summary>
      <dd><a href="javascript:" role="button">按钮</a></dd>
      <dd><a href="javascript:" role="button">输入框</a></dd>
      <dd><a href="javascript:" role="button">下拉列表</a></dd>
      <dd><a href="javascript:" role="button">单选框</a></dd>
    </details>
  </div>
</div>
body {
  margin: 0;
  font-size: 16px;
}
/* 隐藏默认三角 */
::-webkit-details-marker {
  display: none;
}
::-moz-list-bullet {
  font-size: 0;
  float: left;
}
.main {
  overflow: hidden;
  font-size: 16px;
  margin-left: 10px;
}
.aside {
  float: left;
  width: 198px;
  padding-bottom: 3999em;
  margin-bottom: -3991em;
  background-color: #fff;
  border-right: 1px solid;
  border-left: 1px solid;
  border-color: lightgray;
}
.bg {
  position: absolute;
  top: 0;
  bottom: 0;
  margin-left: -1px;
  margin-right: -1px;
  width: 198px;
  border-right: 1px solid;
  border-left: 1px solid;
  border-color: lightgray;
  background-color: #fff;
}

details {
  position: relative;
}
summary {
  user-select: none;
  outline: 0;
}
dt::after {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  top: 6px;
  right: 10px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E %3Cpath fill='%23000000' d='M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z'%3E%3C/path%3E %3C/svg%3E")
    no-repeat;
  background-size: 100% 100%;
  transition: transform 0.2s;
}
[open] dt::after {
  transform: rotate(180deg);
}
dd,
dt {
  height: 30px;
  line-height: 30px;
  cursor: pointer;
}
dt {
  position: relative;
  font-weight: bold;
  padding-left: 0.7em;
}
dd {
  margin-left: 0px;
  font-size: 14px;
  color: #666;
}

a {
  padding-left: 2em;
  display: block;
  text-decoration: none;
  color: inherit;
  outline: 0;
}

dd:hover,
a:focus,
summary:focus {
  background-color: #edf9ff;
  color: #4cbaef;
}

Despair-lj avatar Aug 07 '19 14:08 Despair-lj

DEMO

<section>
    <aside class="fold-wrapper">
        <input class="fold-title-hidden" type="checkbox" name="" id="title1">
        <label class="fold-title" for="title1">布局</label>
        <div class="fold-body">
            <a role="button"><input type="radio" name="fold-item"><label>Flex布局</label> </a>
            <a role="button"><input type="radio" name="fold-item"><label>Grid布局</label> </a>
            <a role="button"><input type="radio" name="fold-item"><label>Shapes布局</label></a>
            <a role="button"><input type="radio" name="fold-item"><label>Columns布局</label></a>
        </div>
    </aside>
    <aside class="fold-wrapper">
        <input class="fold-title-hidden" type="checkbox" name="" id="title2">
        <label class="fold-title" for="title2">组件</label>
        <div class="fold-body">
            <a role="button"><input type="radio" name="fold-item"><label>按钮</label> </a>
            <a role="button"><input type="radio" name="fold-item"><label>输入框</label> </a>
            <a role="button"><input type="radio" name="fold-item"><label>下拉列表</label></a>
            <a role="button"><input type="radio" name="fold-item"><label>单复选框</label></a>
        </div>
    </aside>

</section>
.fold-wrapper {
    width: 150px;
    margin-bottom: 10px;
}

.fold-title {
    display: flex;
    align-items: center;
    font-weight: bold;
}

.fold-title::after {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-left: auto;
    border-left: 2px solid #000;
    border-top: 2px solid #000;
    transform: rotateZ(45deg);
    transition: all .2s linear;

}

.fold-title-hidden {
    display: none;
    /* position: absolute; */
}

.fold-title-hidden:checked+label::after {
    color: red;
    transform: rotateZ(225deg);
}

.fold-title-hidden:checked~.fold-body {
    display: none
}

.fold-body {
    padding-left: 1.5em;
}

.fold-body a {
    position: relative;
    display: block;
    margin: 10px 0;
}

.fold-body a:hover {
    color: #03a9f4;
}

.fold-body a:active {
    color: #03a9f4;
}

.fold-body input {
    position: absolute;
    width: 100%;
    height: 100%;
    cursor: pointer;
    opacity: 0;
}

.fold-body input:checked+label {
    color:#03a9f4;
}

livetune avatar Aug 07 '19 14:08 livetune

demo

<div class="menu-wrap">
  <ul class="menu-item">
    <input type="checkbox" id="check1">
    <label class="menu-item-label" for="check1">布局</label>
    <div class="menu-item-list">
      <a class="menu-item-nav">Flex 布局</a>
      <a class="menu-item-nav">Grid 布局</a>
      <a class="menu-item-nav">Shapes 布局</a>
      <a class="menu-item-nav">Flex 布局</a>
      <a class="menu-item-nav">Flex 布局</a>
    </div>
  </ul>
  <ul class="menu-item">
    <input type="checkbox" id="check2">
    <label class="menu-item-label" for="check2">组件</label>
    <div class="menu-item-list">
      <a class="menu-item-nav">按钮</a>
      <a class="menu-item-nav">输入框</a>
      <a class="menu-item-nav">下拉列表</a>
      <a class="menu-item-nav">单选框</a>
    </div>
  </ul>
</div>
ul {
  padding: 0;
  margin: 0;
}
.menu-wrap {
  width: 180px;
  background: #ccc;
}
.menu-item {
  padding-left: 20px;
  position: relative;
  border-bottom: 1px solid #fff;
}
.menu-item-label {
  display: inline-block;
  width: 100%;
  position: relative;
  line-height: 40px;
  cursor: pointer;
}
.menu-item-label::after {
  content: "";
  position: absolute;
  right: 20px;
  top: 50%;
  margin-top: 3px;
  width: 6px;
  height: 6px;
  border: 2px solid;
  border-width: 2px 2px 0 0;
  transform: translateY(-10px) rotate(135deg);
  transition: 0.3s;
}
input[type="checkbox"] {
  display: none;
}
.menu-item-list {
  max-height: 0;
  overflow: hidden;
  padding: 0 14px;
  transition: all 0.3s;
}
.menu-item-nav {
  display: inline-block;
  line-height: 40px;
  padding: 0 20px;
  width: 100%;
  margin-left: -30px;
}
.menu-item-nav:hover {
  background: #666;
  color: #fff;
  cursor: pointer;
}
input[type="checkbox"]:checked ~ .menu-item-list {
  max-height: 666px;
}
input[type="checkbox"]:checked ~ .menu-item-label::after {
  transform: translateY(-8px) rotate(-45deg);
}

GitHdu avatar Aug 07 '19 14:08 GitHdu

Demo

<ul class="menu-list">
    <li class="menu-item">
        <input type="checkbox" id="menu1" class="menu-checkbox" checked />
        <label class="menu-title" for="menu1">布局<i class="arrow"></i></label>
        <div class="sub-menu-list">
            <a href="#" class="menu-link">Flex布局</a>
            <a href="#" class="menu-link">Grid布局</a>
            <a href="#" class="menu-link">Shapes布局</a>
            <a href="#" class="menu-link">Columns布局</a>
        </div>
    </li>
    <li class="menu-item">
        <input type="checkbox" id="menu2" class="menu-checkbox" checked />
        <label class="menu-title" for="menu2">组件<i class="arrow"></i></label>
        <div class="sub-menu-list">
            <a href="#" class="menu-link">按钮</a>
            <a href="#" class="menu-link">输入框</a>
            <a href="#" class="menu-link">下拉框</a>
            <a href="#" class="menu-link">单复选框</a>
        </div>
    </li>
</ul>
.menu-list{
    width: 180px;
    height: 408px;
    margin: 0 auto;
    padding: 4px 0;
    border-left: 1px solid #ccc;
    border-right: 1px solid #ccc;
    list-style: none;
    padding-left: 0;
}
.menu-link,
.menu-title{
    display: block;
    height: 40px;
    line-height: 40px;
    font-size: 14px;
    text-decoration: none;
}
.menu-title{
    position: relative;
    padding: 0 10px;
    color: #333;
    cursor: pointer;
}
.menu-title .arrow{
    position: absolute;
    right: 10px;
    top: 50%;
    margin-top: -3px;
    border-color: #333 transparent transparent transparent;
}
.menu-title .arrow:before{
    content:"";
    position: absolute;
    left: -6px;
    border-color: #fff transparent transparent transparent;
    bottom: 2px;
}
.menu-title .arrow,
.menu-title .arrow:before{
    width: 0;
    height: 0;
    border-width: 6px 6px 0 6px;
    border-style: solid;
}
.menu-title:hover{
    background-color: rgb(241, 250, 255);
}
.menu-link{
    padding-left: 30px;
    color: #666;
    -webkit-transition: all .3s;
    -o-transition: all .3s;
    transition: all .3s;
}
.menu-link:hover{
    background-color: rgb(237, 249, 255);
    color: rgb(65, 181, 236);
}
.menu-checkbox{
    display: none;
}
.menu-checkbox:checked + .menu-title .arrow,
.menu-checkbox:checked + .menu-title .arrow:before{
    border-width: 0 6px 6px 6px;
}
.menu-checkbox:checked + .menu-title .arrow{
    border-color: transparent transparent #333 transparent;
}
.menu-checkbox:checked + .menu-title .arrow:before{
    bottom: auto;
    top: 2px;
    border-color: transparent transparent #fff transparent;
}
.sub-menu-list{
    display: none;
}
.menu-checkbox:checked ~ .sub-menu-list{
    display: block;
}

Tenwq avatar Aug 07 '19 16:08 Tenwq

Demo https://codepen.io/crazyboy/pen/zgRgQX

<ul class="nav-list">
	<li>
		<input type="checkbox" class="group-check" id="group-check-1"/>
		<label for="group-check-1" class="group-title">布局</label>
		<ul class="item-list">
			<li>Flex布局</li>
			<li>Grid布局</li>
			<li>Shapes布局</li>
			<li>Columns布局</li>
		</ul>
	</li>
	<li>
		<input type="checkbox" class="group-check" id="group-check-2"/>
		<label for="group-check-2" class="group-title">组件</label>
		<ul class="item-list">
			<li>按钮</li>
			<li>输入框</li>
			<li>下来列表</li>
			<li>单复选框</li>
		</ul>
	</li>
</ul>
.nav-list {
	position: fixed;
	padding: 0;
	border-style: solid;
	border-color: #ebedee;
	border-width: 0 1px;
}
.nav-list ul {
	padding: 0;
}
.nav-list li {
	list-style: none;
}
.item-list {
	transition: max-height 1s ease;
	overflow: hidden;
	max-height: 0;
}
.item-list li, .group-title {
	cursor: pointer;
}
.item-list li:hover, .group-title:hover {
	background-color: #edf9ff;
	color: #62c4f2;
}
.item-list li {
	padding: 0.7em 1.5em;
	color: #64676f;
}
.group-check {
	display: none;
}
.group-title {
	display: block;
	padding: 0.7em 0.5em;
	color: #62656d;
	font-weight: bolder;
}
.group-title::after {
	content: '';
	border-width: 0.15em;
	padding: 0.15em; 
	border-style: solid;
	float: right;
	border-color: #62656d #62656d transparent transparent;
	transform: rotate(135deg);
	margin-top: 0.15em;
	transition: transform 1s ease, margin 1s ease;
}
.group-check:checked + .group-title::after {
	transform: rotate(-45deg);
	margin-top: 0.65em;
}
.group-check:checked + .group-title + .item-list {
	max-height: 1000px;
}

NeilChen4698 avatar Aug 07 '19 17:08 NeilChen4698

demo

<div class="vertical-nav">
    <details class="ui-menu" open>
        <summary class="ui-title">布局</summary>
        <ul class="ui-list">
            <li>Flex布局</li>
            <li>Grid布局</li>
            <li>Shapes布局</li>
            <li>Columns布局</li>
        </ul>
    </details>
    <details class="ui-menu">
        <summary class="ui-title">组件</summary>
        <ul class="ui-list">
            <li>按钮</li>
            <li>输入框</li>
            <li>下拉列表</li>
            <li>单复选框</li>
        </ul>
    </details>
</div>
        * {
            margin: 0;
            padding: 0;
        }

        ul, li {
            list-style: none;
        }

        .vertical-nav {
            width: 200px;
            padding: 0 15px;
            margin: 100px auto;
            border-width: 0 1px 0 1px;
            border-style: solid;
            border-color: #ccc;
        }

        details.ui-menu {
            padding: 5px 0;
            user-select: none;
        }

        summary.ui-title {
            outline: none;
            position: relative;
        }

        ul.ui-list > li {
            padding: 12px 20px;
            cursor: pointer;
            transition: .2s;
        }

        ul.ui-list > li:hover {
            background: #edf9ff;
            color: #33b2ee;
        }

        summary::-webkit-details-marker {
            display: none;
        }

        summary:after {
            position: absolute;
            content: "";
            width: 8px;
            height: 8px;
            top: 5px;
            right: 30px;
            border-width: 2px 2px 0 0;
            border-style: solid;
            border-color: #000;
            transform: rotate(135deg);
            transition: .2s;
            cursor: pointer;
        }

        details.ui-menu[open] > summary.ui-title:after {
            transform: rotate(-45deg);
        }

guqianfeng avatar Aug 08 '19 02:08 guqianfeng

demo展示 html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
    <div class="menu">
      <div class="menu-group">
        <input type="checkbox" class="select-btn">
        <div class="menu-title">布局</div>
        <ul class="menu-list">
          <li class="cur">Flex 布局</li>
          <li>Grid 布局</li>
          <li>Shapes 布局</li>
          <li>Flex 布局</li>
        </ul>
      </div>
      <div class="menu-group">
         <input type="checkbox" class="select-btn">
         <div class="menu-title">组件</div>
         <ul class="menu-list">
          <li>按钮</li>
          <li>输入框</li>
          <li>下拉列表</li>
          <li>单选复选</li>
        </ul>
      </div>
    </div>
</body>
</html>

css

ul{
  list-style:none;
   padding:0;
    margin:0;
}

.menu{
  color:#434343;
  background:#fff;
  font-size:14px;
  border: solid #ccc;
  border-width: 0 1px;
  line-height:40px;
  margin:0;
  width:200px;

}

.menu-group{
    position:relative;
}

.select-btn{
  width:100%;
  margin:0;
  height:40px;
  position:absolute;
  opacity:0;
}

.select-btn:checked ~ .menu-list{
  display:none;
}

.menu-title{
  padding:0 10px;
}

.menu-title:after{
  content:"∧";
  float:right;
  font-weight:bold;
  font-size:16px;
}

.select-btn:checked + .menu-title:after{
  content:"∨";
}

.menu-list li{
  padding: 0 30px;
  cursor:pointer;
}

.menu .cur,.menu li:hover{
  color:#32b2ed;
  background:#edf9ff;
}

juzhiqiang avatar Aug 08 '19 03:08 juzhiqiang

demo

想到两种方法, 一种input加label 一种就是details了.

les-lee avatar Aug 08 '19 03:08 les-lee

我是参考了张老师的这篇文章来实现的借助HTML5 details,summary无JS实现各种交互效果

这道题中我将a标签的href去掉了,因为a是锚点的话我这里有两个问题:

  1. 点击的时候总是自动的跳到页面的顶部

  2. 点击的时候单选框按钮不能被选中

我本来打算将dl标签放到details标签中去的,可惜收起的动画效果不能实现,老师将dl放的跟detail标签同级是有意义的

jsbin

这是借助张老师的css代码

/* 隐藏默认三角 */
::-webkit-details-marker {
    display: none;
}

::-moz-list-bullet {
    font-size: 0;
}

summary {
    user-select: none;
    outline: 0;
}

summary::after {
    content: '';
    width: 12px;
    height: 12px;
    transition: transform .2s;
    background-size: 100%;
    background-repeat: no-repeat;
    
}

/* 动画效果 */
details+dl {
    max-height: 0;
    transition: max-height .25s;
    margin: 0 0 1rem;
    overflow: hidden;
}

[open]+dl {
    /* 原值是100,我改成了200 */
    max-height: 200px;
}

该题目中我自己的具体实现

.sidebar {
    width: 200px;
}

.sidebar summary {
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #000;
    font-weight: bold;
}

.sidebar summary::after {
    /* 我改成了svg直接内联 */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='icon' viewBox='0 0 1024 1024' version='1.1' width='128' height='128'%3E%3Cdefs%3E%3Cstyle type='text/css'/%3E%3C/defs%3E%3Cpath d='M472.064 272.448l-399.232 399.232c-22.08 22.08-22.08 57.792 0 79.872 22.016 22.016 57.792 22.08 79.872 0L512 392.256l359.296 359.296c22.016 22.016 57.792 22.08 79.872 0 22.08-22.08 22.016-57.792 0-79.872L551.936 272.448C529.856 250.432 494.144 250.432 472.064 272.448z' /%3E%3C/svg%3E");
    transform: rotate(180deg);
}

.sidebar [open] summary::after {
    transform: rotate(0deg);
}

.sidebar dd {
    margin-left: 0;
}
.sidebar dd label{
    display:block;
}
.sidebar dd a {
    display:block;
    padding:10px 0 10px 32px;
    color: #333;
    text-decoration: none;
}

/* 使用radio作为选中激活的办法 */
.sidebar [name=sidebar-radio] {
    /*键盘上下左右这种写法没办法高亮*/
    /* visibility: hidden; */
    clip-path: circle(0);
    position: absolute;
}

.sidebar [name=sidebar-radio]:checked+a {
    background: #edf9ff;
    color: #36b3ee;
}

html

<div class="sidebar">
    <details open>
        <summary>布局</summary>
    </details>
    <dl>
        <dd>
            <label>
                <input type="radio" name="sidebar-radio" checked autofocus />
                <a>Flex布局</a>
            </label>
        </dd>
        <dd>
            <label>
                <input type="radio" name="sidebar-radio" />
                <a>Grid布局</a>
            </label>
        </dd>
        <dd>
            <label>
                <input type="radio" name="sidebar-radio" />
                <a>Shapes布局</a>
            </label>
        </dd>
        <dd>
            <label>
                <input type="radio" name="sidebar-radio" />
                <a>Columns布局</a>
            </label>
        </dd>
    </dl>
    <details open>
        <summary>组件</summary>
    </details>
    <dl>
        <dd>
            <label>
                <input type="radio" name="sidebar-radio" />
                <a>按钮</a>
            </label>
        </dd>
        <dd>
            <label>
                <input type="radio" name="sidebar-radio" />
                <a>输入框</a>
            </label>
        </dd>
        <dd>
            <label>
                <input type="radio" name="sidebar-radio" />
                <a>下拉列表</a>
            </label>
        </dd>
        <dd>
            <label>
                <input type="radio" name="sidebar-radio" />
                <a>单复选框</a>
            </label>
        </dd>
    </dl>
</div>

liyongleihf2006 avatar Aug 08 '19 06:08 liyongleihf2006

> demo <

* { padding: 0; margin: 0; }
ul,li { list-style: none; }
.menu-list { width: 160px; height: 90vh; border: 1px solid #ccc; border-top: none; border-bottom: none; padding: 20px 0; }
.menu-sub { display: none;  transition: .2s;}
.menu-item-icon { display: inline-block; transform: rotate(90deg); transition: .2s; }
.menu-item { display: flex; justify-content: space-between; padding: 0 10px; line-height: 40px; }
.menu-group input { position: absolute; display: block; width: 100%; height: 40px; top: 0; opacity: 0; z-index: 0;}
.menu-group {position: relative; }
.menu-group input:checked+.menu-item .menu-item-icon{ transform: rotate(270deg); }
.menu-group input:checked+.menu-item+.menu-sub { display: block; }
.menu-sub-item {line-height: 40px; padding-left: 30px; font-size: 14px; cursor:default; }
.menu-sub-item:hover { background: #EDF9FF; color: #33b2ee; }
<div class="menu-list">
  <div class="menu-group">
    <input type="checkbox">
    <div class="menu-item">
      <b>布局</b>
      <span class="menu-item-icon">></span>
    </div>
    <ul class="menu-sub">
      <li class="menu-sub-item">Flex布局</li>
      <li class="menu-sub-item">Grid布局</li>
      <li class="menu-sub-item">Shapes布局</li>
      <li class="menu-sub-item">Columns布局</li>
    </ul>
  </div>
  <div class="menu-group">
    <input type="checkbox">
    <div class="menu-item">
      <b>组件</b>
      <span class="menu-item-icon">></span>
    </div>
    <ul class="menu-sub">
      <li class="menu-sub-item">按钮</li>
      <li class="menu-sub-item">输入框</li>
      <li class="menu-sub-item">下拉列表</li>
      <li class="menu-sub-item">单复选框</li>
    </ul>
  </div>
</div>

JaimeCheng avatar Aug 08 '19 06:08 JaimeCheng

demo

<div class="aside">
    <details open class="menu">
        <summary class="menu-summary">布局</summary>
        <ul class="menu-ul">
            <li class="menu-li"><a href="javascript:;">Flex布局</a></li>
            <li class="menu-li"><a href="javascript:;">Grid布局</a></li>
            <li class="menu-li"><a href="javascript:;">Shapes布局</a></li>
            <li class="menu-li"><a href="javascript:;">Columns布局</a></li>
        </ul>
    </details>
    <details class="menu">
        <summary class="menu-summary">组件</summary>
        <ul class="menu-ul">
            <li class="menu-li"><a href="javascript:;">按钮</a></li>
            <li class="menu-li"><a href="javascript:;">输入框</a></li>
            <li class="menu-li"><a href="javascript:;">下拉列表</a></li>
            <li class="menu-li"><a href="javascript:;">单复选框</a></li>
        </ul>
    </details>
</div>
/* reset */
ul, li {
    margin: 0;
    padding: 0;
    list-style: none;
}
a {
    color: #888a90;
    text-decoration: none;
}
/* 去掉默认箭头样式 */
::-webkit-details-marker {
    display: none;
}
::-moz-list-bullet {
    font-size: 0;
    float: flex;
}
/* 主要样式 */
.aside {
    width: 200px;
    border-left: 1px solid #e0e0e0;
    border-right: 1px solid #e0e0e0;
}
.menu {
    cursor: pointer;
}
.menu-summary {
    position: relative;
    padding: 0 10px;
    line-height: 40px;
    font-weight: 900;
    user-select: none;
    outline: none;
}
.menu-summary::after {
    content: '';
    position: absolute; right: 10px; top: 50%;
    margin-top: -4px;
    width: 8px;
    height: 8px;
    border: 2px solid;
    border-width: 2px 2px 0 0;
    transform: rotate(135deg);
    transition: all .2s;
}
.menu[open] .menu-summary::after {
    transform: rotate(-45deg);
}
.menu-li {
    padding-left: 40px;
    line-height: 30px;
}
.menu-li:hover {
    color: #5dc2f1;
    background: #edf9ff;
}
.menu-li:hover a {
    color: #5dc2f1;
}

ZhangXDong avatar Aug 08 '19 06:08 ZhangXDong

demo

<div class="menu-list">
   <details open> 
    <summary>布局</summary> 
    <dl>
      <dd>Flex布局</dd>
      <dd>Grid布局</dd>
      <dd>Shapes布局</dd>
      <dd>Columns布局</dd>
    </dl>
  </details>
  <details> 
    <summary>组件</summary> 
    <dl>
      <dd>按钮</dd>
      <dd>输入框</dd>
      <dd>下拉列表</dd>
      <dd>单复选框</dd>
    </dl>
  </details>
</div>
.menu-list {
  width: 150px;
  border-left: 1px solid #eee;
  border-right: 1px solid #eee;
}
details {
  width: 100%;
  font-size: 14px;
}
details > summary {
  position: relative;
  padding: 0 10px;
  line-height: 40px;
  outline: 0;
  font-weight: 500;
  color: #333;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  /* 清除summary默认样式(除了chrome浏览器,其他浏览器(Firefox也支持)可以通过list-style进行清除默认样式) */
  list-style: none;
}
/* Chrome清除summary默认样式 */
details > summary::-webkit-details-marker {
  display: none;
}
details > summary::after {
  content: '';
  position: absolute;
  right: 15px;
  top: 50%;
  width: 6px;
  height: 6px;
  border: 2px solid #666;
  border-left: none;
  border-top: none;
  transform: translateY(-50%) rotate(45deg);
  transition: transform .2s;
}
details[open] > summary::after {
  transform: translateY(-50%) rotate(-135deg);
}
details dl {
  margin: 0;
  max-height: 0;
  transition: max-height .25s;
  overflow: hidden;
}
details[open] dl {
  max-height: 200px;
}
details dd {
  margin-left: 0;
  padding-left: 2em;
  line-height: 40px;
  cursor: pointer;
  color: #666;
}
details dd:hover {
  background-color: #eff9fe;
  color: #33b2ee;
}

asyncguo avatar Aug 08 '19 06:08 asyncguo

Demo: https://codepen.io/wghwebitem/pen/rXdgrX

* {
				font-family: "微软雅黑";
			}
			
			ul {
				padding: 0;
				margin: 0;
				list-style: none;
				display: none;
				position: relative;
				top: 5px;
			}
			
			ul li {
				width: 100%;
				height: 35px;
				line-height: 35px;
				margin: 0 auto;
			}
			
			ul li div {
				width: 90%;
				height: 35px;
				text-decoration: none;
				display: block;
				color: #666;
				padding-left: 10%;
				cursor: pointer;
			}
			
			input {
				display: none;
			}
			
			.znav {
				width: 200px;
				border-left: 1px solid #ccc;
				border-right: 1px solid #ccc;
				background: #fafafa;
			}
			
			.znav .znav-div {
				position: relative;
				padding-top: 10px;
				padding-bottom: 10px;
			}
			
			.znav-div-tle {
				padding-left: 8px;
				cursor: pointer;
			}
			
			.znav-icon {
				position: absolute;
				top: 8px;
				right: 10px;
				width: 10px;
				height: 10px;
				border: solid #666;
				border-width: 2px 2px 0 0;
				display: block;
				transform: rotate(135deg);
				-webkit-transform: rotate(135deg);
				cursor: pointer;
			}
			
			.checks:checked~ul {
				display: block;
			}
			
			.checks:checked+.znav-icon {
				transform: rotate(-45deg);
				-webkit-transform: rotate(-45deg);
				margin-top: 10px;
				color: red;
			}
			
			.tradio:checked+div {
				background: #bdeffc;
				color: deepskyblue;
			}
**html**
<div class="znav">
			<div class="znav-div">
				<label for="ipt1">
					<input type="checkbox" class="checks" id="ipt1" checked/>
					<span class="znav-icon"></span>
					<div class="znav-div-tle">布局</div>
				    <ul>
						<label for="rad1"><li><input type="radio" class="tradio" id="rad1" name="r"><div>Flex布局</div></li></label>
						<label for="rad2"><li><input type="radio" class="tradio" id="rad2" name="r"><div>Grid布局</div></li></label>
						<label for="rad3"><li><input type="radio" class="tradio" id="rad3" name="r"><div>Shapes布局</div></li></label>
						<label for="rad4"><li><input type="radio" class="tradio" id="rad4" name="r"><div>Columns布局</div></li></label>
				     </ul>
				</label>
			</div>
			<div class="znav-div">
				<label for="ipt2">
					<input type="checkbox" class="checks" id="ipt2"/>
					<span class="znav-icon"></span>
					<div class="znav-div-tle">组件</div>
					<ul>
						<label for="rad5"><li><input type="radio" class="tradio" id="rad5" name="r"><div>按钮</div></li></label>
						<label for="rad6"><li><input type="radio" class="tradio" id="rad6" name="r"><div>输入框</div></li></label>
						<label for="rad7"><li><input type="radio" class="tradio" id="rad7" name="r"><div>下拉列表</div></li></label>
						<label for="rad8"><li><input type="radio" class="tradio" id="rad8" name="r"><div>单选选框</div></li></label>
					</ul>
				</label>
			</div>
		</div>

WGHwebitem avatar Aug 08 '19 12:08 WGHwebitem

demo 解析

将details中的隐藏元素去除,并将其写出来的原因是,如果写进去那么隐藏部分的height初始是auto,没办法从0开始所以不可以形成过渡动画,所以再将移除部分根据open属性值来给高度,因此 就可以有过渡动画效果 除了details这样的写法还有就算只要是有点击标签元素,标签元素会添加 特定属性的就可以了例如input[type='checkbox'],当我们点击input的时候会自动添加checkbox的属性,但是从语言上来说还是details会好一点 CSS

<style>
    .container {
      width: 180px;
      min-height: 600px;
      border-left: 1px solid #999;
      border-right: 1px solid #999;
    }

    .details-box {
      margin: 10px;
      /* max-height: 20px;
      overflow: hidden;
      transition: all 1s; */
    }

    .details-box summary {
      position: relative;
      font-weight: bold;
      cursor: pointer;
      /* 阻止选中 */
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      outline: 0;
    }

    .details-box summary a {
      color: inherit;
      text-decoration: none;
    }

    .details-box summary::after {
      content: '';
      position: absolute;
      width: 1em;
      height: 1em;
      top: .2em;
      right: 5px;
      background: url('https://www.zhangxinxu.com/study/201801/arrow-on.svg') no-repeat;
      background-size: 100% 100%;
      transform: rotate(180deg);
      transition: transform .2s;
    }

    .details-box:not([open]) summary::after {
      margin-top: .25em;
      transform: rotate(0deg);
    }

    /* 隐藏默认三角 */
    .details-box ::-webkit-details-marker {
      display: none;
    }

    .details-box ::-moz-list-bullet {
      font-size: 0;
    }

    .details-box+ul li {
      line-height: 2;
      color: #999999;
    }

    details+ul {
      margin: 0 0 0 10px;
      padding: 0 0 0 1em;
      max-height: 0;
      transition: max-height 1s;
      overflow: hidden;
      list-style-type: none;
    }

    details[open]+ul {
      max-height: 200px;
    }
  </style>

HTML

<div class="container">
    <details class="details-box layout">
      <!-- 解决outline交互体验 -->
      <summary   tabindex="-1"><a href="javascript:" onClick="this.parentNode.click();">布局</a></summary>
      <!-- <ul>
        <li>Flex布局</li>
        <li>Grid布局</li>
        <li>Shapes布局</li>
        <li>Columns布局</li>
      </ul> -->
    </details>
    <ul>
      <li>Flex布局</li>
      <li>Grid布局</li>
      <li>Shapes布局</li>
      <li>Columns布局</li>
    </ul>
    <details class="details-box component">
      <!-- 解决outline交互体验 -->
      <summary   tabindex="-1"><a href="javascript:" onClick="this.parentNode.click();">组件</a></summary>
      <!-- <ul>
        <li>按钮</li>
        <li>输入框</li>
        <li>下拉列表</li>
        <li>单复选框</li>
      </ul> -->
    </details>
    <ul>
      <li>按钮</li>
      <li>输入框</li>
      <li>下拉列表</li>
      <li>单复选框</li>
    </ul>
  </div>

zengqingxiao avatar Aug 08 '19 12:08 zengqingxiao

这题不会!

fzpijl avatar Aug 08 '19 14:08 fzpijl

demo

<!--  过度无障碍设置,优先使用语义化标签 -->
<ul class="mtree-wrapper" role="tree" aria-label="菜单"> 
 <li role="none"> 
  <details role="none" > 
   <summary class="mtree-title" role="treeitem" aria-level="1" aria-setsize="2" aria-posinset="1">布局</summary> 
   <ul class="mtree-group" role="group"> 
    <li> <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="5" aria-posinset="1" href="#flex" id="flex">Flex布局</a> </li> 
    <li> <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="5" aria-posinset="2" href="#grid" id="grid">Grid布局</a> </li> 
    <li> <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="5" aria-posinset="3" href="#shapes" id="shapes">Shapes布局</a> </li> 
    <li> <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="5" aria-posinset="4" href="#columns" id="columns">Columns布局</a> </li> 
    <li class="mtree-item" role="treeitem" aria-level="2" aria-setsize="5" aria-posinset="5" >
     <details role="none" > 
     <summary class="mtree-title" role="treeitem" aria-level="1" aria-setsize="1" aria-posinset="1">其他布局</summary> 
     <ul class="mtree-group" role="group"> 
      <li> <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="2" aria-posinset="1" href="#table" id="table">table布局</a> </li> 
      <li > <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="2" aria-posinset="2" href="#float" id="float">float布局</a> </li> 
     </ul> 
     </details>
    </li>
   </ul> 
  </details>
 </li> 
 <li role="none">
  <details role="none" > 
   <summary class="mtree-title" role="treeitem" aria-level="1" aria-setsize="2" aria-posinset="2">组件</summary> 
    <ul class="mtree-group" role="group"> 
     <li> <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="4" aria-posinset="1" href="#button" id="button">按钮</a> </li> 
     <li> <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="4" aria-posinset="2" href="#input" id="input">输入框</a> </li> 
     <li> <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="4" aria-posinset="3" href="#dropdown" id="dropdown">下拉列表</a> </li> 
     <li > <a class="mtree-item" role="treeitem" aria-level="2" aria-setsize="4" aria-posinset="4" href="#checkradio" id="checkradio">单复选框</a> </li> 
    </ul> 
  </details>
 </li> 
</ul>
.mtree-wrapper{
  border:1px solid lightgray;
  margin:0;
  padding:0;
  font-family:sans-serif;
}
.mtree-wrapper ::-webkit-details-marker {
    display: none;
}
.mtree-wrapper ::-moz-list-bullet {
    font-size: 0;
}
.mtree-wrapper ul,.mtree-wrapper li{
  list-style:none;
}
.mtree-group{
  padding-left:0;
}
.mtree-title{
  font-weight:bold;
  color:#333;
  line-height:3rem;
  height:3rem;
  text-indent:.5rem;
  cursor:pointer;
}
.mtree-title:hover{
  background:rgba(0,0,0,0.02);
}
.mtree-title::after{
  content:"";
  display:block;
  width:3rem;
  height:3rem;
  float:right;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M19.293 7.293l1.414 1.414L12 17.414 3.293 8.707l1.414-1.414L12 14.586z'/%3E%3C/svg%3E");
  background-size:1rem;
  background-position:center;
  background-repeat:no-repeat;
}
.mtree-item{
  line-height:3rem;
  display:block;
}
.mtree-wrapper [open] .mtree-title::after{
  transform:rotate(180deg);
}
.mtree-item:hover{
  background:rgba(0,0,0,0.02);
}
.mtree-item{
  padding-left:1.5rem;
  text-decoration:none;
  color:#333;
} 
.mtree-item:target{
    background: #edf9ff;
    color: #33b2ee;
}

Seasonley avatar Aug 08 '19 15:08 Seasonley

demo

<ul class="menu-box">
  <li>
    <input class="menu-checkbox" type="checkbox" checked id="menu-1" />
    <label class="menu-header" for="menu-1"><span>布局</span><i class="icon-arrow"></i></label>
    <ul class="menu-item">
      <li role="button">Flex布局</li>
      <li role="button">Grid布局</li>
      <li role="button">Shapes布局</li>
      <li role="button">Columns布局</li>
    </ul>
  </li>
  <li>
    <input class="menu-checkbox" type="checkbox" checked id="menu-2" />
    <label class="menu-header" for="menu-2"><span>组件</span><i class="icon-arrow"></i></label>
    <ul class="menu-item">
      <li role="button">按钮</li>
      <li role="button">输入框</li>
      <li role="button">下拉菜单</li>
      <li role="button">单复选框</li>
    </ul>
  </li>
</ul>
body {
  font-size: 16px;
}
ul,
li {
  list-style: none;
  padding: 0;
  margin: 0;
}
.menu-box {
  width: 155px;
  margin-left: 32px;
  border: 1px solid #ccc;
}
.menu-header {
  font-size: 16px;
  height: 36px;
  line-height: 36px;
  text-indent: 8px;
  position: relative;
  display: flex;
  font-weight: bold;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
}
.menu-checkbox {
  position: absolute;
  width: 0;
}
.menu-item {
  display: none;
}
.menu-item li {
  text-indent: 25px;
  height: 36px;
  line-height: 36px;
  cursor: pointer;
}
.menu-checkbox:checked ~ .menu-item {
  display: block;
}
.menu-checkbox:checked ~ .menu-header .icon-arrow {
  transform: rotate(45deg);
}
.menu-item li:hover,
.menu-item li:focus {
  background: #edf9ff;
  color: #6ec9f2;
}
.icon-arrow {
  width: 6px;
  height: 6px;
  border-top: 2px solid #000;
  border-left: 2px solid #000;
  transform: rotate(225deg);
  margin: 0 20px;
  transition: all 0.5s;
}

zy017 avatar Aug 08 '19 15:08 zy017

demo

html 代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <nav>
    <section>
      <input id='id-input-layout' class='toggle' type='checkbox' hidden>
      <label for='id-input-layout'>布局</label>
      <ol>
        <li>Flex布局</li>
        <li>Grid布局</li>
        <li>Shapes布局</li>
        <li>Columns布局</li>
      </ol>
    </section>
    
    <section>
      <input id='id-input-component' class='toggle' type='checkbox' hidden>
      <label for='id-input-component'>组件</label>
      <ol>
        <li>按钮</li>
        <li>输入框</li>
        <li>下拉列表</li>
        <li>单复选框</li>
      </ol>
    </section>
  </nav>
</body>
</html>

css 代码

* {
  padding: 0px;
  margin: 0px;
}

nav {
  border-left: 1px solid grey;
  border-right: 1px solid grey;
  display: inline-block;
}

label {
  display: flex;
  justify-content: space-between;
  
  padding: 0px 6px;
  margin: 10px 0px;
  
  font-weight: bold;
}
label::after {
  content: '∨';
  
  transform: rotate(0deg);
  transition: transform 0.5s;
}
.toggle:checked ~ label::after {  
  transform: rotate(180deg);
}

ol {
  visibility: hidden;
  max-height: 0px;
  
  padding: 0px;
  list-style-type: none;
  
  transition: max-height 0.5s;
}
.toggle:checked ~ ol{
  visibility: visible;
  max-height: 500px;
}

li {
  padding: 10px 24px;
}
li:hover {
  background-color: #edf9ff;
  color: #2fb0ec;
}

ghost avatar Aug 09 '19 01:08 ghost

CSS基础测试10

<section class="wrapper">
		<div class="outer">
			<span class="title">布局</span>
			<ul class="inner">
				<li class="item">Flex布局</li>
				<li class="item">Grid布局</li>
				<li class="item">Shapes布局</li>
				<li class="item">Columns布局</li>	
			</ul>
		</div>
		<div class="outer">
			<span class="title">组件</span>
			<ul class="inner">
				<li class="item">按钮</li>
				<li class="item">输入框</li>
				<li class="item">下拉列表</li>
				<li class="item">单复选框</li>	
			</ul>
		</div>
	</section>
		.wrapper {
			width: 200px;
			margin: 0 auto;
			border-left: 1px solid #dddddd;
			border-right: 1px solid #dddddd;
		}
		.inner {
			display: none;
			margin: 0;
			padding: 0;
		}
		.outer:hover .inner {
			display: block;
		}
		.title {
			display: inline-block;
			padding: 10px;
			color: black;
			font-weight: bold;
			cursor: pointer;
		}
		.title::after {
			content: '>';
			display: inline-block;
			transform: rotate(90deg) translateY(-130px);
		}
		.outer:hover .title::after {
			transform: rotate(-90deg) translateY(130px);
		}
		.item {
			padding: 8px 20px;
			list-style: none;
			font-size: 15px;
			cursor: pointer;
		}
		.item:hover {
			background: #edf9ff;
			color: #11a5e9;
		}

EmmaYXY avatar Aug 09 '19 02:08 EmmaYXY

DEMO HTML

<div class="togglebox">
  <!--外层嵌套div,改变menu:checked只影响内部-->
  <div>
    <input id="menu-layout" class="menu" type="checkbox" />
    <label for="menu-layout" class="menu-title">布局</label>
    <div class="menu-layout-item">
      <a>Flex布局</a>
      <a>Grid布局</a>
      <a>Shapes布局</a>
      <a>Columns布局</a>
    </div>
  </div>
  <div>
    <input id="menu-component" class="menu" type="checkbox" />
    <label for="menu-component" class="menu-title">组件</label>
    <div class="menu-layout-item">
      <a>按钮</a>
      <a>输入框</a>
      <a>下拉列表</a>
      <a>单复选框</a>
    </div>
  </div>
</div>

CSS

.togglebox {
  width: 200px;
  margin: 0 auto;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}

.menu {
  position: absolute;
  opacity: 0;
}

.menu-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  line-height: 50px;
  padding: 0 20px;
  font-size: 14px;
  font-weight: 700;
  border-top: 1px solid #ddd;
  background: #fff;
  cursor: pointer;
}
/*::after选择器在元素后面插入内容*/
.menu-title::after {
  content: "";
  width: 6px;
  height: 6px;
  transform: rotate(225deg);
  border-style: solid;
  border-width: 2px 0 0 2px;
  transition: transform 0.3s;
}
/*菜单内容默认高度为0隐藏,通过input的check状态变化修改高度大小做显示*/
.menu-layout-item {
  height: 0;
  opacity: 0;
  overflow: hidden;
  -webkit-transition: all 0.3s ease-in-out;
  -moz-transition: all 0.3s ease-in-out;
  -o-transition: all 0.3s ease-in-out;
  transition: all 0.3s ease-in-out;
}

.menu-layout-item a {
  line-height: 40px;
  padding: 0 25px;
  font-size: 14px;
  display: block;
  font-size: 12px;
  color: #666;
  cursor: pointer;
}

a:hover {
  background: #edf9ff;
  color: #33b2ee;
}
/*~选择器 父级以下对应的所有元素 如上述在父级添加div过滤外部相同元素*/
.menu:checked ~ .menu-layout-item {
  height: auto;
  opacity: 1;
}
/*+相邻兄弟选择器 获取相邻元素,两者具有相同父元素*/
.menu:checked + .menu-title::after {
  transform: rotate(45deg);
}

lifelikejuly avatar Aug 09 '19 03:08 lifelikejuly

demo链接: https://jsbin.com/zutoyaleyu/

<nav class="nav-wrap">
    <ul class="outter-ul">
        <li class="outter-li">
            <input id="outter-input-1" class="outter-input" type="checkbox" hidden />
            <label for="outter-input-1" class="outter-label">布局</label>
            <ul class="inner-ul">
                <li class="inner-li"><a href="javascript:;" class="active">flex布局</a></li>
                <li class="inner-li"><a href="javascript:;">grid布局</a></li>
                <li class="inner-li"><a href="javascript:;">shapes布局</a></li>
                <li class="inner-li"><a href="javascript:;">columns布局</a></li>
            </ul>
        </li>
        <li class="outter-li">
            <input id="outter-input-2" class="outter-input" type="checkbox" hidden />
            <label for="outter-input-2" class="outter-label">组件</label>
            <ul class="inner-ul">
                <li class="inner-li"><a href="javascript:;">按钮</a></li>
                <li class="inner-li"><a href="javascript:;">输入框</a></li>
                <li class="inner-li"><a href="javascript:;">下拉列表</a></li>
                <li class="inner-li"><a href="javascript:;">单复选按钮</a></li>
            </ul>
        </li>
    </ul>
</nav>
body {
    margin: 0;
}

ul {
    margin: 0;
    padding: 0;
}

li {
    list-style-type: none;
}

a {
    text-decoration: none;
}


.nav-wrap {
    box-sizing: border-box;
    max-width: 200px;
    min-height: 100vh;
    border-left: 1px solid #333;
    border-right: 1px solid #333;
}

.outter-ul {
    .outter-label {
        display: block;
        padding:0 10px;
        line-height: 40px;
        color: #333;
        font-weight: 700;
    }
}

.inner-ul {
    overflow: hidden;
    max-height: 0;
    .inner-li {
        >a {
            display: block;
            padding: 0 20px;
            line-height: 40px;
            color: #888;
        }
        .active{
            color: #39b4ee;
            background-color: #edf9ff
        }
    }
}

input[type="checkbox"]+label {
    position: relative;
    display: block;
    line-height: 40px;
    color: #333;
    font-weight: 700;
    &::after {
        position: absolute;
        right: 10px;
        top: 50%;
        content: '';
        border-top: 1px solid #333;
        border-left: 1px solid #333;
        width: 10px;
        height: 10px;
        transform: translateY(-50%) rotate(45deg);
    }
}

input[type="checkbox"]:checked+label::after {
    // transition: transform 1s ease;
    transform: translateY(-50%) rotate(-135deg);
}

input[type="checkbox"]:checked+label+.inner-ul {
    max-height: 100vh;
    transition: max-height 1s ease;
}

bugaosunihhh avatar Aug 09 '19 04:08 bugaosunihhh

demo

看到这道题想到了张老师的一篇文章,以前看张老师写过关于纯css交互效果

借助HTML5 details,summary无JS实现各种交互效果

ul, li {
    margin: 0;
    padding: 0;
}

ul {
    list-style: none;
}
summary{
    user-select: none;
    outline: 0;
}
summary a {
    text-decoration: none;
    color: inherit;
}
summary::-webkit-details-marker {
    display: none;
}

summary::-moz-list-bullet {
    font-size: 0;
}

.side-wrap {
    width: 180px;
    height: 500px;
    border-left: 1px solid #ececec;
    border-right: 1px solid #ececec;
}

.side-menu summary {
    position: relative;
    padding: 10px;
    color: #474a54;
}

.side-menu .side-submenu li {
    padding: 10px 30px;
    color: #87898f;
}

.side-menu .side-submenu li:hover {
    cursor: pointer;
    color: #3cb5ee;
    background: #edf9ff;
}

.side-menu summary::after {
    content: '';
    position: absolute;
    margin-top: 5px;
    right: 10px;
    width: 6px;
    height: 6px;
    border: 2px solid;
    border-width: 2px 2px 0 0;
    transform: rotate(135deg);
}

.side-menu[open] summary::after {
    margin-top: 8px;
    transform: rotate(-45deg);
}
<div class="side-wrap">
    <details class="side-menu" open>
        <summary tabindex="-1"><a href="javascript:">布局</a></summary>
        <ul class="side-submenu">
            <li>Flex布局</li>
            <li>Grid布局</li>
            <li>Shapes布局</li>
            <li>Columns布局</li>
        </ul>
    </details>
    <details class="side-menu">
        <summary><a href="javascript:">组件</a></summary>
        <ul class="side-submenu">
            <li>按钮</li>
            <li>输入框</li>
            <li>下拉列表</li>
            <li>单复选框</li>
        </ul>
    </details>
</div>

silverWolf818 avatar Aug 09 '19 05:08 silverWolf818

demo

css:

ul {
    list-style: none;
    padding: 0;
}

.menu-item {
    line-height: 40px;
    font-size: 14px;
    color: #666;
    transition: .3s;
    cursor: pointer;
}

.menu-item a {
    padding: 0 25px;
    color: #666;
    text-decoration: none;
    display: block;
}

.menu-item a:hover {
    background: #edf9ff;
    color: #33b2ee;
}

.menu-checkbox {
    display: none;
}

.menu-title {
    font-weight: bold;
    color: #333;
    position: relative;
    display: block;
}

.menu-title::after {
    content: '';
    position: absolute;
    right: 10px;
    top: 50%;
    margin-top: 3px;
    width: 6px;
    height: 6px;
    border: 2px solid;
    border-width: 2px 2px 0 0;
    transform: translateY(-8px) rotate(135deg);
    transition: .3s;
}

.menu-checkbox:checked+.menu-title::after {
    transform: translateY(-8px) rotate(-45deg);
}

.menu-checkbox:checked~.sub-menu {
    display: none;
}

html:

<ul class="ui-menu">
    <li class="menu-item">
        <input type="checkbox" id="menu1" class="menu-checkbox" />
        <label class="menu-title" for="menu1">布局</label>
        <ul class="sub-menu">
            <li class="menu-item"><a href="#">Flex布局</a></li>
            <li class="menu-item"><a href="#">Grid布局</a></li>
            <li class="menu-item"><a href="#">Shapes布局</a></li>
            <li class="menu-item"><a href="#">Columns布局</a></li>
        </ul>
    </li>
    <li class="menu-item">
        <input type="checkbox" id="menu2" class="menu-checkbox" />
        <label class="menu-title" for="menu2">组件</label>
        <ul class="sub-menu">
            <li class="menu-item"><a href="#">按钮</a></li>
            <li class="menu-item"><a href="#">输入框</a></li>
            <li class="menu-item"><a href="#">下拉列表</a></li>
            <li class="menu-item"><a href="#">单复选框</a></li>
        </ul>
    </li>
</ul>

hewxwshining avatar Aug 09 '19 07:08 hewxwshining

demo

<ul class="menu-container">
    <li>
        <input type="checkbox" id="item1">
        <label for="item1">
            <p class="menu-item-title"><span>布局</span><i class="arrow"></i></p>
        </label>
        <ul class="menu-item-container">
            <li class="menu-item">Flex布局</li>
            <li class="menu-item">Grid布局</li>
            <li class="menu-item">Shapes布局</li>
            <li class="menu-item">Columns布局</li>
        </ul>
    </li>
    <li>
        <input type="checkbox" id="item2">
        <label for="item2">
            <p class="menu-item-title"><span>组件</span><i  class="arrow"></i></p>
        </label>
        <ul class="menu-item-container">
            <li class="menu-item">按钮</li>
            <li class="menu-item">输入框</li>
            <li class="menu-item">下拉列表</li>
            <li class="menu-item">单复选框</li>
        </ul>
    </li>
</ul>
ul, li {
        list-style: none;
        padding: 0;
        margin: 0;
    }
    .menu-container {
        border: 1px solid #bababa;
        width: 153px;
    }
    .menu-item-title {
        font-size: 14px;
        font-weight: bold;
        padding: 0 8px;
        display: flex;
        justify-content: space-between;
        align-items: center; 
        cursor: pointer;
    }
    .menu-item-container {
        font-weight: normal;
        display: none;
    }
    .menu-item {
        padding-left: 30px;
        height: 40px;
        line-height: 40px;
        font-size: 14px;
    }
    .menu-item:hover {
        background: #edf9ff;
        cursor: pointer;
        color: #4bbbef;
    }
    .arrow {
        width: 4px;
        height: 4px;
        border-width: 2px;
        border-color: black black transparent transparent;
        border-style: solid;
        transform: rotate(-45deg);
        cursor: pointer;
    }
    input[type="checkbox"] {
        visibility: hidden;
        display: block;
        height: 0;
        margin: 0;
    }
    input[type="checkbox"]:checked~.menu-item-container {
        display: block;
    }
    input[type="checkbox"]:checked~.menu-item-title .arrow {
        transform: rotate(135deg);
    }

frankyeyq avatar Aug 09 '19 08:08 frankyeyq

DEMO 还是使用了点js,就为了切换开关的动效

<ul class="menu">
  <li class="menu-item">
    <div class="menu-item-label" onclick="openSubMenu(this)">布局</div>
    <ul class="menu-sub">
      <li class="menu-sub-item" id="flex"><a class="menu-sub-item-label" href="#flex">Flex布局</a></li>
      <li class="menu-sub-item" id="grid"><a class="menu-sub-item-label" href="#grid">Grid布局</a></li>
      <li class="menu-sub-item" id="shapes"><a class="menu-sub-item-label" href="#shapes">Shapes布局</a></li>
      <li class="menu-sub-item" id="columns"><a class="menu-sub-item-label" href="#columns">Columns布局</a></li>
    </ul>
  </li>
  <li class="menu-item">
    <div class="menu-item-label" onclick="openSubMenu(this)">组件</div>
    <ul class="menu-sub">
      <li class="menu-sub-item" id="button"><a class="menu-sub-item-label" href="#button">按钮</a></li>
      <li class="menu-sub-item" id="input"><a class="menu-sub-item-label" href="#input">输入框</a></li>
      <li class="menu-sub-item" id="select"><a class="menu-sub-item-label" href="#select">下拉列表</a></li>
      <li class="menu-sub-item" id="checks"><a class="menu-sub-item-label" href="#checks">单复选框</a></li>
    </ul>
  </li>
</ul>

使用的css里的target 切换的点击 上箭头和下箭头用的是label的两个伪元素,得到了有点奇怪的动效, 其实就是为了实验效果(之前从未写过)

ul {
  margin: 0;
  list-style: none;
  padding: 0;
}

.menu, .menu-item-label::after, .menu-item-label::before {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
}

.menu-sub-item-label:hover, .menu-sub-item-label:focus, .menu-sub-item-label:active, .menu-sub-item:target > .menu-sub-item-label { 
  background: #edf9ff;
  color: #3cb5ee;
  outline: none;
}

.menu {
  width: 200px;
  color: #333;
  margin: 0 auto 0 0;
  border: 1px solid #e5e5e5;
  border-style: none solid;
  overflow-y: auto;
}
.menu-item, .menu-sub-item {
  font-size: 15px;
}
.menu-item-label, .menu-sub-item-label {
  cursor: pointer;
  display: block;
  padding: 12px 6px 12px;
  transition: all 0.2s;
}
.menu-item .menu-sub, .menu-sub-item .menu-sub {
  overflow-y: hidden;
  height: 0;
  transition: all 0.2s;
}
.menu-item-label {
  position: relative;
  padding-left: 12px;
  font-weight: bold;
  overflow: hidden;
}
.menu-item-label::after, .menu-item-label::before { 
  content: "";
  width: 1px;
  height: 0.6em;
  background-color: currentcolor;
  transition: all 0.2s;
}
.menu-item-label::before {
  margin: auto 16px auto auto;
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
}
.menu-item-label::after {
  margin: auto 10px auto auto;
  -webkit-transform: rotate(-45deg);
          transform: rotate(-45deg);
}
.menu-item.open .menu-item-label::before {
  -webkit-transform: rotate(-45deg);
          transform: rotate(-45deg);
}
.menu-item.open .menu-item-label::after {
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
}
.menu-sub-item-label {
  padding-left: 30px;
  font-weight: normal;
  color: #666;
  text-decoration: none;
}

为了更好展示,还是加了一些js

// 切换子菜单打开还是关闭
const openSubMenu=(dom)=>{
  const {classList}=dom.parentElement,
        className='open',
        {nextElementSibling}=dom;
        hasClass=classList.contains(className),
        h=hasClass?0:nextElementSibling.scrollHeight;
  nextElementSibling.style.height=`${h}px`; // 切换高度,适应css3 过渡效果
  classList.toggle(className); // 切换class
}

8-10 更新

新的Demo 使用radio和checkbox配合css3 :checked 选中效果 使用line-heightopacity配合过度效果,终于纯css实现了 😭

怕代码太长,影响阅读,直接使用pug

ul.menu
  each item in menus
    li.menu-item
      input.none.menu-check(type="checkbox",checked,name="menu",id=item.name)
      label.menu-item-label(for=item.name)= item.label
      ul.menu-sub
        each subitem in subMenus
          if subitem.pname===item.name
            li.menu-sub-item
              input.none.menu-check(type="radio",id=subitem.name,name="submenu")
              label.menu-sub-item-label(for=subitem.name)= subitem.label

只展示修改部分的scss

.none {
  display: none;
}
.menu-sub-item {
    &-label {
      cursor: pointer;
      display: block;
      font-size: 15px;
      line-height: 3;
      overflow: hidden;
      transition: all $time;
    }
}
// 两个选中效果
.menu-check:checked {
  // 外层选中
  & ~ .menu-sub .menu-sub-item-label {
    line-height: 0;
    opacity: 0;
  }
  & ~ .menu-item-label {
    &::before {
      transform: rotate(45deg);
    }
    &::after {
      transform: rotate(-45deg);
    }
  }
  // 子菜单选中
  & ~ .menu-sub-item-label{
    @extend %hover;
  }
}

效果终于满意了 : )

Forx-Js avatar Aug 09 '19 09:08 Forx-Js

demo

<div class="droplist">
<!--   menu layout -->
  <div class="menu">
    <input type="radio" id="rdo-layout" name="rdo-menu">
    <label for="rdo-layout">布局</label>
    <dl>
      <dd>Flex布局</dd>
      <dd>Grid布局</dd>
      <dd>Shapes布局</dd>
      <dd>Columns布局</dd>
    </dl>  
  </div>
  <!--  menu component -->
  <div class="menu">
    <input type="radio" id="rdo-component" name="rdo-menu">
    <label for="rdo-component">组件</label>
    <dl>
      <dd>按钮</dd>
      <dd>输入框</dd>
      <dd>下拉列表</dd>
      <dd>单复选框</dd>
    </dl>
  </div>
</div>
<style type="text/css">
:root {
  --main-color: #51545c;
  --second-color: #ececec;
}
.droplist {
  border-style: solid;
  border-color: transparent var(--second-color);
  color: var(--main-color);
  width: 180px;
}
label {
  font: bold 14px/.9 YaHei; 
  display:block;
  padding: 10px;
}
label::after {
  content: '';
  border-style: solid;
  border-color: var(--main-color) var(--main-color) transparent transparent;
  width: .5rem;
  height:.5rem;
  float: right;
  transform: translateY(.3rem) rotate(-45deg);
  transition: transform .3s ease-out;
}
dl {
  line-height: 2.5;
  margin: 0;
  max-height: 0;
  overflow: hidden;
  transition: max-height .3s ease-out;
}
dd {
  margin: 0;
  padding: 0 10px;
  text-indent: 2rem;
}
dd:hover {
  color: #44b8ef;
  background: #edf9ff;
}
input[type=radio]:checked + label::after {
  transform: translateY(-.3rem) rotateZ(135deg);
}
input[type=radio]:checked ~ dl {
  max-height: 1000px;
}
.menu input[type=radio] {
  display: none;
}
</style>

9lk avatar Aug 10 '19 02:08 9lk