13

I have a square-shaped flexbox, that is completely covered with one hyperlink.

Now I want to vertically center the content of the flexbox.

However, using a div element with the property display: table and a nested div with the property display: table-cell; vertical-align: middle does not work, since I lose the square shape.

If I use divs instead of ul and li I lose the property of being able to click everywhere.

I would like "Text" to be aligned in the horizontal and vertical center of the red box:

body {
  margin: 0px;
  width: 100%;
}
main {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}
.flex-container {
  width: 100%;
}
ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  -webkit-padding-start: 0px;
  -webkit-margin-before: 0px;
  -webkit-margin-after: 0px;
}
li {
  display: flex;
  flex-direction: column;
  width: 50%;
}
.red {
  background-color: red;
}
.white {
  background-color: white;
}
.tile:before {
  content: '';
  float: left;
  padding-top: 100%;
}
.tile {
  text-align: center;
}
<main>
  <div class="flex-container">
    <ul>
      <li class="red">
        <a href="/">
          <div class="tile">
            Text
          </div>
        </a>
      </li>
    </ul>
  </div>
</main>
SherylHohman
  • 16,580
  • 17
  • 88
  • 94
Skrodde
  • 655
  • 3
  • 7
  • 19
  • Remove the superfluous div, and make the links itself flex items that cover the whole height, and have their content centered. – CBroe Jan 30 '17 at 15:43

4 Answers4

23

main {
  height: 200px;
  width: 200px;
}
a {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: red;
  height: 100%;
}
<main>
  <a href="/">
    <div class="tile">Text</div>
  </a>
</main>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • The div should be a span because it is not good practice to nest a block element (div) inside an inline element (a) – AndrewBrntt Oct 17 '19 at 16:14
  • 1
    @AndrewBrntt, thanks for the message but that practice is obsolete. With HTML5, a `div` element inside an anchor element (`a`) is perfectly valid and acceptable practice. In more technical terms, anchor elements are allowed to contain *flow* and *phrasing* content. Divs represent flow content. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Properties – Michael Benjamin Oct 17 '19 at 23:01
  • 1
    Right on, I was not aware that had changed thanks – AndrewBrntt Oct 18 '19 at 22:31
3

In your .tile delcaration, you need the flexbox code as follows:

justify-content: center;
display: flex;
align-items: center;

You LI declaration should just be display:block as it is not using the flexbox properties.

Zack Kirby
  • 169
  • 5
0

Change your CSS as followed:

    .tile:before {
        content: '';
        float: left;
    }
    .tile {
        text-align: center;
        padding-top: 50%;
        padding-bottom: 50%;
    }

You will not lose your square-shape and the padding will always center the text.

You can check it out here:

https://plnkr.co/edit/BgPW9exwJpyxHFn5fMBP?p=preview

webfussel
  • 116
  • 1
  • 6
0

I removed the :before part of .tile, and moved it to the a tag (now class-ed click-container. Since it doesn't feel like where it should be. You want the a element itself to be square, not its content.

Now that we have a square anchor, you can use any of the vertical alignment tricks to center the content, in this example I used the absolute+translate trick:

body {
  margin: 0px;
  width: 100%;
}
main {
  display:flex; 
  flex-wrap:wrap;
}
.flex-container {
  width: 100%;
}
ul {
  display: flex;
  flex-wrap:wrap;
  list-style: none;
  -webkit-padding-start:0px;
  -webkit-margin-before: 0px;
  -webkit-margin-after: 0px;
}
li {
  display: flex;
  flex-direction: column;
  width: 50%;
}
.red {
  background-color: red;
}
.white {
  background-color: white;
}

/* edited code */
.tile {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.click-container {
  display: block;
  text-align: center;
  position: relative;
}
.click-container:before{
  float: left;
  padding-top: 100%;
  content: "";
}
<body>    
  <main>
    <div class="flex-container">
      <ul>
        <li class="red">
          <a class="click-container" href="/">
            <div class="tile">
              Text
            </div>
          </a>
        </li>
      </ul>
    </div>
  </main>
</body>
AVAVT
  • 7,058
  • 2
  • 21
  • 44