darkchampionz
darkchampionz

Reputation: 1224

HTML extend height of div

div.div1 {
  position: relative;
  border: 1px solid black;
  height: 100px;
  width: 100px;
  padding: 10px;
}

div.div2 {
  background-color: gray;
  border: 1px solid black;
  padding: 10px;
}

div.div3 {
  position: absolute;
  border: 1px solid red;
  height: 20px;
  width: 20px;
  bottom: 10px;
  left: 10px;
}
<div class="div1">
  <div class="div2">Test 123</div>
  <div class="div3">A</div>
</div>

I use the above code to display a big div with two divs in it. For the first one I use position: absolute to place it on bottom left of the div.

How can I extend the height of the second gray one so that it's 5 pixels above the first, but without having to measure its exact height in pixel (like the pic below)? I can set height: 50px; for example but is there another way?

enter image description here

Upvotes: 2

Views: 1993

Answers (4)

nem035
nem035

Reputation: 35481

EDIT: I suggest that, if you can focus on the modern browser features, going the flexbox way as shown by Pete is definitely a cleaner approach than the ones I've shown bellow. That being said, here are the alternatives:

You can use calc to dynamically determine the height of div2:

div.div1 {
  position: relative;
  border: 1px solid black;
  height: 100px;
  width: 100px;
  padding: 10px;
}

div.div2 {
  background-color: gray;
  border: 1px solid black;
  padding: 10px;
  height: calc(
    100%
    - 20px /* div1: padding top and bottom */
    - 2px  /* div1: border top and bottom */
    - 20px /* div3: height */
    - 2px  /* div3: border top and bottom*/
    - 5px  /* desired separation*/
  );
}

div.div3 {
  position: absolute;
  border: 1px solid red;
  height: 20px;
  width: 20px;
  bottom: 10px;
  left: 10px;
}
<div class="div1">
  <div class="div2">Test 123</div>
  <div class="div3">A</div>
</div>

You can avoid including padding and border width in your calculations if you set the box-sizing for your divs to border-box (You might want to set this for all elements):

div {
  box-sizing: border-box;
}

div.div1 {
  position: relative;
  border: 1px solid black;
  height: 100px;
  width: 100px;
  padding: 10px;
}

div.div2 {
  background-color: gray;
  border: 1px solid black;
  padding: 10px;
  height: calc(
    100%
    - 20px /* div3: height */
    - 5px  /* desired separation */
  );
}

div.div3 {
  position: absolute;
  border: 1px solid red;
  height: 20px;
  width: 20px;
  bottom: 10px;
  left: 10px;
}
<div class="div1">
  <div class="div2">Test 123</div>
  <div class="div3">A</div>
</div>

Upvotes: 3

bashleigh
bashleigh

Reputation: 9314

There's this rather new, hip CSS property called 'flex' which you're now going to love because it does it exactly that without the need of positioning absolute etc. I did something similar yesterday where I had a vertical nav bar and I wanted one menu at the top and one at the bottom. In a responsive environment; using your approach of positioning absolute it would've resulted in a nasty mess of working out heights to stop the content from overlapping. Flex prevented this! Yeyyyyy

https://css-tricks.com/snippets/css/a-guide-to-flexbox/

In your example you want to do something like this:

.div1 {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: space-around;
}
.div2 {
    align-self: flex-start;
    flex-grow:1;
    width:100%;
}
.div3 {
    align-self: flex-end;
    width:100%;
}

Now your div 3 will always be at the bottom. Although now .div3 will extend the entire width so within the div insert your content and BOOM done.

Upvotes: 1

Pete
Pete

Reputation: 58412

I would use a flexbox approach rather than absolute positioning (comments in css below)

div.div1 {

  display: flex;
  flex-direction:column;
  /* add the above styles*/
  
  border: 1px solid black;
  min-height: 100px;         /*I would also change this to min-height otherwise it may cause issues if your text goes to 2 lines*/
  width: 100px;
  padding: 10px;
}

div.div2 {
  flex-grow:1;        /* make div grow to fill the space */
  margin-bottom:5px;  /* minus the amount of margin you wanted */
  
  background-color: gray;
  border: 1px solid black;
  padding: 10px;
}

div.div3 { 
  /* remove absolute positioning */
  border: 1px solid red;
  height: 20px;
  width: 20px;
}
<div class="div1">
  <div class="div2">Test 123</div>
  <div class="div3">A</div>
</div>

Upvotes: 4

Johannes
Johannes

Reputation: 67738

You can use calc on the heightsetting as in my snippet below. That setting is 100% minus (20 + 10 + 2) for the height, border and bottom of the lower DIV minus (5 + 2) for the distance and the border of the first DIV minus 10px for the padding of the parent, summing up to 49px .

div.div1 {
  position: relative;
  border: 1px solid black;
  height: 100px;
  width: 100px;
  padding: 10px;
}

div.div2 {
  background-color: gray;
  border: 1px solid black;
  padding: 10px;
  height: calc(100% - 49px);
}

div.div3 {
  position: absolute;
  border: 1px solid red;
  height: 20px;
  width: 20px;
  bottom: 10px;
  left: 10px;
}
<div class="div1">
  <div class="div2">Test 123</div>
  <div class="div3">A</div>
</div>

Upvotes: 0

Related Questions