我正在为大型菜单做一些原型设计,其中菜单项应该"智能"显示,根据菜单项的数量,它们可以读为行或列.

菜单项会有自己的子元素,所以它们真的很像:

 mega menu left text | menu item 1   menu item 2   menu item 3
                     | sublink1 A    sublink2 A    sublink3 A
                     | sublink1 B    sublink2 B
                     | sublink1 C

为了简单起见,我不包括下面的内容.

显示取决于菜单项的数量. 例如,如果有1-3个菜单项,它读起来就像一行:

mega menu left text | menu item 1   menu item 2   menu item 3

如果菜单项超过3个,它读起来就像列一样,自上而下,然后向右,但它仍然需要"智能",因为菜单项4在其自己的列中,而不是在菜单项3下面(它总是需要在右侧维护3列):

mega menu left text | menu item 1   menu item 3   menu item 4
                    | menu item 2

5个菜单项:

mega menu left text | menu item 1   menu item 3   menu item 5
                    | menu item 2   menu item 4

6个菜单项:

mega menu left text | menu item 1   menu item 3   menu item 5
                    | menu item 2   menu item 4   menu item 6

7个菜单项:

mega menu left text | menu item 1   menu item 4   menu item 7
                    | menu item 2   menu item 5
                    | menu item 3   menu item 6

8个菜单项:

mega menu left text | menu item 1   menu item 4   menu item 7
                    | menu item 2   menu item 5   menu item 8
                    | menu item 3   menu item 6

9个菜单项:

mega menu left text | menu item 1   menu item 4   menu item 7
                    | menu item 2   menu item 5   menu item 8
                    | menu item 3   menu item 6   menu item 9

10个菜单项:

mega menu left text | menu item 1   menu item 5   menu item 9
                    | menu item 2   menu item 6   menu item 10
                    | menu item 3   menu item 7   
                    | menu item 4   menu item 8

在css中有什么方法可以优雅地做到这一点吗? 我以为css列可以做到这一点,但它不太起作用.这是一个小提琴/演示,如果您移动左侧的滑动块,您会看到它掉落的位置:

https://jsfiddle.net/vsdpjwn9/
This uses break-inside: avoid-column; on the <li>

https://jsfiddle.net/3x8scuwt/
This uses display: inline-block; on the <li>

我还try 了带有Flexbox的单独原型,但它似乎倒下得更快,所以我放弃了它.看起来css网格也是一样的. 问题是,这些菜单项将是动态的,将有不同数量的菜单项,每个菜单项都有不同数量的子链接. 可能不会超过3行,但我不想依赖于此.

任何css解决方案,或者这是否需要JavaScript根据单个菜单项的数量设置自定义布局?

它也需要响应,但菜单项基本上变成了相互堆叠的手风琴.

这是小提琴的一个代码:

HTML:

<div id="container">
  <div class="left">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    <div style="margin-top:1rem;">
      <input id="slider" type="range" min="1" max="8" value="8">
      <p id="slider-output" style="margin-top:0;"></p>
    </div>

  </div>

  <div class="right">
    <ul>
      <li class="1">
          <h4>1 Secondary Content</h4>
          <a href="#a1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#a2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#a3">Lorem ipsum dolora</a><br>
          <a href="#a4">Lorem ipsum dolora</a><br>
          <a href="#a5">Lorem ipsum dolora</a>
      </li>

      <li class="2">
          <h4>2 Secondary Content</h4>
          <a href="#b1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#b2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#b3">Lorem ipsum dolora</a><br>
          <a href="#b4">Lorem ipsum dolora</a><br>
          <a href="#b5">Lorem ipsum dolora</a><br>
          <a href="#b6">Lorem ipsum dolora</a>
      </li>

      <li class="3">
          <h4>3 Secondary Content</h4>
          <a href="#c1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#c2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#c3">Lorem ipsum dolora</a><br>
          <a href="#c4">Lorem ipsum dolora</a>
      </li>

      <li class="4">
          <h4>4 Secondary Content</h4>
          <a href="#d1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#d4">Lorem ipsum dolora</a>
      </li>

      <li class="5">
          <h4>5 Secondary Content</h4>
          <a href="#e1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#e2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#e3">Lorem ipsum dolora</a><br>
          <a href="#e4">Lorem ipsum dolora</a><br>
          <a href="#e5">Lorem ipsum dolora</a>
      </li>

      <li class="6">
          <h4>6 Secondary Content</h4>
          <a href="#f1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#f2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#f3">Lorem ipsum dolora</a><br>
          <a href="#f4">Lorem ipsum dolora</a><br>
          <a href="#f5">Lorem ipsum dolora</a><br>
          <a href="#f6">Lorem ipsum dolora</a>
      </li>

      <li class="7">
          <h4>7 Secondary Content</h4>
          <a href="#g1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#g2">Lorem ipsum dolora</a>
      </li>
      
      <li class="8">
          <h4>8 Secondary Content</h4>
          <a href="#h1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#h2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
          <a href="#h3">Lorem ipsum dolora</a><br>
          <a href="#h4">Lorem ipsum dolora</a><br>
      </li>
    </ul>
  </div>
