skip to Main Content

I have the following html:

<div class="menu">
  <div class="menu-item">
    <div class="menu-label">Item 1</div>
    <button class="help">Button</button>
  </div>
  <div class="menu-item">
    <div class="menu-label">Item 2</div>
  </div>
  <div class="menu-item">
    <div class="menu-label">Item 3</div>
  </div>
  <div class="menu-item">
    <div class="menu-label">Item 4</div>
  </div>
</div>

and the corresponding CSS here:

.menu {
  display: table;
}
.menu-item {
  display: table-row;
  vertical-align: middle;
/*   following properties are for debugging purposes */
  background: orange;
  outline: solid blue 2px;
  height: 40px; 
}
.menu-label {
  display: table-cell;
  vertical-align: middle;
  padding: 0 15px;
}
.help {
  display: table-cell;
}

I’m trying to make the button element to show up underneath the Item1’s menu-label but I can’t quite figure that out.
I can’t change much of .menu-item styling because it’s a shared styling in a huge codebase (but i could possibly add another class). How can I achieve this with mainly using .help class?

codepen

2

Answers


  1. The trick is to ensure that the .menu-label and .help elements form a single table-cell. The CSS table anonymous objects construction helps with this. If both elements are not display:table-cell but are the only sibling children of a display:table-row element, then a single anonymous table-cell box will be automatically created to contain both elements. These elements can then create block-level boxes to be laid out vertically within this anonymous table-cell.

    We can target the .help element directly, and to minimise the impact on the styling of .menu-label elements, just target it only when it is immediately followed by a .help element.

    .menu {
      display: table;
    }
    .menu-item {
      display: table-row;
      vertical-align: middle;
    /*   following properties are for debugging purposes */
      background: orange;
      outline: solid blue 2px;
      height: 40px; 
    }
    .menu-label {
      display: table-cell;
      vertical-align: middle;
      padding: 0 15px;
    }
    .help {
      display: table-cell; /* can be removed */
    }
    
    /* Added */
    .menu-label:has(+ .help), .help {
      display: block;
      margin: auto;
    }
    <div class="menu">
      <div class="menu-item">
        <div class="menu-label">Item 1</div>
        <button class="help">Button</button>
      </div>
      <div class="menu-item">
        <div class="menu-label">Item 2</div>
      </div>
      <div class="menu-item">
        <div class="menu-label">Item 3</div>
      </div>
      <div class="menu-item">
        <div class="menu-label">Item 4</div>
      </div>
    </div>
    Login or Signup to reply.
  2. You can check if .menu-item has a button and display it flex with flex direction column

    .menu {
      display: table;
    }
    .menu-item {
      display: table-row;
      vertical-align: middle;
    /*   following properties are for debugging purposes */
      background: orange;
      outline: solid blue 2px;
      height: 40px; 
    }
    
    .menu-item:has(.help){
      display:flex;
      flex-direction:column;
    }
    .menu-label {
      display: table-cell;
      vertical-align: middle;
      padding: 0 15px;
    }
    .help {
      display: table-cell;
    }
    <div class="menu">
      <div class="menu-item">
        <div class="menu-label">Item 1</div>
        <button class="help">Button</button>
      </div>
      <div class="menu-item">
        <div class="menu-label">Item 2</div>
      </div>
      <div class="menu-item">
        <div class="menu-label">Item 3</div>
      </div>
      <div class="menu-item">
        <div class="menu-label">Item 4</div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search