0

I have a question about styling:

I want to align buttons from different divs which are all contained in a wrapper div:

<div wrapper>
  <div 1> Image Text... (button1) </div>
  <div 2> Image Text... (button2) </div>
  <div 3> Image Text... (button3) </div>
</div>

The texts in each child div are different lengths, but I need the buttons 1 2 and 3 to be on the same height.

For a reference (and my actual problem for you to look at):

http://www.maf-swiss.org/fliege-mit/#mitarbeiter_werden (just scroll down a bit, the 3 pictures are where the child divs start and the text and buttons are below)

As you can see the buttons simply go after the text, I tried many things, but I always seem to reference the child div only, and not the wrapper div.

Do I need to use position absolute in the child divs such that the first relative positioning is the one from the wrapper div? (if that makes any sense, otherwise ignore this :D)

Is this achievable using CSS only or do I need to change the layout of that section?

EDIT: Upon further investigation I realized that the problem is a bit more complex:

.box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.container {
  display: flex;
}

.container > div {
  width: 200px;
}

.content {
  padding: 6% 8%;
}

.boxButton {
  text-align: center;
}

.image {
  margin-left: auto;
  margin-right: auto;
}
<div class="container">
  <div class="box">
    <div class="image">
      <img src=http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg>
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sapien est, tempus eget aliquet nec, suscipit vitae lectus. Sed ut convallis lorem, non tincidunt sapien.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
  <div class="box">
    <div class="image">
      <img src=http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg>
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sapien est, tempus eget aliquet nec, suscipit vitae lectus.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
  <div class="box">
    <div class="image">
      <img src="http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg">
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
</div>

After reading the tutorials of flexboxes I do understand why it looks like this now. Is there a way with flexbox to make the text in the content wrapper come immediately after the image div but the button still at the bottom of the container?

I am able to change or add divs inside the contentWrapper, but the layout around it is fixed like that.

Octoshape
  • 1,131
  • 8
  • 26
  • What browsers do you need to support? Also, could you please give us all a full working example with the minimum amount of code needed to reproduce the issue? I suggest using a code snippet. – Frank Tan Jul 14 '16 at 00:26
  • @FrankTan Sorry, I completely forgot about how important that information would be :) It is not very clear which browsers I will need to support, so I will try your solution with the flexbox for now. – Octoshape Jul 14 '16 at 04:54

5 Answers5

1

UPDATE

You edited your question, so I updated my snippet. The principle is still the same as my original answer; you just need to apply the styles to the correct divs.

/* Begin changes */
.box, .contentWrapper {
  display: flex;
  flex-direction: column;
}

.content {
  flex-grow: 1;
  display: flex;
}

.contentWrapper {
  flex-grow: 1;
  justify-content: space-between;
}
/* End changes */

.container {
  display: flex;
}

.container > div {
  width: 200px;
}

.content {
  padding: 6% 8%;
}

.boxButton {
  text-align: center;
}

.image {
  margin-left: auto;
  margin-right: auto;
}
<div class="container">
  <div class="box">
    <div class="image">
      <img src=http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg>
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sapien est, tempus eget aliquet nec, suscipit vitae lectus. Sed ut convallis lorem, non tincidunt sapien.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
  <div class="box">
    <div class="image">
      <img src=http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg>
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sapien est, tempus eget aliquet nec, suscipit vitae lectus.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
  <div class="box">
    <div class="image">
      <img src="http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg">
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
</div>

Original Answer

If you only need to support modern browsers, there is a flexbox solution.

