0

I am currently working on building a responsive site but have come across a strange flaw with HTML 5.

There is no longer going to be support for sizing images at 100%, and also background images. You can now ONLY specify an image size by pixels. So if you have an image in a column or grid system, and that column or grid is sized in % as most are, the image will just fall back to its original size. This is fine if we are willing to only use images at the maximum resolution for the biggest media size.

This is fundamental kick in the teeth to responsive sites. I have looked around the web at responsive solutions and it seems that even systems like pure.css have ignored the flaw and put massive images in that work fine on full hd but take ages to load. This is a major problem when dealing with responsive sites as images by nature will now have to be output at full anticipated resolution. Imagine when 4hd becomes the norm, all responsive sites will require compressed jpegs of around 8mb in size just to work. Even for tiny icons, if they are intended to grow or shrink in scale.

The flaw has however been picked up by browsers which for now still support 100% image width but only when styled inline - for how long?

Below is an example where I would normally set an img to be wrapped by a container that makes the image fit 100% of the space given to it whilst retaining its ratio:

.photo-box img {
max-width: 100%;
height: auto;

}

In HTML 5 this no longer works. The image will only show at its maximum resolution. However if you force 100% into inline like so

<img src="images/pics/articles/article_127.jpg" alt="girl" width="100%"/>