</div>

Css:以下内容:

    #container {
    width: 900px;
    min-height: 400px;
    display: flex;
    gap: 40px;
    padding: 1em;
    border: 1px solid #ccc;
}
.left {
    width: 25%;
    padding-right: 40px;
    border-right: 1px solid #ccc;
}
.right {
    width: 100%;
    margin-left: auto;
}
/*
ul {
  border: 1px solid red;
  height: 400px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
}
*/

ul {
  list-style: none;
  columns: 3;
  column-gap: 25px;
  margin: 0;
  padding: 0;
  width: 98%;
  border: 1px solid blue;
}

li {
  border: 1px solid red;
  list-style-type: none;
  margin: 0 0 15px 0;
  
  /*display: inline-block;*/
  break-inside: avoid-column;
  
}
li:first-child {
  margin-top: 0;
}

li a {
  display: inline-block;
  margin: .125rem 0;
}

h4 {
  margin: 0;
}

[hidden] {
  display: none !important;
}

JS:

    const slider = document.getElementById('slider');
const output = document.getElementById('slider-output');
const LIs = document.querySelectorAll('li');

output.innerHTML = slider.value;

slider.oninput = function() {
  output.innerHTML = this.value;

  LIs.forEach(li => {
    if (+li.classList.value > slider.value) {
      li.setAttribute('hidden', '');
    } else {
      li.removeAttribute('hidden');
    }
  });
}

推荐答案

据我所知,如果没有使用nth-child Select 器的一些时髦方法,纯CSS是不可能的,而nth-child Select 器仍然需要有限数量的项目.(另外,正如你所知,班级名称只有数字are not valid.)

然而,这可以通过CSS网格和一点改变行数的JavaScript来轻松完成.

唯一增加的复杂性是当只有4个项目时,默认情况下最后li个将放置在第二列,因此需要将其指定为位于第三列.这可以使用CSS或JavaScript来完成.

ul {
    display: grid;
    --row-number: 3;
    grid-template-rows: repeat(var(--row-number), 1fr);
    grid-template-columns: repeat(3, 1fr);
    grid-auto-flow: column;
}

/*Use CSS for the special case*/
li:nth-child(4 of :not([hidden])):nth-last-child(-n + 1 of :not([hidden])) {
    grid-column: 3;
}
function updateColumnNumber() {
    ul.style.setProperty('--row-number', Math.ceil(slider.value / 3));
}

const slider = document.getElementById('slider');
const output = document.getElementById('slider-output');
const LIs = document.querySelectorAll('li');
const ul = document.getElementById('right-grid');
output.innerHTML = slider.value;

slider.oninput = function () {
    output.innerHTML = this.value;

    LIs.forEach(li => {
        if (+li.classList.value > slider.value) {
            li.setAttribute('hidden', '');
        } else {
            li.removeAttribute('hidden');
        }
    });
    updateColumnNumber();
}

let li4 = null;
function updateColumnNumber() {
    /*Or use JS for the special case*/
    /*li4?.style.removeProperty('grid-column');
    if (slider.value == 4) {
        li4 = ul.querySelectorAll("li:not([hidden])")[3];
        li4?.style.setProperty('grid-column', 3)
    }*/

    ul.style.setProperty('--row-number', Math.ceil(slider.value / 3));
}

updateColumnNumber();
#container {
  width: 900px;
  min-height: 400px;
  display: flex;
  gap: 40px;
  padding: 1em;
  border: 1px solid #ccc;
}

.left {
  width: 25%;
  padding-right: 40px;
  border-right: 1px solid #ccc;
}

.right {
  width: 100%;
  margin-left: auto;
}

ul {
  list-style: none;
  display: grid;
  --row-number: 3;
  grid-template-rows: repeat(var(--row-number), 1fr);
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-flow: column;
  gap: 25px;
  margin: 0;
  padding: 0;
  width: 98%;
  border: 1px solid blue;
}

