3

To continue my question Vertically center align divs with unknown height

I have such code:

https://jsfiddle.net/yyjde1gb/

#test {
  background: yellow;
  display: flex;
  align-items: center;
}
#block1 {
  background-color: grey;
}
#block2 {
  background-color: green;
  margin-left: auto;
}
<div id="test">
  <div id="block1">
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
  </div>
  <div id="block2">
    sample
  </div>
</div>

It uses flex.

The question is: is it possible to get the same result without flex (and without JavaScript surely)?

IMPORTANT: It is forbidden to hard-code any heights or widths in pixels, ems, percent, ... (which makes the difficulty for this question). All the heights and widths are implicitely formed only by the contained text. That's an adaptive footer prototype.

First thing that comes to mind is to use floats - but it is impossible because of the vertical-align: middle of the "block2" div (floats are vertical-align: top only) - see details in Vertically center align divs with unknown height .

EDIT1: The "test" div is supposed to span to all the width of the page since it is a footer.

EDIT2: The proposed solution should support the oldest browsers possible.

UPDATE1: The best answer is by @Muhammad Usman. The pseudo-element :after is supported in older browsers that transform proposed by @Nenad Vracar's answer. Thank you everybody!

UPDATE2: In the @Muhammad Usman's answer it may be necessary to add line-height property - if it is declared in some parent block (thus affecting our footer). I had to add line-height: 0; to the zero-sized font block and line-height: 16px; to the block with 16px font size.

Community
  • 1
  • 1
prograils
  • 2,248
  • 1
  • 28
  • 45

4 Answers4

1

You can use position: relative on parent and position: absolute on right element.

#test {
  background: yellow;
  position: relative;
  width: 100%;
}
#block1 {
  background-color: grey;
  display: inline-block;
}
#block2 {
  background-color: green;
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}
<div id="test">
  <div id="block1">
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
  </div>
  <div id="block2">
    sample
  </div>
</div>
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
1

You should be able to use display:inline-block; on your child elements, and then use vertical-align:

#test {
  background: yellow;
}
#block1 {
  vertical-align: middle;
  background-color: grey;
  display: inline-block;
}
#block2 {
  background-color: green;
  vertical-align: middle;
  margin-left: auto;
  display: inline-block;
}
<div id="test">
  <div id="block1">
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
  </div>
  <div id="block2">
    sample
  </div>
</div>
jbutler483
  • 24,074
  • 9
  • 92
  • 145
1

With following HTML we can make it possible in 3 steps.

<div class="parent">
  <div class="child block1">
       // block one content goes here...
  </div>
  <div class="child block2">
       // block two content goes here...
  </div>
</div>

Step #01:

Use display: inline-block property to make child elements middle aligned.

.child {
  vertical-align: middle;
  display: inline-block;
}

Step # 02:

Remove the extra space added as a result of making elements inline-block. Here is one way of removing this space:

.parent {
  letter-spacing: -4px;
  font-size: 0;
}
.child {
  letter-spacing: 0;
  font-size: 14px;
}

Step #03:

Make elements to touch the extreme corners. Here is a method that will align the left element to the left edge and right one to the right edge of browser (In case parent is occupying full browser width).

.parent {
  text-align: justify;
}
.parent:after {
  display: inline-block;
  vertical-align: top;
  line-height: 0;
  width: 100%;
  content: '';
  height: 0;
}

You can see the demo in following snippet:

.parent {
  background: yellow;
  text-align: justify;
  letter-spacing: -4px;
  margin-bottom: 20px;
  font-size: 0;
}
.parent:after {
  display: inline-block;
  vertical-align: top;
  line-height: 0;
  width: 100%;
  content: '';
  height: 0;
}
.child {
  vertical-align: middle;
  display: inline-block;
  letter-spacing: 0;
  font-size: 16px;
  padding: 5px;
}
.block1 {
  background-color: grey;
}
.block2 {
  background-color: green;
}
<div class="parent">
  <div class="child block1">
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
  </div>
  <div class="child block2">
    sample
  </div>
</div>
<div class="parent">
  <div class="child block1">
    <div>test test test test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test test test test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test test test test</div>
  </div>
  <div class="child block2">
    sample text goes here...
  </div>
</div>
Mohammad Usman
  • 37,952
  • 20
  • 92
  • 95
0

It would seem that CSS tables would do the trick as shown below.

I enclosed the text in #block2 in a div, which may be more consistent with the mark-up in #block1.

(Note: Panglos provided the same answer as this in the earlier version of your question. Am I missing something in your requirements?)

#test {
  background: yellow;
  display: table;
}
#block1, #block2 {
  display: table-cell;
  vertical-align: middle;
}
#block1 div {
  background-color: grey;
}
#block2 div {
  background-color: green;
}
<div id="test">
  <div id="block1">
    <div>test</div>
    <div>test</div>
    <div>test</div>
  </div>
  <div id="block2">
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>test</div>
    <div>sample text goes here</div>
  </div>
</div>
Marc Audet
  • 46,011
  • 11
  • 63
  • 83