.box {
  /* The important stuff */
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

/* Not necessary for you; I did this to make the snippet look like your example. */
.container {
  display: flex;
}

.container > div {
  width: 200px;
}
<div class="container">
  <div class="box">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sapien est, tempus eget aliquet nec, suscipit vitae lectus. Sed ut convallis lorem, non tincidunt sapien.</p>
    <div>
      <button>Button</button>
    </div>
  </div>
  <div class="box">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sapien est, tempus eget aliquet nec, suscipit vitae lectus.</p>
    <div>
      <button>Button</button>
    </div>
  </div>
  <div class="box">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    <div>
      <button>Button</button>
    </div>
  </div>
</div>

The important part is to have each .box contain two elements. In this case, I put the text in a <p> and the button in a <div>. Then, use display: flex. justify-content: space-between pulls the <p> towards the top and the <div> towards the bottom.

Frank Tan
  • 4,234
  • 2
  • 19
  • 29
  • How would this work if there are 3 elements in each `.box`? – Octoshape Jul 14 '16 at 04:56
  • Nevermind, I just looked at some flexbox tutorials online, I understand now. Let me try this approach real quick. – Octoshape Jul 14 '16 at 04:58
  • Ok upon looking more closely at my situation, I realized that it is a little more complex and it doesn't work that easily with the flexbox. Let me adjust my question above and give you a snippet of the problem. – Octoshape Jul 14 '16 at 05:10
  • @Octoshape I updated my answer. This is the same markup you have in your updated question. The principle is still the same. – Frank Tan Jul 14 '16 at 12:57
  • Thanks for the updated answer, your solution would have definitely worked but sadly I don't work for them anymore now, and other things had more priority, so they went with keeping the texts roughly the same length. – Octoshape Jul 20 '16 at 16:03
  • @Octoshape I see. All the best to you. – Frank Tan Jul 20 '16 at 16:32
1

Updated layout:

  • div "container": Horizontally oriented flexbox.
    • div "box": Vertically oriented flexbox. As a child of container, is expanded horizontally as much as its siblings.
      • div "image": column banner.
      • div "content": Horizontally oriented flexbox. As a child of box, is expanded to the remaining height.
        • div "contentWrapper": Vertically oriented flexbox. As a child of content, is expanded to the maximum width possible. Its children are positioned with space between the lines, keeping the text immediately after the image and the button at the bottom.
          • p: column text.
          • p "boxButton": column button.

Instructions:

To align the buttons don't use percentage units for content's padding. Instead use something like this:

.content {
  padding: 10px 13px ;
}

Now you will see another problem, the text and button end up at the bottom. To change that, remove:

.box {
  justify-content: space-between;
}
.container > div {
  width: 200px;
}

Then add:

.box {
/*...*/
  -webkit-flex-grow: 1 ;
  flex-grow: 1 ;
  -webkit-flex-basis: 0 ;
  flex-basis: 0 ;
}
.content {
  padding: 10px 13px ;
  -webkit-flex-grow: 1 ;
  flex-grow: 1 ;
  display: -webkit-flex;
  display: flex;
}
.contentWrapper {
  -webkit-flex-grow: 1 ;
  flex-grow: 1 ;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: column;
  flex-direction: column;
  -webkit-justify-content: space-between ;
  justify-content: space-between ;
}

Works fine in Firefox, Chrome and Edge.

.box {
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: column;
  flex-direction: column;
  -webkit-flex-grow: 1 ;
  flex-grow: 1 ;
  -webkit-flex-basis: 0 ;
  flex-basis: 0 ;
}


.container {
  display: -webkit-flex;
  display: flex;
}

.content {
  padding: 10px 13px ;
  -webkit-flex-grow: 1 ;
  flex-grow: 1 ;
  display: -webkit-flex;
  display: flex;
}

.contentWrapper {
  -webkit-flex-grow: 1 ;
  flex-grow: 1 ;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: column;
  flex-direction: column;
  -webkit-justify-content: space-between ;
  justify-content: space-between ;
}

.boxButton {
  text-align: center;
}

.image {
  margin-left: auto;
  margin-right: auto;
}
<div class="container">
  <div class="box">
    <div class="image">
      <img src=http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg>
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sapien est, tempus eget aliquet nec, suscipit vitae lectus. Sed ut convallis lorem, non tincidunt sapien.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
  <div class="box">
    <div class="image">
      <img src=http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg>
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sapien est, tempus eget aliquet nec, suscipit vitae lectus.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
  <div class="box">
    <div class="image">
      <img src="http://a1.mzstatic.com/us/r30/Purple/v4/47/1b/54/471b54ad-a6cf-f61e-2f33-11ffc6bd8215/icon100x100.jpeg">
    </div>
    <div class="content">
      <div class="contentWrapper">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        <p class="boxButton">
          <button>Button</button>
        </p>
      </div>
    </div>
  </div>
</div>
  • This looks great! Is it possible in any way that we don't have to remove the `contentWrapper` div? That part is done automatically, and I can only change what goes inside the `contentWrapper` div. – Octoshape Jul 14 '16 at 11:40
  • If that doesn't work while keeping the `contentWrapper` I guess I'll have to find another solution, but currently as the question stands, your answer is the "most correct" one imho. – Octoshape Jul 14 '16 at 11:41
0

Absolutely positioning might be a good way to go, since all those elements are the same height (buttons, and the line of text after the buttons). Just add a container div around those elements.

wrapper {
  postition: relative; 
  padding-bottom: 150px; 
}
container {
  position:absolute; 
  bottom: 40px; 
}

The other option would be just setting a min-height on the paragraph tag before the button, so the elements above the button are all the same height.

  • The problem is, that the section is generated dynamically so it is not possible for me to change its layout or add a container around those elements easily. That's why I asked for a CSS only solution, but I'm sure your approach would work if it was a regular HTML/CSS problem. I should have clarified some more. Thank you for trying anyways. – Octoshape Jul 14 '16 at 05:03
0
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
<div class="col-md-3 text-center"><a href="#" class="btn btn-info" role="button">Link Button</a></div>
<div class="col-md-3 text-center"><button type="button" class="btn btn-info">Button</button></div>
<div class="col-md-3 text-center"><input type="button" class="btn btn-info" value="Input Button"></div>
<div class="col-md-3 text-center"><input type="submit" class="btn btn-info" value="Submit Button"></div>
</body>
</html>
Om Shankar
  • 265
  • 4
  • 11
0

just add this css to your button

button{
 bottom: -40px
    position: relative;}
Ganesh Putta
  • 2,622
  • 2
  • 19
  • 26