Home > other >  Expand and overlay div on other sibling elements
Expand and overlay div on other sibling elements

Time:06-05

How do I achieve an input field that: on hover, it expands on the other sibling elements (that have the same parent)?
so for example I have:

  .grandparent{
        display: flex;
        justify-content: space-between;
        width:100%;
        height:5rem;
    }
    .other{
        background-color: #7fffd477;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 5rem;
    }
    .parent{
        background-color: #fff67f;
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        padding: 12px;
    }
    .child-1{
        background-color: #ff7f7f;
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 100%;
        width: 60%;
    }
    .child-2{
        background-color: #77ab55;
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;
        width: 5rem;
    }
    .child-2:hover{
        width: 100%;
        transition: all 0.5s;
    }
<div >
    <div > 
        <div >
            <div >1.1</div>
            <div >1.2</div>
        </div>
        <div >
            2.0
        </div>
    </div>
    <div >
        other
    </div>
</div>

I want the "child-2" div to expand for the whole "parent" (yellow) div and overlay other sibling elements when I hover on it.
Anyone can help me achieve this through CSS?

CodePudding user response:

For the rightmost element in parent to expand over its siblings without affecting them it needs to be positioned absolute and 'anchored' at the right hand side of parent so that the width can grow towards the left.

For the simple HTML structure given in the question where there is only one sibling of the expandable element it would be possible to achieve the required layout without changing the HTML but removing the flex from parent.

However, the question mentions 'siblings' and there is therefore a requirement to layout parent with equal spacing between all its children.

This snippet allows for this by adding a div within child-2. child-2 remains with its given width and therefore takes part in the flex calculations for parent.

However, the inner div is the one which will be positioned absolute and expand to the left.

To get positioning and dimensions correct the 5rem width of child-2 and 12px padding of parent are made CSS variables and CSS calc is used. This should make it easier to change these settings if required.

To show the increased generality, this snippet has 2 siblings (each for the demo set to child-1 settings with width 30% instead of 60%).

.grandparent {
  display: flex;
  justify-content: space-between;
  width: 100%;
  height: 5rem;
}

.other {
  background-color: #7fffd477;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 5rem;
}

.parent {
  --pad: 12px;
  /* set to the width of the parent's padding */
  background-color: #fff67f;
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: var(--pad);
  position: relative;
}

.child-1 {
  background-color: #ff7f7f;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
  width: 60%;
  width: 30%;
}

.child-2 {
  --w: 5rem;
  /* the width of the rightmost element in parent */
  height: 100%;
  width: var(--w);
  right: 0;
}

.child-2>* {
  position: absolute;
  background-color: #77ab55;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--w);
  height: calc(100% - (2 * var(--pad)));
  transition: all 0.5s;
  right: var(--pad);
}

.child-2:hover>* {
  width: calc(100% - (2 * var(--pad)));
}
<div >
  <div >
    <div >
      <div >1.1</div>
      <div >1.2</div>
    </div>
    <div >
      <div >1.1</div>
      <div >1.2</div>
    </div>
    <div >
      <div>
        2.0
      </div>
    </div>
  </div>
  <div >
    other
  </div>
</div>

CodePudding user response:

I have adjusted the HTML structure: .child-1 is now after .child-2. The CSS for .parent now includes flex-direction: row-reverse.

It is now possible to easily affect .child-1 via CSS (display: none).

.grandparent {
  display: flex;
  justify-content: space-between;
  width: 100%;
  height: 5rem;
}

.other {
  background-color: #7fffd477;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 5rem;
}

.parent {
  background-color: #fff67f;
  display: flex;
  justify-content: space-between;
  flex-direction: row-reverse; /* Added */
  align-items: center;
  width: 100%;
  padding: 12px;
}

.child-1 {
  background-color: #ff7f7f;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
  width: 60%;
}

.child-2 {
  background-color: #77ab55;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 5rem;
}

.child-2:hover {
  width: 100%;
  transition: all 0.5s;
  z-index: 10;
}


/* Added */

.child-2:hover .child-1 {
  display: none;
}
<div >
  <div >
    <div >
      2.0
    </div>
    <div >
      <div >1.1</div>
      <div >1.2</div>
    </div>
  </div>
  <div >
    other
  </div>
</div>

  •  Tags:  
  • css
  • Related