有一天,我在没有使用脚本的情况下绘制了顶级菜单的代码。一切顺利,但对吗?事实上,我用于造型input type="checkbox"等等pointer-events: none;。项目中有这样的实现吗,还是这种情况还是用JS比较好?
菜单代码:
body {
font-family: Tahoma, Arial
}
.topbar {
display: flex;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 40px;
background-color: white;
border-bottom: 2px solid rgba(0, 0, 0, 0.08);
}
.topbar__button-open-leftmenu {
display: block;
width: 24px;
height: 24px;
padding: 8px;
cursor: pointer;
}
.topbar__button-open-leftmenu:hover {
border-bottom: 2px solid #1C90F3;
}
.topbar__button-open-leftmenu svg path {
fill: #333;
}
.topbar__button-open-leftmenu:hover svg path {
fill: #000;
}
.topbar__memu {
display: flex;
list-style: none;
padding: 0;
margin: 0 auto 0 0;
opacity: 1;
transform: translateX(0);
transition: all 0.4s ease;
pointer-events: auto;
}
.topbar__memu li {
transform: scale(1);
transition: all 0.6s ease;
opacity: 1;
}
.topbar__memu li:nth-child(1) {
transition-delay: 0s;
}
.topbar__memu li:nth-child(2) {
transition-delay: 0.1s;
}
.topbar__memu li:nth-child(3) {
transition-delay: 0.2s;
}
#topbar__checked-search:checked ~ .topbar__memu li:nth-child(1) {
transform: scale(0);
transition-delay: 0.2s;
opacity: 0;
pointer-events: none;
}
#topbar__checked-search:checked ~ .topbar__memu li:nth-child(2) {
transform: scale(0);
transition-delay: 0.1s;
opacity: 0;
pointer-events: none;
}
#topbar__checked-search:checked ~ .topbar__memu li:nth-child(3) {
transform: scale(0);
transition-delay: 0s;
opacity: 0;
pointer-events: none;
}
.topbar__memu-item {
display: block;
height: 40px;
padding: 0 10px;
line-height: 40px;
font-size: 0.8rem;
color: #333;
text-decoration: none;
}
.topbar__memu-item:hover {
color: #000;
border-bottom: 2px solid #1C90F3;
}
.topbar__button-open-search {
display: block;
position: relative;
width: 40px;
height: 40px;
}
.topbar__button-open-search:hover {
background-color: #f5f5f5;
}
.topbar__button-open-search svg {
position: absolute;
top: 10px;
left: 10px;
width: 20px;
height: 20px;
}
.topbar__button-open-search svg path {
fill: #333;
}
.topbar__button-open-search:hover svg path {
fill: #000;
}
.topbar__button-open-search svg#icon-serach-close {
opacity: 1;
transition: all 0.4s ease;
}
.topbar__button-open-search svg#icon-serach-open {
opacity: 0;
transition: all 0.4s ease;
}
#topbar__checked-search:checked ~ .topbar__button-open-search svg#icon-serach-close {
opacity: 0;
transition: all 0.4s ease;
}
#topbar__checked-search:checked ~ .topbar__button-open-search svg#icon-serach-open {
opacity: 1;
transition: all 0.4s ease;
}
#topbar__checked-search {
display: none;
}
.topbar__search {
display: block;
position: absolute;
left: 50%;
top: 0;
width: 60%;
height: 30px;
padding: 5px;
opacity: 0;
transform: translateX(-50%);
transition: opacity 0.4s ease;
pointer-events: none;
}
#topbar__checked-search:checked ~ .topbar__search {
transition-delay: 0.6s;
opacity: 1;
pointer-events: auto;
}
.topbar__search-input {
display: block;
width: calc(100% - 40px);
height: 30px;
padding: 0 30px 0 10px;
border: none;
border-radius: 3px;
background-color: #f4f4f4;
font-family: inherit;
outline: none;
transition: background 0.2s ease;
}
.topbar__search-input:focus {
background-color: #eeeeee;
}
.topbar__search-button {
display: block;
position: absolute;
top: 11px;
right: 12px;
width: 18px;
height: 18px;
padding: 0;
background: none;
border: none;
cursor: pointer;
}
.topbar__search-button svg path {
fill: #333;
}
.topbar__search-button:hover svg path {
fill: #000;
}
.topbar__search-panel {
display: block;
position: fixed;
top: 42px;
left: 0px;
width: 100%;
height: calc(100vh - 42px);
background-color: rgba(0, 0, 0, 0.6);
opacity: 0;
pointer-events: none;
transition: opacity 1s ease;
}
#topbar__checked-search:checked ~ .topbar__search-panel {
opacity: 1;
pointer-events: auto;
}
.topbar__search-panel-list {
display: block;
position: absolute;
top: 10px;
left: 50%;
width: 60%;
padding: 5px 0;
border-radius: 2px;
transform: translateX(-50%) translateY(-20%);
background-color: white;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
transition: transform 0.4s ease, opacity 0.4s ease;
opacity: 0;
}
#topbar__checked-search:checked ~ .topbar__search-panel .topbar__search-panel-list {
transition-delay: 0.6s;
transform: translateX(-50%) translateY(0%);
opacity: 1;
}
.topbar__search-panel-list:before {
display: block;
content: 'Результаты поиска:';
font-size: 0.8rem;
padding: 3px 10px;
margin: 0 0 5px 0;
color: #acacac;
border-bottom: 1px solid #f2f2f2;
}
.topbar__search-panel-list-item {
display: block;
font-size: 0.8rem;
padding: 3px 10px;
color: #333;
text-decoration: none;
}
.topbar__search-panel-list-item:hover {
background-color: #f4f4f4;
}
/* Leftmenu */
.leftmenu {
display: block;
position: fixed;
top: 42px;
left: 0px;
width: 100%;
height: calc(100vh - 42px);
background-color: rgba(0, 0, 0, 0.6);
opacity: 0;
pointer-events: none;
transition: opacity 0.4s ease;
}
#topbar__checked-leftmenu:checked + .leftmenu {
opacity: 1;
pointer-events: auto;
}
.leftmenu__list {
display: block;
position: absolute;
left: -200px;
width: 200px;
height: 100%;
margin: 0;
padding: 0;
background-color: white;
transition: left 0.4s ease;
}
#topbar__checked-leftmenu:checked + .leftmenu .leftmenu__list {
left: 0;
}
.leftmenu__list-item {
display: block;
padding: 6px 12px;
font-size: 0.8rem;
color: #333;
text-decoration: none;
}
.leftmenu__list-item:hover {
background-color: #f4f4f4;
}
.leftmenu__hidemenu {
display: block;
position: absolute;
left: 200px;
top: 0;
width: calc(100% - 200px);
height: 100%;
}
<div class="topbar">
<label for="topbar__checked-leftmenu" class="topbar__button-open-leftmenu">
<svg viewBox="0 0 32 32">
<path d="M 16 6 C 14.895431 6 14 6.8954305 14 8 C 14 9.1045695 14.895431 10 16 10 C 17.104569 10 18 9.1045695 18 8 C 18 6.8954305 17.104569 6 16 6 z M 16 14 C 14.895431 14 14 14.895431 14 16 C 14 17.104569 14.895431 18 16 18 C 17.104569 18 18 17.104569 18 16 C 18 14.895431 17.104569 14 16 14 z M 16 22 C 14.895431 22 14 22.895431 14 24 C 14 25.104569 14.895431 26 16 26 C 17.104569 26 18 25.104569 18 24 C 18 22.895431 17.104569 22 16 22 z"></path>
</svg>
</label>
<input type="checkbox" id="topbar__checked-search">
<ul class="topbar__memu">
<li><a href="" class="topbar__memu-item">Пункт 1</a>
</li>
<li><a href="" class="topbar__memu-item">Пункт 2</a>
</li>
<li><a href="" class="topbar__memu-item">Пункт 3</a>
</li>
</ul>
<div class="topbar__search">
<input type="text" class="topbar__search-input" placeholder="Найти...">
<button class="topbar__search-button">
<svg version="1" viewBox="0 0 24 24" enable-background="new 0 0 24 24">
<path d="M 9 2 C 5.1 2 2 5.1 2 9 C 2 12.9 5.1 16 9 16 C 10.722428 16 12.28779 15.386196 13.5 14.375 L 14 14.875 L 14 15.6875 L 20.3125 22 L 22 20.3125 L 15.6875 14 L 14.8125 14 L 14.34375 13.53125 C 15.372135 12.314388 16 10.738606 16 9 C 16 5.1 12.9 2 9 2 z M 9 4 C 11.8 4 14 6.2 14 9 C 14 11.8 11.8 14 9 14 C 6.2 14 4 11.8 4 9 C 4 6.2 6.2 4 9 4 z"></path>
</svg>
</button>
</div>
<label for="topbar__checked-search" class="topbar__button-open-search">
<svg id="icon-serach-close" version="1" viewBox="0 0 24 24" enable-background="new 0 0 24 24">
<path d="M 9 2 C 5.1 2 2 5.1 2 9 C 2 12.9 5.1 16 9 16 C 10.722428 16 12.28779 15.386196 13.5 14.375 L 14 14.875 L 14 15.6875 L 20.3125 22 L 22 20.3125 L 15.6875 14 L 14.8125 14 L 14.34375 13.53125 C 15.372135 12.314388 16 10.738606 16 9 C 16 5.1 12.9 2 9 2 z M 9 4 C 11.8 4 14 6.2 14 9 C 14 11.8 11.8 14 9 14 C 6.2 14 4 11.8 4 9 C 4 6.2 6.2 4 9 4 z"></path>
</svg>
<svg id="icon-serach-open" viewBox="0 0 32 32">
<path style="text-indent:0;text-align:start;line-height:normal;text-transform:none;block-progression:tb;-inkscape-font-specification:Bitstream Vera Sans" d="M 8.71875 7.28125 L 7.28125 8.71875 L 14.5625 16 L 7.28125 23.28125 L 8.71875 24.71875 L 16 17.4375 L 23.28125 24.71875 L 24.71875 23.28125 L 17.4375 16 L 24.71875 8.71875 L 23.28125 7.28125 L 16 14.5625 L 8.71875 7.28125 z"
color="#000" overflow="visible" font-family="Bitstream Vera Sans"></path>
</svg>
</label>
<div class="topbar__search-panel">
<div class="topbar__search-panel-list">
<a href="#" class="topbar__search-panel-list-item">Обои для рабочего стола</a>
<a href="#" class="topbar__search-panel-list-item">Новости</a>
<a href="#" class="topbar__search-panel-list-item">StackOverflow</a>
</div>
</div>
</div>
<input type="checkbox" id="topbar__checked-leftmenu">
<div class="leftmenu">
<ul class="leftmenu__list">
<li><a href="#" class="leftmenu__list-item">Пункт 1</a>
</li>
<li><a href="#" class="leftmenu__list-item">Пункт 2</a>
</li>
<li><a href="#" class="leftmenu__list-item">Пункт 3</a>
</li>
</ul>
<label for="topbar__checked-leftmenu" class="leftmenu__hidemenu"></label>
</div>
如果有人知道如何更好地实现这一点,我将很高兴学习:)
В современном web приложении js кода непомерно много, и, моё мнение - если есть возможность писать без js - пишите без js. В том числе и меню.
Когда стоит написать меню js.
Вам надо написать крутое меню которое имеет ряд функционала (нажатие по кнопки как описано выше, задержка при потере курсора мыши, итд).
Но все простые всплывашки если можно обойтись без js надо писать без js. Это не только моё мнение, детально, почему стоит уменьшить объём js кода рассказано в этой статье.
使用
<input type="checkbox" />+<label>主要是一种黑客攻击。在我看来,这种技术在不违反语义的情况下只有一种用途——这些是自定义复选框和单选按钮。在所有其他情况下,在可以制作语义标记的情况下使用这种技术是一种糟糕的形式,因为:可用性受到影响;您的菜单无法使用键盘访问,因此无法使用屏幕阅读器访问。使用特殊软件和设备的盲人或视障人士比您想象的要多得多,在一些西方国家,无障碍是政府的一项要求。
出现附加标记。
代码的模块化受到质疑,因为附加元素是严格互连的。
复选框在表单外部使用并用于其他目的(即不用于将数据数组发送到服务器),这可能会在某些 CMS 中导致问题,这些 CMS 会自动用标签包装表单元素
<form>(首先出现的是介意)。P.S. прятать меню за кнопкой-гамбургером само по себе сомнительное UI-решение.
По мне, такое решение - не совсем оправдано. Оно может иметь место в качестве материала для общего развития, тренировок, но не для релизного проекта. Почему? Потому что это велосипед, хак, который сложно контролировать, в том плане, если вы открыли где-нибудь пункт меню, то как связать это с остальными элементами? Через JS, очевидно. А раз использование этого подразумевает скрипты, то проще и решить это скриптами. Тем более, что для меню это пара строчек.
- Доводы в пользу того, что мол а как же мобильные юзвери - нынешние мобилки помощнее среднего пк пару лет назад, поедать код тоннами они научены, не думаю, что стоит экономить на наносекундах, получая в ответ негибкое, плохо масштабируемое решение.
- Про то что контент не индексируется, это бред, гуголь давно всему научился.
- "Если JS" упадет - это приведет к останову всей страницы. Тоже сомнительно. Не в том плане, что не приведет, а в том, что непоставленная скобка, что в JS, что в CSS приведет к неправильной работе компонентов, отсюда - проблема выедена из яйца. (Да и мы ведь не кидаем код в продакшн, предварительно не протестив его, верно?)
- "JS требует времени на разработку" - css does the same. CSS также нуждается во времени на верстку, разработку, подгонку, разница лишь в том, что JS предоставляет куда более обширный инструментарий, позволяя решать идентичные задачи быстрее.