使用仅 CSS 将汉堡/菜单图标转换为叉号/关闭图标

4

我试图使用纯CSS的方法通过hack来在点击时将“汉堡菜单”图标更改为“关闭”图标。请检查以下代码:

.ham
{
 height: 30px;
 padding: 15px 20px;
}
.dsp-none
{
  display:none;
}
.cross
{
  display:none;
  height: 30px;
 padding: 15px 20px; 
}
.ham-icon:checked .cross
{
 display: block;
}
<input id="click" type="checkbox" name="menu" class="ham-icon dsp-none"/><label for="click" class="ham-lnk"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve" class="ham tr-fl"><rect x="12" y="20" width="40" height="2"/><rect x="12" y="32" width="40" height="2"/><rect x="12" y="44" width="40" height="2"/></svg>
            <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
             width="611.979px" height="611.979px" viewBox="0 0 611.979 611.979" class="cross"><g><path d="M356.781,305.982L601.453,61.311c14.033-14.033,14.033-36.771,0-50.774c-14.004-14.033-36.741-14.033-50.774,0
              L306.007,255.208L61.277,10.536c-14.004-14.033-36.771-14.033-50.774,0c-14.004,14.004-14.004,36.742,0,50.774l244.701,244.672
              L10.503,550.684c-14.004,14.004-14.004,36.771,0,50.774c7.016,7.017,16.216,10.51,25.387,10.51c9.2,0,18.371-3.493,25.387-10.51
              l244.701-244.701l244.671,244.701c7.017,7.017,16.217,10.51,25.388,10.51c9.199,0,18.399-3.493,25.387-10.51
              c14.033-14.033,14.033-36.771,0-50.774L356.781,305.982z"/></g></svg></label>

我无法得到所需的结果。 点击后应该变成十字形图标,无需使用任何动画或过渡效果。有人可以提供一种解决方法吗?

2个回答

4

不确定你为什么要使用SVG,在HTML和CSS的帮助下,可以轻松实现。

在示例CSS中有一条注释:

/* Try different values here: .25rem, .5rem, .2rem, 5rem, 10rem... */
transform-origin: 5rem center;

我个人认为 5rem 的效果看起来不错,但你可能喜欢在 .25rem 2rem 之间选择一些东西。

以下是代码:

const button = document.getElementById('button');
const icon =  document.getElementById('icon');

button.onclick = () => icon.classList.toggle('close');
#button {
  position: relative;
  width: 4rem;
  height: 4rem;
  background: #000;
  cursor: pointer;
}

#button:hover {
  background: rgb(0, 100, 100);
}

#icon {
  position: absolute;
  top: 0;
  right: 1rem;
  left: 1rem;
  width: auto;
  height: 100%;
}

/* MENU ICON */

.lines,
.lines:before,
.lines:after {
  position: absolute;
  display: block;
  width: 100%;
  left: 0;
  background: #FFFFFF;
  transition: 0.3s;
}

.lines {
  height: 3px;
  margin-top: -2px;
  top: 50%;
}

.lines:before,
.lines:after {
  content: '';
  height: 100%;

  /* Try different values here: .25rem, .5rem, .2rem, 5rem, 10rem... */
  transform-origin: 5rem center;
}

.lines:before {
  top: 8px;
}

.lines:after {
  top: -8px;
}

/* CLOSE ICON */

.close {
  transform: scale3d(0.8, 0.8, 0.8);
}

.close .lines {
 background: transparent;
}

.close .lines:before,
.close .lines:after {
  top: 0;
  transform-origin: 50% 50%;
}

.close .lines:before {
  transform: rotate3d(0, 0, 1, 45deg);
}

.close .lines:after {
  transform: rotate3d(0, 0, 1, -45deg);
}
<div id="button">
  <div id="icon">
    <span class="lines"></span>
  </div>
</div>

无论如何,如果您只是需要修复自己的问题,主要问题在于CSS选择器(或HTML结构)错误。例如,您有这个选择器:
.ham-icon:checked .cross

但在您原始的 HTML 中,.cross 不是 .ham-icon 的后代。

我稍微更改了 HTML 的结构、CSS 选择器,并对交叉图标 SVG 进行了一些调整:

.hidden {
  display: none;
}

/* DEFULT: Menu icon shown, close icon hidden */

#menu-icon {
  height: 30px;
  padding: 15px 20px;
}

#close-icon {
  display:none;
  height: 30px;
  padding: 15px 20px; 
}

/* CHECKED: Menu icon hidden, close icon shown */

#checkbox:checked + #menu-icon {
  display: none;
}

#checkbox:checked ~ #close-icon {
  display: block;
}
<label>

  <input id="checkbox" type="checkbox" name="menu" class="hidden"/>

  <svg id="menu-icon"
    version="1.1"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    x="0px"
    y="0px"
    viewBox="0 0 64 64"
    enable-background="new 0 0 64 64"
    xml:space="preserve">
    
    <rect x="12" y="20" width="40" height="2"/>
    <rect x="12" y="32" width="40" height="2"/>
    <rect x="12" y="44" width="40" height="2"/>
  </svg>

  <svg id="close-icon"
    version="1.1"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    x="0px"
    y="0px"
    viewBox="-100 -100 800 800">
  
    <g><path d="M356.781,305.982L601.453,61.311c14.033-14.033,14.033-36.771,0-50.774c-14.004-14.033-36.741-14.033-50.774,0L306.007,255.208L61.277,10.536c-14.004-14.033-36.771-14.033-50.774,0c-14.004,14.004-14.004,36.742,0,50.774l244.701,244.672L10.503,550.684c-14.004,14.004-14.004,36.771,0,50.774c7.016,7.017,16.216,10.51,25.387,10.51c9.2,0,18.371-3.493,25.387-10.51l244.701-244.701l244.671,244.701c7.017,7.017,16.217,10.51,25.388,10.51c9.199,0,18.399-3.493,25.387-10.51
c14.033-14.033,14.033-36.771,0-50.774L356.781,305.982z"/></g>
</svg>
              
</label>


谢谢您的回复。但是,正如我所提到的,我必须仅使用CSS和HTML来实现所需的结果。不允许使用其他脚本。我只有这两个SVG文件,必须使用它们来达到结果。 - AKNair
@AKNair 请检查编辑内容。这可能更接近您要寻找的内容,尽管SVG可能需要进一步调整才能看起来好看。 - Danziger
1
非常感谢!!!这是一个很好的答案。这对我有用......并且我也了解到了我犯的错误。 - AKNair

0

我在W3Schools上看到了一个类似这样的例子。不要改变图标/使用display:none属性,而是使用动画。

这里是W3schools的例子。


谢谢您的回复。实际上,我已经检查了所有这些示例。主要问题是仅使用现有资源解决问题,即仅通过图像完成它。我在我的问题中提到了这一点,即不使用转换或动画。我不确定为什么会给我这种限制,但由于时间紧迫,我想在这里寻求建议。 - AKNair

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接