0

In my project, there are two columns. The left contains an image that is, at maximum, 100% of the left column's width with an auto height. The right varies in width while the left one fills up the remaining space. This uses the technique described in JackJoe's answer to a previous question.

What I want to do now is vertically center the column with the smaller height. There are times when the right column or the left column is shorter, depending upon the width of the window. I have tried using

{
  position: relative;
  top: 50%;
  transform: translateY(-50%); //with more prefixes
}

However, for some reason the top: 50% part does not work at all. Here is my current code, without the vertical centering attempt (this works as expected):

$(document).ready(function() {
 $("#right").click(function() {
   $(this).toggleClass("wide");
 });
});
#container {
 width: 100%;
 border: 1px solid red;
 height: auto;
 overflow: hidden;
}

#right {
 float: right;
 border: 1px solid green;
 width: 100px;
 transition: 1s width;
}

#left {
 border: 1px solid green;
 width: auto;
 overflow: hidden;
}

#left img {
 max-width: 100%;
 height: auto;
}

#right.wide {
 width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
 <div id="right">
  Click Me
 </div>
 <div id="left">
  <img src="http://placehold.it/440x120"/>
 </div>
</div>

EDIT: I forgot to specify -- the width of the right column needs to depend upon the widths of it's contents, just like the width of an inline-block element element would with no set width. I just used exact widths in the demo to show the fluidity of the columns.

Community
  • 1
  • 1
Ian
  • 5,704
  • 6
  • 40
  • 72
  • Your right-hand column holds text, which by definition, has no intrinsic width. So, what will control the width of the text? You might specify a min-width for the image, or a max-width for the right hand text. You need to make a design decision on what you typically expect of the content. – Marc Audet Oct 05 '14 at 22:13
  • I had simplified the code for the same of showing what it is I'm talking about. On the right is going to be a magnifying glass button that when clicked expands into a search bar, and on the left is the image, a logo. Thus, the form controls the width. All of that works fine now except the vertical centering part. – Ian Oct 06 '14 at 11:04
  • I updated my answer to demonstrate the show/hide of the expanding right column. I think the design will work nicely. – Marc Audet Oct 06 '14 at 11:23

2 Answers2

1

You could use CSS tables to get the desired result. Apply display: table-cell to the left and right elements and vertical-align: middle to vertically center the content.

This is a pretty robust approach and works in most modern browsers.

The major advantage is that you don't need any JavaScript/jQuery to adjust the layout.

Update: If you have optional elements that show/hide on the right, the vertical centering will still work.

$(document).ready(function() {
 $("#right").click(function() {
   $(this).toggleClass("wide");
 });
});
#container {
  width: 100%;
  border: 1px solid red;
  height: auto;
  display: table;
}
#right {
  display: table-cell;
  vertical-align: middle;
  border: 1px solid green;
  width: 200px;
  transition: 1s width;
}
#left {
  display: table-cell;
  vertical-align: middle;
  border: 1px solid green;
  width: auto;
}
#left img {
  width: 100%;
  height: auto;
  display: block;
}
#right.wide {
  width: 300px;
}
#right p.extra {
  display: none;
}
#right.wide p.extra {
  display: block;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
  <div id="left">
    <img src="http://placehold.it/440x120" />
  </div>
  <div id="right"><p><b>Click Me</b></p>
    <p class="extra">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer facilisis velit ut neque tempor quis cursus tortor suscipit. Curabitur rutrum magna vitae arcu pharetra eget cursus ante accumsan. Nunc commodo malesuada adipiscing. Pellentesque consequat laoreet sagittis. Sed sit amet erat augue. Morbi consectetur, elit quis iaculis cursus, mauris nulla hendrerit augue, ut faucibus elit sapien vitae justo. In a ipsum malesuada nulla rutrum luctus. Donec a enim sapien. Sed ultrices ligula ac neque vulputate luctus. Suspendisse pretium pretium felis, in aliquet risus fringilla at. Nunc cursus sagittis commodo.</p>
  </div>
</div>
Marc Audet
  • 46,011
  • 11
  • 63
  • 83
  • That jquery in the question was not to adjust the layout, it was just to demo the way the right column changes. I'll try that though and see how it turns out. – Ian Oct 05 '14 at 21:00
  • In your example, if you were using floated elements, you would need JavaScript to determine which element was taller and then adjust the vertical placement of the other shorter element. – Marc Audet Oct 05 '14 at 21:03
  • OK, I see what you mean. I was hoping I could use CSS because the containing element is always the same height as the tallest element. The problem with this method is that I can't get the right table cell to be the width I want--it needs to change with the width of its contents (see the edit on my question I'm about to make). – Ian Oct 05 '14 at 21:05
  • OK, here's [a demo](http://jsfiddle.net/iansan5653/5yx1rzbw/13/) of what's actually inside the right column. As you can see, it doesn't expand like it should, it just breaks. – Ian Oct 06 '14 at 12:00
  • Here's [the same demo](http://jsfiddle.net/iansan5653/yt97hsxo/1/), but without the table display. It doesn't have vertical centering, but the column width is not broken. – Ian Oct 06 '14 at 12:04
  • What is happening is that your two input fields are wrapping onto two lines, because the table is trying to show as much of the image as possible and it can do so by breaking the content at natural points. To keep the two input fields on the same line, use `#se_searchform {white-space: nowrap;}` see demo at http://jsfiddle.net/audetwebdesign/6m1o0w1z/ – Marc Audet Oct 06 '14 at 12:29
  • One more detail, the input box height needs minor tweaking: `height: 49px; box-sizing: border-box;`, but otherwise, the seach box styling works well. – Marc Audet Oct 06 '14 at 12:38
0

You could use display: table-cell to achieve the vertical alignment. This uses however different HTML (and CSS).

#container {
 width: 100%;
 border: 1px solid red;
 height: auto;
 overflow: hidden;
    display: table
}

#right {
 border: 1px solid green;
 width: 100px;
 transition: 1s width;
    display: table-cell;
    vertical-align: middle;
}

#left {
 border: 1px solid green;
 width: auto;
 overflow: hidden;
    display: table-cell;
}

Here's a fiddle: http://jsfiddle.net/woj3s8La/

sven
  • 609
  • 5
  • 14
  • The problem is that the right column's width does not work using this method. I need it to change depending upon the width of its contents, like an inline-block element with no width set (see my edit). This does not happen in a table. – Ian Oct 05 '14 at 21:09