How to put text over an image without absolute positioning or setting the image as backbround
Asked Answered
O

6

22

I'm trying to see if it is possible to put some text over an image without using position: absolute or having the image being, the background of an element.
The reason for the constraints is that the HTML code is going into an e-mail, and it turns out that hotmail supports neither.
I remember that when I first began studying CSS, fiddling around with float-ing text around images I often ended up with the text merrily going all over the image. Sadly, I can't reproduce that behavior.

Full story (edited in):
I received a fancy layout from the graphics designer. It's basically a nice background picture, with logos linking to websites and what basically is a "text goes here" area in the middle.
As usual in these cases, I'm using tables to make sure that everything stays in place AND works crossbrowser+crossmailclient.
The problem arises from the fact that the middle "text goes here" area is not a white rectangle, but has a some background graphics.
Having made some test, it appears that Live Hotmail does not seem to like neither position: absolute or background-image; relative margins are also not good because they'd ruin the rest of the layout.

Current version, works in any other mail client/website:

...
<td>
<img src='myimage.jpg' width='600' height='400' alt=''>
<p style="position: absolute; top: 120px; width: 500px; padding-left: 30px;">
blablabla<br>
yadda yadda<br>
</p>
</td>
...

Of course, “it's not possible” could be a perfectly acceptable answer, but I hope not ;)

Ogbomosho answered 1/12, 2009 at 22:57 Comment(0)
P
88

I used to pull stunts like this all the time as soon as tables came. Really ugly, and may seriously embarrass any validator you run it trough: overlapping table cells. Works in most browsers though and even without css.

Example:

<table>  
  <tr>
    <td></td>
    <td rowspan=2><img src="//i.stack.imgur.com/XlOi4.png"></td>
  </tr>  
  <tr>
    <td colspan=2>This is the overlay text</td>
  </tr>  
</table>

I know, I deserve a downvote for this.

Palmy answered 2/12, 2009 at 0:17 Comment(5)
This is madness! Also: works, sorta. The layout (as you may have guessed by the example) already relies on a table for positioning. Since I already have several colspans and rowspans going on around and I suck at setting them, I just put another <table> in my td, and basically used your example. It works, but it somehow adds 1px (horizontal on Safari, vertical on Firefox) and even specifying sizes in all manners won't fix it.Ogbomosho
How can I modify this so that the text is visible only when the image is not loaded. When the image is available, I do not want to show the text.Benzel
Agos - did you try setting cellpadding and cellspacing to zero?Ashbaugh
This solution worked for me in apple mail, gmail and outlook.com but broke the layout in Outlook 2010. Will have to stick with solid colour square backgrounds.Informative
How do you do this with more rows and different width percentages in those rows?Mancy
C
7

If you use absolute positioning, you should specify both the left and top attributes. Also, you should set position:relative; on some parent element to make it a layer, so that the absolute positioning uses that element as origin. If you don't specify the origin, it may be the window or it may be some other element, and you don't know where your absolutely positioned element will end up.

There are some other alternatives to place elements on top of each other, each with their own limitations.

You can use relative positioning to make text display on top of an image:

<img src="..." alt="" />
<div style="position:relative;top:-50px;">
   This text will display 50 pixels higher than it's original position,
   placing it on top of the image. However, the text will still take up
   room in it's original position, leaving an empty space below the image.
</div>

You can use a floating element inside another element to put text on top of an image:

<div>
   <div style="float:left;">
      This text will be on top of the image. The parent element
      gets no height, as it only contains floating elements.
      However, IE7 and earlier has a bug that gives the parent
      element a height anyway.
   </div>
</div>
<img src="..." alt="" />
Counterfoil answered 1/12, 2009 at 23:16 Comment(1)
Hi and thanks for the explanation. Relative positioning (and I'm including gWiz's answer) is not viable: that would live a hole below, and even if I fixed the stuff below, there'd still be some hundred pixels of emptiness at the bottom. The float solution seems clever in theory, but it does not seem to work. The element is indeed removed from the flow, but subsequent elements are placed next to it, or if there is no room, below it.Ogbomosho
P
4

You can try setting negative margins. This is very difficult to maintain in all but the least complex layouts. A negative margin effective "pulls" the element in that direction.

<img src="blah.jpg" height="100"/>
<div style="margin-top:-100px">
  blah blah blah
</div>
Presbyterial answered 1/12, 2009 at 23:24 Comment(1)
Note: Negative margins are in many cases equivalent to position:relative; with negative position, e.g. position:relative; top:-100px, as in Guffa's answer.Presbyterial
K
2

The best way to control the look of things would be to make the text part of the image itself. Of course, if you use a lossy image format like jpeg with high compression it could look really bad, but maybe a PNG will work for you? Or, depending on the number of colors, a gif might work.

This also gives you consistent-looking fonts, filtering, etc.

Kress answered 1/12, 2009 at 23:2 Comment(6)
Your solution is indeed clever, but I forgot to mention that the email is for confirmation/invitation purpose, and thus the text is dynamic (e.g. it begins like "Hi, Andy!").Ogbomosho
...I could generate dynamically the image, but the thought alone gives me headaches.Ogbomosho
Ah, I see. Is there any chance you can generate the image dynamically? May not be feasible if you're sending lots of these. What tools are you using to generate the email?Kress
LOL, you answered before I asked it. :)Kress
php on a shared hosting ;_; I'm not sending a lot of these, but such a solution (while technically very interesting & challenging) is definitely out of scope for this project.Ogbomosho
This is not a good decision for accessibility purposes anymore. Images with text inside can't be parsed by screen readers, they should be two separate elements.Iey
R
0

say if you have a parent div and an image and paragraph inside it, give position "relative" to all three of them, and give "z-index" to children, say "20" image and and "21" to Text. the text will appear over the image. and you can adjust the text with "top or left or right or bottom"

CSS
#learning{
margin: 0px;
padding:0px;
height: auto;
width: 100%;
position: relative;

}
#learning>img{
width:inherit;
height:inherit;
margin: 0px;
display: block;
position: relative;
z-index: 20;
}
#learning > p{
font-family: 'droid_serifitalic';
color: white;
font-size: 36px;
position: relative;
top:470px;
left:500px;
z-index: 21;
} 
Rostellum answered 19/12, 2014 at 10:52 Comment(0)
I
0

 .main_image{grid-area: overflow;}

    .main_text{
    grid-area:overflow;
    color: white;
    margin: auto auto auto 5%;
    font-size: 2rem;
    line-height: 3rem;} 
    .main{
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows:1fr; 
    grid-template-areas: "overflow";
    }
    <div class="main">
			
      <div class="main_image">
         <img src="https://images.unsplash.com/photo-1548783300-70b41bc84f56?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80" style="width:100%; height:auto">
       </div>

       <div class="main_text"> 
            <p>overlap text</p>
            <h2>your text</h2>
            <p>lorem ipsum lorem lorem</p>
       </div>  
   </div>
   
Irrefragable answered 8/7, 2019 at 18:20 Comment(1)
While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Coroner

© 2022 - 2024 — McMap. All rights reserved.