I'm in the process of trying to wrap my head around using srcset and sizes on img tags.
Whilst I think I have grasped the basics – mainly thanks to this article – I'm struggling in practical application of the sizes attribute.
In all the examples I can find, things are massively simplified and the sizes attribute is declared as if at each breakpoint, the image width will be an exact proportion of the viewport width, allowing the use of vm units. For example:
sizes="(min-width: 36rem) 33.3vw,
100vw"
Of course in real life, images are often within other containers which themselves might be within other containers and so on, each with their own margin, padding or positioning.
Is it fair to say that in all but the simplest cases (when images are of fluid width and are not simply an exact percentage of the viewport), calc must be used, potentially adding hideously complex calculations to the html markup as an images dimensions need to be calculated working from viewport width, down through any containers to the image? For example how would you calculate the correct size for an image located a container with 7px padding that is itself inside a container that is 45% of its container with 15px margin that is inside a sidebar that is 25% of the main page container which has 15px of padding and has a min-width of 1220px?
sizes="(min-width: 36rem) calc(((((1220px - (2 * 15px) * 25%) * 45%) - (2 * 15px) - (2 * 7px)),
100vw"
Trying to calculate this in the sizes attribute seems ludicrous, especially given that all this might change at each breakpoint. having to keep this massively complex calculation in sync with changes to the CSS seems like madness. And then you have the patchy browser support for calc.
I feel like I'm missing something obvious, but what is it?
Note: I'm aware of Alexander Farkas's excellent Lazy Sizes which does the size calculations for you through the use of data attributes, but I'm interested in standard usage.
First of all % units are not allowed in sizes. You must use vw units. (Which can include the scrollbar width). So your 25% becomes 24-25vw for example.
Second there is no real difference between rem and em (in context of sizes attribute). In case you don't use em/rem based media queries / min-width/max-width in your CSS, never use those in your sizes attribute.
Basically sizes don't need to match your real image size 100% exactly. It is a tell for the browser to find the right image candidate approximately.
Your min-width: 1200px rule as also every max-width usage in your CSS, should be clearly part of a new media condition in your sizes attribute.
This leaves us with the following sizes part:
(min-width: 1200px) calc(11vw - 44px)
In case you add have a max-width defined or a media query that stops sidebar from growing, you can be less correct and simply transform 11vw - 44px into 10vw:
For example:
sizes="<...,>(min-width: 1800px) 180px, (min-width: 1200px) 10vw, <....>"
About calc support: picturefill 3.0 beta as also respimage, do include calc support for IE8+, so all browsers which do support sizes have good enough calc support and all respimage polyfilled browsers do support calc in sizes also.
About getting this straight. This is clearly painfull and in most cases your CMS/backend system should help here. In most projects you should agree upon a limited set of allowed image formats and write the sizes for those corresponding to your design. And your backend should manage to attach those sizes at the right place. In case this is not possible. Either use indeed lazySizes or use srcset with sizes at least for the most important images (i.e.: large image formats, because this is where you can save data most).
If you want you can pick a real website and we attach full correct sizes to it. But be aware. It must be only width constrained. The standard currently does not support height constrained images (This is a lazysizes feature only).
Related
I understand that currently we are supposed to use width and height attributes on <img> elements again, mostly to avoid or minimize layout shift. And this works OK when I have images with the same set dimensions across all screen sizes.
But what do I do in the following situations:
fluid width/height, possibly simply 100%, so full container width, and the container changes its dimensions based on screen size basic responsiveness)
same, but with image itself having set dimensions but differing on breakpoints?
I tried searching for answers online, obviously, but in most cases I can only find articles convincing me how important it is to use these attributes, or, that this is a hassle now, but will be much easier once aspect-ratio is introduced and implemented in the browsers. So, not very useful so far.
In other words, let's say I have an image that is:
100% wide, height: auto on mobile breakpoint,
20rem x 12rem for medium resolutions,
40rem x 24rem for large resolutions,
60rem x 36rem for xlarge ones.
What would I put in the width="X" height="X" attributes?
Ok, so after quite extensive research and experimentation I've found out that, in truth, it doesn't really matter as long as the aspect ratio is preserved. So the best bet would probably be to use image's original dimensions.
I have a very big website many different elements and generation of content. It does not seem practical to unconditionally add a meta[#name="viewport"] to the HTML of all the pages, because then it might break down various elements, and/or make some of the logos or graphics unnecessarily large.
We'd instead like to use a CSS media query like #media (width: 980px), (hover: none) {…}, and increase the font-size of actual text. This can partially be done automatically through -webkit-text-size-adjust, however, the feature seems 100% half-baked in that it simply accepts a percentage for the zoom without consideration of how big or small the viewport is, which would vary even on a single device w/ landscape vs. portrait mode.
Question: Is there a way to determine the appropriate font-size that I should use in my 980px viewport to match the default font-size that would have been set had viewport's width been set to device-width?
There's quite a lot of resources encouraging to use ems over pixels in media queries. However, none of them easily explains the obvious doubt about it:
If I have two divs and I want to hide one of them on iPhone4-like devices, how do I do it with em-based media queries? The device resolution is 640x960 in pixels.
In every article there a note that usually 1em = 16px. But since it is not certain, why would I want to convert to ems and risk breaking my design? What if user changes his default font to 20px? Or 10px? My div will hide either too soon or too late.
Example from Foundation:
/* min-width 641px, medium screens */
#media only screen and (min-width: 40.063em) { }
How can I be sure it really is 641px and not 1282px? Why would anyone use something so untrustworthy instead of old good pixels?
First the sizing in em cannot be changed by the user as this is a browser setting that cannot be changed. So at best it could vary between browsers but I don't know any that differs from this standard. For that reason, it can be considered quite safe to use.
But for media queries, I would recommend to use rem units. em units is mostly preferred for font sizing in components as it scales relatively based on the parent DOM element. While rem units work well for sizing root elements (width, height...).
px is an absolute unit of measurement (like in, pt, or cm) that also
happens to be 1/96 of an in unit. Because it is
an absolute measurement, it may be used any time you want to define
something to be a particular size, rather than being proportional to
something else like the size of the browser window or the font size.
em is not an absolute unit - it is a unit that is relative to the
currently chosen font size. Unless you have overridden font style by
setting your font size with an absolute unit (such as px or pt), this
will be affected by the choice of fonts in the user's browser or OS
if they have made one, so it does not make sense to use em as a
general unit of length except where you specifically want it to scale
as the font size scales.
Based on this, the most accurate option is using px instead of embased on what you are asking, but you can always redefine your fonts and use rem instead, this is better for responsive websites, together with percentages. That's a matter of judgment in every single element you are adding to your website, and of course, lots of testing to make sure it looks good and works flawless on any resolution and devices.
I personally prefer to do it this way:
I define my fonts and font-sizes (this overrides the default ones)
I use percentages for the block elements
I use rem for the fonts and media queries
But of course sometimes I have to use pixels or change some of my "default" rules depending on my needs. As I said before, it's too a matter of judgement on your needs and on it is best.
Note: The em unit is relative to the font-size of the parent. The rem unit is relative to the root—or the html—element. That means that we can define a single font size on the html element and define all rem units to be a percentage of that.
I'm building a responsive website and I'm wondering what unit I should use? I've seen a lot of sites using pixels (px) for measurements and I've seen some using percent (%). Is there a preferred — or right — way of doing responsive design?
I've found percent to be hard to use, since it makes calculations hard and I've ended up with values like 2.754% and so on when setting widths/margins etc. Pixels seems easier, it's just simple addition and subtraction, but I've read that it isn't "future proof" or something like that and wont scale properly if the user zooms in the browser window. Is that still true?
If you have any experience or expertise, please share! I would love to hear what you guys have to say!
Thanks!
For layout type things like the sizes of boxes, you want to use % because you will typically have several columns sized as a percentage of their parent that will stack on top of each other at a certain breakpoint (width:100%). No other unit will allow you to fill 100% of the space like % does.
For padding/margins use em, normally you will want to space your elements out relative to the size of your text. With em (the with of an 'M' character) you can quite easily say I want approximately 1 character spacing here.
For borders you can use px or em, there is a difference though. If you want your border to look like it's one pixel wide on all devices, use 1px. It may not be one pixel on all devices however, high density displays convert 1px into 2px for example. If you want your border to be a size based on your font, use em.
For fonts use em (or %), the use of em carries through parents to children and it just a nicer unit to work with over px.
Of course you must use percentage. But with the min-height, max-height, min-width, max-width CSS keys.
For the next generation
vw and vh. The vw is 1/100th of the window's width and the vh is 1/100th of the window's height.
For responsiveness they are going to be the new units.
Use percentages along with min-width and max-width in pixels. This stops percentages making your divs too small or too large. eg
div {
width:100%; //full width of browser
max-width: 960px; //this means it will be 100% of the browser until 960px then it will stop expanding
}
For layouts vh and vw are good because they are relative to the device's view port. They give you the possibility of designing with the view port of the device in mind. With this said you know what will show on the window and what won't without being too careful.
For text em is best because if it's responsive features.
There are many types of display that people use, so it is hard to expect what resolutions will your user use to view your site. To avoid this problem, I am thinking using percentage instead of pixels, em and pt to define the web layout. However, is this a good practice to do this? Including using the percentage, eg 80% for the main wrapper ?
I know it is hard to do it when it come to determine the width of the inner element. I'll have to calculate the percentages based on the each div's parent. How do you guys cope with this problem when it come to different browser's resolution?
Css media query is best solution for this check this http://css-tricks.com/css-media-queries/
There's obviously debate between fluid and fixed layouts, but fluid layouts can work very well as well.
An example is smashing magazine (try resizing your window with the site loaded).
I believe that it would be a lot easier if you use a framework of some sort. If you have used any grids CSS framework before, you can have a look at Liquid Blueprint. This allows you to work in a grid based manner, but have the page fluidly resize according to the browser's size.
I use percentages for every width within the outer container but have min-width: and max-width: for the container itself, so it scales a small amount. Say 960px for min width and 1160px for the max width. This way it works larger screen sizes better and if I want to I can go back and make it responsive because its already all in percentages.