0

I horizontally centered text on a hero image with margin: 0 auto but without specifying width. I've read in a bunch of places that this trick only works when width is specified; why is it working in this case? My guess is the width is simply set to the default image width.

Here's the code I'm using (view CodePen for full code). If I remove everything but the image URL from the CSS ruleset for .hero-image, it still works.

HTML:

<!-- Inside (Bootstrap 4) container-fluid div -->
    <div class="row">
      <div class="col">
        <div class="hero-image">
          <div class="hero-text text-white">
            <h1>Natalie Cardot</h1>
            <h5>Web developer</h5>
          </div>
        </div>
      </div>
    </div>

CSS:

.hero-image {
  background-image: url(https://image.ibb.co/fzz87S/laptop_reversed.jpg);
  /* Sets height to full height (100%) of viewport */
  height: 100vh;
  /* Ensures background image spans the full width of the viewport */
  background-size: cover;
  /* Aligns image to center of viewport */
  background-position: center;
  background-repeat: no-repeat;
  /* Enables flex layout */
  display: flex;
  /* Vertically aligns (align-items defines how the browser distributes space between and around flex items along cross-axis of container; works like justify-content but in the perpendicular direction) */
  align-items: center;
}

.hero-text {
  margin: 0 auto;
}
nCardot
  • 5,992
  • 6
  • 47
  • 83

3 Answers3

1

Here it's not about the classic margin:auto but about flexbox. You container is set with display:flex and .hero-image is a flex item and it's width is no more 100% like a default div but it's equal to size of its content and that's why margin:auto is centering your element where you don't need to specify a fixed width.

Some related questions:

What's the difference between margin:auto and justify-content / align-items center?

Flex item width flex-direction: column and margin: 0 auto

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • It works even without having display: flex, so that can't be it. As I mentioned, if I remove everything but the image URL from the CSS ruleset for .hero-image, it still works. – nCardot Apr 19 '18 at 14:44
  • no it won't work :) remove the flex and see that your div will become 100% width AND it will be centre with `text-align:center` ;) so text-align:center – Temani Afif Apr 19 '18 at 14:47
  • Just learned the .col div has a max-width 100%, with and without display: flex; this must be the reason. Also, the body's text-align: center doesn't horizontally center the hero text--margin: 0 auto is needed. – nCardot Apr 19 '18 at 14:57
  • @NatalieCardot text align will center all your text .. now you have two situation, the hero is by default 100% width (so text is centered) and when you add flex it will no more be 100% width and here you need margin:auto to center the block and not the text (because text is already centered) – Temani Afif Apr 19 '18 at 15:09
0

Margin:0 auto works because of the default font-size I would recommend that you make the hero-text have a width of 100%. While using text-align:center; as that will always center the text. My Final Code

.hero-text {
    margin:0px;
    width:100%;
    text-align:center
}
  • If it can work with the default font size, then why is it we are supposed to specify a width for it to work at all (there's always a default font size)? – nCardot Apr 19 '18 at 06:33
  • You don't always need to specify width but if we didn't have default size the page would be mostly unviewable. Chrome and other browsers have default size to make the page easy to view without css. – Industrial Comet Apr 19 '18 at 21:27
0

The text is centered because you have body { text-align: center }. The reason that the width of the hero text div is not the full width of the browser window is because .hero-image is display: flex. For the auto margin to do something the div needs to be less than 100% wide. It is, so it works but you don't really need it because the centered text does it for you.

If you remove display: flex then you'll see that .hero-image becomes 100% wide and your auto margin does nothing because there's no space for L/R margin (note however the text is still centered because of text-align).

Ryan Silva
  • 925
  • 2
  • 9
  • 17
  • Without margin: 0 auto; for .hero-text, the text is not horizontally centered, but left aligned. – nCardot Apr 19 '18 at 06:25
  • Without 0 auto for .hero-text, the text is still aligned center *within hero-text*, but the hero-text box moves to the left side. Why? Because of display: flex, hero-text is only as wide as its content. If you remove display: flex then the hero-text div will be 100% wide again. – Ryan Silva Apr 19 '18 at 20:11
  • You said "If you remove display: flex then you'll see that .hero-image becomes 100% wide and your auto margin does nothing"... the h1 blocks of text still are horizontally centered without display: flex; the auto margin still works – nCardot Apr 19 '18 at 20:19
  • The text is centered because of `text-align: center`. Try removing display:flex and .hero-text margin. The text will still be centered. – Ryan Silva Apr 23 '18 at 17:54