li:nth-child(4 of :not([hidden])):nth-last-child(-n + 1 of :not([hidden])) {
    grid-column: 3;
}

li {
  box-sizing: border-box;
  border: 1px solid red;
  list-style-type: none;
  margin: 0 0 15px 0;
  /*display: inline-block;*/
  break-inside: avoid-column;
}

li:first-child {
  margin-top: 0;
}

li a {
  display: inline-block;
  margin: .125rem 0;
}

h4 {
  margin: 0;
}

[hidden] {
  display: none !important;
}
<div id="container">
  <div class="left">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    <div style="margin-top:1rem;">
      <input id="slider" type="range" min="1" max="10" value="10">
      <p id="slider-output" style="margin-top:0;"></p>
    </div>

  </div>

  <div class="right">
    <ul id="right-grid">
      <li class="1">
        <h4>1 Secondary Content</h4>
        <a href="#a1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#a2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#a3">Lorem ipsum dolora</a><br>
        <a href="#a4">Lorem ipsum dolora</a><br>
        <a href="#a5">Lorem ipsum dolora</a>
      </li>

      <li class="2">
        <h4>2 Secondary Content</h4>
        <a href="#b1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#b2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#b3">Lorem ipsum dolora</a><br>
        <a href="#b4">Lorem ipsum dolora</a><br>
        <a href="#b5">Lorem ipsum dolora</a><br>
        <a href="#b6">Lorem ipsum dolora</a>
      </li>

      <li class="3">
        <h4>3 Secondary Content</h4>
        <a href="#c1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#c2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#c3">Lorem ipsum dolora</a><br>
        <a href="#c4">Lorem ipsum dolora</a>
      </li>

      <li class="4">
        <h4>4 Secondary Content</h4>
        <a href="#d1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#d4">Lorem ipsum dolora</a>
      </li>

      <li class="5">
        <h4>5 Secondary Content</h4>
        <a href="#e1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#e2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#e3">Lorem ipsum dolora</a><br>
        <a href="#e4">Lorem ipsum dolora</a><br>
        <a href="#e5">Lorem ipsum dolora</a>
      </li>

      <li class="6">
        <h4>6 Secondary Content</h4>
        <a href="#f1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#f2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#f3">Lorem ipsum dolora</a><br>
        <a href="#f4">Lorem ipsum dolora</a><br>
        <a href="#f5">Lorem ipsum dolora</a><br>
        <a href="#f6">Lorem ipsum dolora</a>
      </li>

      <li class="7">
        <h4>7 Secondary Content</h4>
        <a href="#g1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#g2">Lorem ipsum dolora</a>
      </li>

      <li class="8">
        <h4>8 Secondary Content</h4>
        <a href="#h1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#h2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#h3">Lorem ipsum dolora</a><br>
        <a href="#h4">Lorem ipsum dolora</a><br>
      </li>

      <li class="9">
        <h4>9 Secondary Content</h4>
        <a href="#h1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#h2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#h3">Lorem ipsum dolora</a><br>
        <a href="#h4">Lorem ipsum dolora</a><br>
      </li>

      <li class="10">
        <h4>10 Secondary Content</h4>
        <a href="#h1">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#h2">Lorem ipsum dalora itmet vistafa alotma pastruma</a><br>
        <a href="#h3">Lorem ipsum dolora</a><br>
        <a href="#h4">Lorem ipsum dolora</a><br>
      </li>
    </ul>
  </div>
</div>

Css相关问答推荐

如何防止背景重复图像被截断

搜索栏突出显示角形HTML中的Mat-Form-field输入框的焦点

如何将Ant设计日期 Select 器的图标设置在输入 Select 器之前而不是之后

如何在一个父类里面 Select 两个不同的类?

基于高度的容器查询不起作用

我怎样才能准确地获得虚构文本内容宽度的边距?

循环一个 sass/scss 变量以生成 css 变量

预期失败时使用toHaveStyle进行测试

更改组件中 css 的值

使用 Flex Box Tailwind CSS 的元素不相等

Rails 7引擎如何使未编译的样式表可用于托管应用程序?

我怎样才能让这个边框出现在按钮元素的上方?

固定元素在 Chrome 中消失

加载资源失败:服务器响应状态为 404(未找到)

范围内的 CSS 未在组件中应用

如何在浏览器的右下角放置一个div?

弹性框中的边距折叠

多个和/或嵌套的 bootstrap 容器?

如何在 React 应用程序中使用 CSS 模块应用全局样式?

将 webkit 滚动条样式应用于指定元素