You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决点击展示子分类时父分类导航上移,维持水平布局问题

解决方案

问题根源

当前父分类列表.switcher使用align-items: center布局,当子分类列表显示时,包含子分类的父<li>高度增加,flex布局会重新对齐所有列表项,导致整个父分类区块向上偏移。同时子分类默认流式布局会撑开父<li>高度,干扰同行元素位置。

修改步骤

1. 调整父分类列表的Flex对齐规则

修改.switcher的CSS,将垂直对齐方式改为顶部对齐,确保所有父分类始终从顶部对齐,不受子元素高度变化影响:

.switcher {
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start; /* 替换原有的center */
  list-style: none;
  width: fit-content;
  padding: 10px 10px;
}

2. 让子分类绝对定位在父分类下方

给包含子分类的父<li>设置相对定位,子分类列表设置绝对定位,避免子分类撑开父元素高度:

.switcher li {
  border-radius: 4px;
  padding: 10px 10px;
  background-color: white;
  cursor: pointer;
  transition: 0.2s linear;
  font-size: 12px;
  user-select: none;
  margin: 5px;
  position: relative; /* 添加相对定位 */
  display: inline-block;
  cursor: pointer;
}

/* 子分类列表样式 */
.switcher li .switcher {
  position: absolute;
  top: 100%; /* 紧贴父元素底部 */
  left: 0;
  margin-top: 5px;
  flex-direction: column; /* 子分类垂直排列 */
  background-color: white;
  padding: 5px 0;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1); /* 可选:增强层级感 */
}

/* 子分类列表项样式优化 */
.switcher li .switcher li {
  margin: 2px 10px;
  padding: 8px 12px;
  border-radius: 4px;
}

.switcher li .switcher li:hover {
  background-color: #f5f5f5; /* 可选:hover高亮 */
}

3. 修复事件冲突问题

原代码中父分类点击会触发图片筛选,现在调整为:点击父分类仅展开/收起子分类,点击子分类才执行筛选逻辑:

const imgs = Array.from(document.images);
// 区分顶级父分类和子分类
const parentCategories = document.querySelectorAll('.switcher > li:not(.switcher li li)');
const subCategories = document.querySelectorAll('.switcher li li');

// 子分类绑定筛选事件
subCategories.forEach(li => {
  li.addEventListener('click', removeActive);
  li.addEventListener('click', filter);
});

// 父分类绑定展开/收起事件
parentCategories.forEach(li => {
  const subMenu = li.querySelector('.switcher');
  if (subMenu) {
    li.addEventListener('click', function(e) {
      e.stopPropagation();
      // 关闭其他父分类的子菜单
      document.querySelectorAll('.switcher li .switcher').forEach(menu => {
        if (menu !== subMenu) menu.style.display = 'none';
      });
      // 切换当前子菜单显示状态
      subMenu.style.display = subMenu.style.display === 'block' ? 'none' : 'block';
      // 激活当前父分类(可选)
      if (this.dataset.cat !== '.all') {
        removeActive.call(this);
      }
    });
  } else {
    // All分类点击逻辑
    li.addEventListener('click', function(e) {
      e.stopPropagation();
      removeActive.call(this);
      filter.call(this);
      // 关闭所有子菜单
      document.querySelectorAll('.switcher li .switcher').forEach(menu => {
        menu.style.display = 'none';
      });
    });
  }
});

// 保留原有核心函数
function removeActive() {
  document.querySelectorAll('.switcher li').forEach(li => {
    li.classList.remove('active');
  });
  this.classList.add('active');
}

function filter() {
  imgs.forEach(img => {
    if (!img.classList.contains('logo')) {
      img.style.display = 'none';
    }
  });
  document.querySelectorAll(this.dataset.cat).forEach(el => {
    el.style.display = 'block';
  });
}

4. 优化HTML结构(可选)

给子分类列表单独添加类名sub-switcher,避免和父列表样式冲突:

<li data-cat=".urb" id="show">
  Urbanism
  <ul class="sub-switcher" id="content" style="display: none">
    <li data-cat=".cityscale">City Scale</li>
    <li data-cat=".residential">Residential</li>
    <li data-cat=".entertainment">Entertainment</li>
  </ul>
</li>

对应CSS修改为:

.switcher li .sub-switcher {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 5px;
  flex-direction: column;
  background-color: white;
  padding: 5px 0;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  list-style: none;
}

.switcher li .sub-switcher li {
  margin: 2px 10px;
  padding: 8px 12px;
  border-radius: 4px;
}

最终效果

  • 所有父分类始终保持同一水平线,不会因子分类展开偏移
  • 子分类显示在对应父分类正下方,不干扰其他父分类位置
  • 父分类仅负责展开/收起子菜单,子分类执行图片筛选逻辑

内容的提问来源于stack exchange,提问作者Farah Anany

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:59:49