Search code examples
htmlcsscentering

Positioning text over image (html,css)


So, I have an image and I want to display in the center of it some text.

Code:

.img {
    position: relative;
}

.img h3 {
    position: absolute;
    width: 100%
    top: 85px;
    text-align: center;
}

Ok, so I managed to do it. But here is the thing: when I resize my browser and the image becomes smaller, the text is going out of the image.

So my question is, do I have to use the @media rule for all the different dimensions? And how do I know which dimensions to use in my CSS?

Or is there maybe something I can do so my text element always stays inside the image?

Thank you in advance.


Solution

  • You have a bunch of different options you can make use of, each with its pros & cons and with a difference in browser support:

    1. Flexbox: (support)

    Flexbox is the simplest option you have, without using tables or having to get your elements out of the document flow, but it's not as widely supported as other viable options. I trust it will be soon enough.

    Code:

    /* --- CSS --- */
    .background {
        height: 10em;
        display: flex;
        align-items: center;
        justify-content: center;
        background-size: cover;
        background-position: center;
    }
    
    .background > h4 {
        color: #000;
        font-size: 2em;
        font-family: sans-serif;
    }
    <!--- HTML --->
    <div class = "background" style = "background-image: url(https://images.freecreatives.com/wp-content/uploads/2015/05/HD-Vintage-Photography-Wallpaper.jpg);">
      <h4>Hello, world!</h4>
    </div>


    2. Line-height: (support)

    When using this option, you have to ensure that:

    • the line height of the title is equal to the container's height and
    • the title is an one-liner.

    (view note #2)

    Code:

    /* --- CSS --- */
    .background {
        height: 10em;
        text-align: center;
        background-size: cover;
        background-position: center;
    }
    
    .background > h4 {
        color: #000;
        font-size: 2em;
        margin: 0 auto;
        font-family: sans-serif;
        line-height: 5em; /* container height / 2 */
    }
    <!--- HTML --->
    <div class = "background" style = "background-image: url(https://images.freecreatives.com/wp-content/uploads/2015/05/HD-Vintage-Photography-Wallpaper.jpg);">
      <h4>Hello, world!</h4>
    </div>


    3. Position: Absolute & Transform: (support)

    This is probably the overall most used method as it is widely enough supported, but it has the disadvantage that gets the element (title) off the normal flow.

    Code:

    /* --- CSS --- */
    .background {
        height: 10em;
        position: relative;
        background-size: cover;
        background-position: center;
    }
    
    .background > h4 {
        top: 50%;
        left: 50%;
        margin: 0;
        color: #000;
        font-size: 2em;
        position: absolute;
        font-family: sans-serif;
        transform: translate(-50%, -50%);
    }
    <!--- HTML --->
    <div class = "background" style = "background-image: url(https://images.freecreatives.com/wp-content/uploads/2015/05/HD-Vintage-Photography-Wallpaper.jpg);">
      <h4>Hello, world!</h4>
    </div>


    4. Table (support)

    Well, I will likely be lynched, if anybody finds this out, but you can use display: table for the container and display: table-cell for the title to take advantage of the aligning of tables.

    You can now center your title:

    • horizontally, by using text-align: center and
    • vertically, by using vertical-align: middle

    Code:

    /* --- CSS --- */
    .background {
        width: 100%;
        height: 10em;
        display: table;
        background-size: cover;
        background-position: center;
    }
    
    .background > h4 {
        color: #000;
        font-size: 2em;
        text-align: center;
        display: table-cell;
        vertical-align: middle;
        font-family: sans-serif;
    }
    <!--- HTML --->
    <div class = "background" style = "background-image: url(https://images.freecreatives.com/wp-content/uploads/2015/05/HD-Vintage-Photography-Wallpaper.jpg);">
      <h4>Hello, world!</h4>
    </div>


    Notes:

    1. Since we are using an empty div for our image the height must be explicitly defined at all times.
    2. Using line-height to center an element vertically requires that the line-height is equal to the height of the parent. In this case, 50% of the parent height is used, due to the fact that the font-size of the title is 2x the font-size of the parent and its also expressed in ems.
    3. With regard to the @media query you made mention of, it should not be used for simple stuff like centering text, but rather for showing/hiding elements based on screen size etc.
    4. If you care about the portability of your website to smaller screens, my advice is to avoid using px (pixels), but instead use % (percentages) that will update based on the screen or em (ems) by manually updating the font-size of the container using a @media query.