Then this works as intended too. But this is not html 5 compliant. see Differences Between HTML 4.01 and HTML5 [http://www.w3schools.com/tags/att_img_width.asp][1]

Now I know a few of you will say - well, why size an image using percentage? But there is always a need for it with responsive sites, and there will be greater need for it when larger media types become available. Don't forget that percentage works both ways to make an image larger but also it is handy to resize an image smaller too without the need for any jquery or similar API or other clientside scripting. When an image gets smaller without % it can lose its ratio when the width has a constricting percentage container or parent. Only width 100% and height auto can stop this from happening.

Now back to the same issue with background images - A common use for background images is to apply rounded corners and shadow effects to an image but to overlay that background with an img tag of the same source with opacity set to 0. This is used all over the web to get around the fact that you can't style shadows or corners consistently to an img tag. Only its container can be styled with such effects and the images square corners overlap them. Now that 100% width is no longer supported this effect will not work as the image in the background cannot resize to match a responsive img above it and so the background tiles even if the repeat is set to none, which looks bad.

Does anyone have the same issue or know of the solution. Can anyone specify who we need to mention this to with the aim to get it back in to HTML5?

Zentaurus
  • 758
  • 2
  • 11
  • 27
fishboy
  • 51
  • 7
  • 3
    I've used HTML5 and 100% with no issues. It's probably something else in your code – Andy Holmes Mar 03 '14 at 11:41
  • 1
    Please create a fiddle to support your statement.. 100% width works.. – Prasanna Aarthi Mar 03 '14 at 11:55
  • 1
    I'am confused with "you can only style images inline..." here: http://jsfiddle.net/NicoO/Wwrz2/ – Nico O Mar 03 '14 at 11:56
  • if you check the link w3c is recommending that % is removed from img tag with regard to width. As a test - set a div to 50% of the screen width then put in an img tag with the width of the image set to 100%. By rights the image should be 50% the size of the browser - filling its container. True. Now reduce the image to say 100px and try that. By rights the image should upscale to be 100% of the 50% box - but it doesn't if you use html5 markup. – fishboy Mar 03 '14 at 12:43
  • This is the problem. People like pure.css have got around this issue by uploading images at 100% browser width but as you can see this is crazy and will lead to massive images instead of small images. Now try to do this with css rather than inline and you will see the issue. inline still works to some degree on most browsers but css does nothing. Combine this with background % scaling and the same happens - unles you use background-size:contain inline – fishboy Mar 03 '14 at 12:45
  • @nico O if you stretch your image in fiddle to be bigger than 1000px it does not scale. See above comment. 100% width means 100% of the maximum image width but that does not help with up or downscaling in flexible containers. You really only see the issue with smaller images but imagine the future where someone views this on 4hd - suddenly you will see that the 100% width image does not fill the container as you intended, so that isn't responsive. The same works in the opposite direction if image width is specified and height isn't the image will begin to dispro as your container shrinks – fishboy Mar 03 '14 at 12:57
  • @fishboy i'am sure you have a valid point. And thanks for your explaination, but it would really help to understand the issue with an example. Alter the fiddle: http://jsfiddle.net/NicoO/Wwrz2/2/ Here the image will always be the size of the current container no matter how big or tiny the image may is. – Nico O Mar 03 '14 at 13:05
  • @ nico - stretch the dividing result bar to the left and you will see your image does not fill the given area 100%. It is always 1000x400 and grows no further. Check out purecss.io and view their layout examples. They have the same issue but have resorted to massive images. Does this make sense? – fishboy Mar 03 '14 at 13:12
  • also @nico Now apply width:100% inline to your img tag in the example and what I am trying to achieve works. However, this is no longer html5 compliant – fishboy Mar 03 '14 at 13:15
  • What is the difference? http://jsfiddle.net/NicoO/Wwrz2/3/ – Nico O Mar 03 '14 at 13:18
  • I agree there is no difference only that in html5 it is not allowed hence what you are doing may suddenly stop being supported. So all images will display at their maximum size only. Which is not what I think your code intends. Sorry the problem gets exponentially worse in a fluid grid, your example is much more simplified. It also gets worse with images as backgrounds. All I am trying to say is that I think html4 works but html5 doesn't. As an example some IDE's pick up that the code whether inline or CSS is invalid, therefore that means 'not allowed' AM I right in assuming this to be true? – fishboy Mar 03 '14 at 13:27
  • @fishboy By using `width:100%` in css instead of `max-width:100%` will always display your image at full container width. Your image will be stretch or shrink to fit in the container. Please see the jsfiddle posted by Nico. I suspect you have errors in your CSS file. Is your container really have the following classname `photo-box`? – service-paradis Mar 03 '14 at 13:52

3 Answers3

2

You confused the attribute (<img width="" />) width with the CSS property width (img { width: ... ; }) which are not the same.

Here is a better source:http://www.w3.org/wiki/HTML/Elements/img and here a possible duplicate of this post: What's the difference between HTML's and CSS's width attribute?

About the attribute width=""

width = non-negative integer
Give the width of the visual content of the element, in CSS pixels. 

About the CSS Property width:; http://www.w3.org/wiki/CSS/Properties/width

Values  <length> | <percentage> | auto | inherit
Initial value   auto
Applies to  All elements but non-replaced inline elements, table rows, and row groups 

So you are safe to use CSS width property with percentage but not within the attribute.

If you want to give an image an inline width of 100%, you may do it like this:

<img style="width: 100%;" />

Regarding your question.

if your HTML is this:

<div class="photo-box">
    <img src="images/pics/articles/article_127.jpg" alt="girl" width="100%"/>
</div>

with this selector:

.photo-box img {
    width: 100%;
    height: auto;
}

It is very much likely that the attribute overrides the CSS property. Remove the property for your tests or try (but don't use this all the time, just for testing)

.photo-box img {
        width: 100% !important;
        height: auto;
    }
Community
  • 1
  • 1
Nico O
  • 13,762
  • 9
  • 54
  • 69
  • Strangely that is what I also thought, however in my tests I cannot get width in css to do anything but when I apply it inline it works. – fishboy Mar 03 '14 at 13:43
  • Then your css have to be faulty I guess. Please post it or even better create a own jsFiddle, you don't even need to register. Just put code, press save/update and copy the url. – Nico O Mar 03 '14 at 13:44
  • I am targeting images in photo-box, I just didn't show that container. I have a div that wraps the img in order to use a background image of the same source then the image is applied with 0 opacity. Thats another isue but it points to the same problem - sorry I didn't want to confuse matters but it appears I already have! – fishboy Mar 03 '14 at 14:03
  • I've updated my answer a lot. What happens, when you make your images visible again and remove the background-images which are redundant to the invisible images. Then remove the `width=""` attribute from the images. Then Apply CSS `width: 100%;` like in my answer now. Desired result? – Nico O Mar 03 '14 at 14:05
  • 1
    @fishboy It would be very useful for people to help you out if you post more code. Please create a http://jsfiddle.net/ with your `photo-box`container, your image container and an image sample. This way we will see exactly your HTML structure as your CSS. It will be easier to help you out because there is nothing wrong with the css property `width:100%`. – service-paradis Mar 03 '14 at 14:14
  • I think so - I will post the combo answer below if that helps anyone else. It appears that display:block is required and with regard to my background for effect I needed to use backgroud-size:contain; to fill the container filled by the image itself. Thanks for your help, not sure where I went wrong but it seems to work now, but is this compliant still? – fishboy Mar 03 '14 at 14:14
  • like i posted in my answer, yes. CSS width allow you to use percentage. Forget about the attribute, nobody will need this. – Nico O Mar 03 '14 at 14:17
1

With some valid pointers from nico it seems I have a solution at least to applying styles to images. I am now using the background source inline and I have changed photo-box to image-box. I am also now able to apply any, none or all styles to the images:

my html is as follows which will draw three images whose containers are 100% wide at all times and have the desired effects applied:

example 1 - just the wrapper

<div class="image-box" style="background-image:url(images/example_123.jpg)">
          <img class="image-hide" src="images/example_123.jpg" alt="image example"/>
</div>

example 2 - the wrapper with the shadows and highlights

<div class="image-box image-effect" style="background-image:url(images/example_123.jpg)">
          <img class="image-hide" src="images/example_123.jpg" alt="image example"/>
</div>

example 3 - the wrapper with corners

<div class="image-box image-radius" style="background-image:url(images/example_123.jpg)">
          <img class="image-hide" src="images/example_123.jpg" alt="image example"/>
</div>

example 4 - the wrapper with all

<div class="image-box image-radius image-effect" style="background-image:url(images/example_123.jpg)">
          <img class="image-hide" src="images/example_123.jpg" alt="image example"/>
</div>

my css is as follows which now works as pointed out by nico, and includes display:block (avoids the 4px height issue) and width:100% (which avoids the inline size issue with html5)

    /*image div wrap for using background under image (applied to container of background)*/

 .image-box {
        background-repeat: no-repeat;
        background-size:contain;
        background-position: center center;
    }

    /*image div wrap for effect (applied to container of background when shadow required)*/

 .image-effect {
        box-shadow: -4px 4px 8px 0px rgba(0, 0, 0, 0.3), inset -3px 3px 5px 0px rgba(255, 255, 255, 0.6), inset 3px -3px 5px 0px rgba(0, 0, 0, 0.6);
    }

    /*image div wrap for corner (applied to container of background when corners required)*/

 .image-radius {
        border-radius: 16px;
    }

    /*img class (to prevent the square edge of the actual image from hiding the style*/

 .image-hide {
        opacity: 0;
    }

    /* img tag when inside image-box (to prevent the addition of 4 pixels when default inline and to set the image width to fit the container always in aspect ratio)*/

 .image-box img {
        height: auto;
        display: block;
        width:100%;
    }
fishboy
  • 51
  • 7
0

You aren't setting width in CSS you mentioned - change max-width to width

Grishka
  • 49
  • 1
  • see above comment - width in % does nothing hence the reason it is not in. however max-width does work with some browsers – fishboy Mar 03 '14 at 12:46
  • by does nothing I mean that beyond the image actual size % does not scale. Imagine Nico Os example on 4hd. The image he uses would be only a quarter of the screen. He would have to upload an image 4000px by 1600px to get it to display full width. I know this is not that relevant now, but it also works in reverse. If you define a media width and the image had no height spcified (as 100% width and Auto height used to do) the ratio is lost. Also bad as we cannot know whether a device is portrait or landscape – fishboy Mar 03 '14 at 13:08