Is there a way to dynamically change padding of child element to fill parent element?

Viewed 582

I need the child element to behave on hover as that the red border (of child element) should be on the same line as the blue one (parent element) from top, left, bottom and right side. Can I do that by padding? There are several boxes with the same structure but different width and height, and with the different length of text (some of them are on two or three lines).

If it is impossible to do it via padding, how can I achieve the same effect via another method?

The code is here

* {
  box-sizing: border-box;
}

.out {
  display: -webkit-box;
  display: flex;
  -webkit-box-pack: center;
          justify-content: center;
  width: 200px;
  height: 200px;
  margin: 2rem auto;
  border: 1px solid blue;
}
.out .in {
  font-size: 20px;
  line-height: 1;
  display: inline-block;
  text-align: center;
  border: 1px solid red;
  padding: 20px;
  margin: auto;
  transition: padding .7s;
}
.out:hover .in {
  padding-top: 90px;
  padding-bottom: 90px;
  padding-left: 40px;
  padding-right: 40px;
  background: rgba(0,0,0,.2);
}
<div class="out">
  <p class="in">
    Hello Friend
  </p>
</div>

<div class="out">
  <p class="in">
    Hello Friend
  </p>
</div>

<div class="out">
  <p class="in">
    Hello Friend this is a new text
  </p>
</div>

<div class="out">
  <p class="in">
    Hello
  </p>
</div>

Thanks

3 Answers

If you can add an extra wrapper you can achieve this by nesting flexbox container and by animating flex-grow

* {
  box-sizing: border-box;
}

.out {
  display: flex;
  flex-direction: column;
  width: 200px;
  height: 200px;
  margin: 2rem auto;
  justify-content: center;
  border: 1px solid blue;
}

.out > div {
  display: flex;
  justify-content: center;
}

.out .in {
  display: flex;
  font-size: 20px;
  justify-content: center;
  align-items: center;
  text-align: center;
  border: 1px solid red;
  padding: 20px;
  margin: 0;
}

.out * {
  flex-grow: 0;
  transition: flex-grow .5s;
}

.out:hover * {
  flex-grow: 1;
}

.out:hover .in {
  background: rgba(0, 0, 0, .2);
}
<div class="out">
  <div>
    <p class="in">
      Hello Friend
    </p>
  </div>
</div>

<div class="out" style="width:auto">
  <div>
    <p class="in">
      Hello Friend
    </p>
  </div>
</div>

<div class="out" style="height:auto;min-height:300px;">
  <div>
    <p class="in">
      Hello Friend this is a new text
    </p>
  </div>
</div>

<div class="out">
  <div>
    <p class="in">
      Hello
    </p>
  </div>
</div>

If you need only background animation and - you can use something like this. Here the element ::after scales separately from with text.

* {
  box-sizing: border-box;
}

.out {
  display: -webkit-box;
  display: inline-flex;
  vertical-align: top;
  -webkit-box-pack: center;
          justify-content: center;
  width: 200px;
  height: 200px;
  margin: 2rem auto;
  border: 1px solid blue;
  overflow: hidden; /* to hide parent exapnded background */
}
.out .in {
  font-size: 20px;
  line-height: 1;
  display: inline-block;
  text-align: center;
  padding: 20px;
  margin: auto;  
  position: relative;
}
.out .in::after {
  content: '';
  background: rgba(0,0,0,.2);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%; 
  transform: scale(1);
  transition: all .7s;  
}
.out:hover .in::after {
  transform: scale(5);
}
<div class="out">
  <p class="in">
    Hello Friend
  </p>
</div>

<div class="out">
  <p class="in">
    Hello Friend this is a new text
  </p>
</div>

<div class="out">
  <p class="in">
    Hello
  </p>
</div>

You can add height and width of child 100% on parent hover.

* {
  box-sizing: border-box;
}

.out {
  display: -webkit-box;
  display: flex;
  -webkit-box-pack: center;
          justify-content: center;
  width: 200px;
  height: 200px;
  margin: 2rem auto;
  border: 1px solid blue;
}
.out .in {
  font-size: 20px;
  line-height: 1;
  display: inline-block;
  text-align: center;
  border: 1px solid red;
  padding: 20px;
  margin: auto;
  transition: padding .7s;
}
.out:hover .in {
  padding-top: 90px;
  padding-bottom: 90px;
  padding-left: 40px;
  padding-right: 40px;
  background: rgba(0,0,0,.2);
  width: 100%;
  height: 100%;
}
<div class="out">
  <p class="in">
    Hello Friend
  </p>
</div>

<div class="out">
  <p class="in">
    Hello Friend
  </p>
</div>

<div class="out">
  <p class="in">
    Hello Friend this is a new text
  </p>
</div>

<div class="out">
  <p class="in">
    Hello
  </p>
</div>

Related