Saud Alghamdi
Saud Alghamdi

Reputation: 199

How can I make a div grow downwards only?

I have a parent div that has a child div centered inside it. What I want is that when I click on the child div it grows downwards only, not both upwards and downwards.

The two divs before I click:

enter image description here

The result I get when I click on div 2:

enter image description here

The result I'm looking for when I click on div 2:

enter image description here

let div2 = document.querySelector("#div2");
div2.addEventListener("click", e => {
  div2.style.height = "300px";
})
#div1 {
  height: 200px;
  width: 200px;
  outline: red solid medium;
  display: flex;
  justify-content: center;
  align-items: center;
}

#div2 {
  height: 100px;
  width: 100px;
  outline: blue solid medium;
}
<div id="div1">
  <div id="div2"></div>
</div>

Upvotes: 0

Views: 2353

Answers (6)

Avinash Chandra
Avinash Chandra

Reputation: 126

let div2 = document.querySelector("#div2");
// Keep the initial height of div2
const initialHeight = (div2.clientHeight);
div2.addEventListener("click", e => {
  // Add top and transform property
  const transformVal = initialHeight / 2;
  div2.style.transform = `translateY(-${transformVal}px)`;
  div2.style.top = '50%';
  div2.style.height = "300px";
})
#div1 {
  height: 200px;
  width: 200px;
  outline: red solid medium;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

#div2 {
  height: 100px;
  width: 100px;
  outline: blue solid medium;
  position: absolute;
}
<div id="div1">
  <div id="div2"></div>
</div>

Upvotes: 1

A Haworth
A Haworth

Reputation: 36574

The problem with keeping flex is that it adjusts to center things when you don't want to, you want the top of the blue square to stay at the same place.

This snippet removes flex and instead centers the blue element by moving it 50% from top and side and then back by half its height/width using a transform.

It also sets it positioned absolute so it doesn't affect the size of its parent when it expands.

A CSS variable is used to specify the initial height. This can then set the initial top position and that remains.

let div2 = document.querySelector("#div2");
div2.addEventListener("click", e => {
  div2.style.height = "300px";
})
#div1 {
  height: 200px;
  width: 200px;
  outline: red solid medium;
  position: relative;
  --h: 100px;
  --w: 100px;
}

#div2 {
  height: var(--h);
  width: var(--w);
  outline: blue solid medium;
  top: calc((100% - var(--h)) / 2);
  left: calc((100% - var(--w)) / 2);
  position: absolute;
}
<div id="div1">
  <div id="div2"></div>
</div>

Upvotes: 0

Stefan Avramovic
Stefan Avramovic

Reputation: 1353

You can do it by setting position absolute

let div2 = document.querySelector("#div2");
div2.addEventListener("click", e => {
  div2.style.height = "300px";
})
#div1 {
position:relative;
  height: 200px;
  width: 200px;
  outline: red solid medium;
  display: flex;
  justify-content: center;
  align-items: center;
}

#div2 {
    position:absolute;
  top:50px;
  height: 100px;
  width: 100px;
  outline: blue solid medium;
}
<div id="div1">
  <div id="div2"></div>
</div>

Upvotes: 2

Avinash
Avinash

Reputation: 46

You should try applying transform-origin property set to "center top" on the child and on the container too if needed. Check out https://www.w3schools.com/cssref/css3_pr_transform-origin.asp for more help!

Upvotes: 0

Darren
Darren

Reputation: 1

you could change the height of div1 to 100% so that it grows with div2 and use padding on div1 to maintain the area around div2.

#div1{
  height: 100%;
  width: 160px;
  padding: 40px;
  outline: red solid medium;
  display: flex;
  justify-content: center;
  align-items: center;
}

Upvotes: 0

franklylately
franklylately

Reputation: 1183

A bit hacky, but using an extra element this works. Definitely not responsive for various sizes though.

let div2 = document.querySelector("#div2");
div2.addEventListener("click", e => {
  div2.style.height = "300px";
})
#div1 {
  height: 200px;
  width: 200px;
  outline: red solid medium;
  display: flex;
  justify-content: center;
  align-items: center;
}
#divc {
  height: 100px;
  width: 100px;
}
#div2 {
  height: 100px;
  width: 100px;
  outline: blue solid medium;
}
<div id="div1">
  <div id="divc"><div id="div2"></div></div>
</div>

Upvotes: 1

Related Questions