I'm trying to resize any image with existing height and width properties by a percentage (and keep proportions). I know that transform: scale(1.05) would take an image that's 100px by 100px and make it 105px by 105px, but it would still only occupy the original 100x100 space in page flow.
How would I do something like:
<img src="an.svg" width="100" height="100" alt="bigger please" class="resize" data-width="100" data-height="100"/>
img.resize {
height: auto;
width: calc(original width * 5%);
}
So that the browser renders an image that's 105px by 105px and that occupies the full 105x105?
I'm using simplified numbers for this question, but the images could have any value for either dimension.
Additionally, I can not use a wrapper or a background image, but I do have access to data-height and data-width attributes present on the images. Codepen is here: https://codepen.io/spicedham/pen/qMKLYq
Assuming you have a container available that the image is placed in, you can easily use calc to get the height and width for the image
check out this pen to see an example.
https://codepen.io/calebswank11/pen/gdKBRE
.container {
width: 300px;
height: 300px;
}
img {
display: block;
width: calc(100% + 5%);
height: calc(100% + 5%);
left: -2.5%;
top:-2.5%;
position: relative;
}
I don't think you can use the width/height attribute of an image to define new width/height. You can probably consider inline styles and CSS variable like this:
img {
width:calc((var(--width) * 5/100 + var(--width))*1px);
height:auto;
}
<img src="https://picsum.photos/100/100?image=1069" height="100" >
<br>
<img src="https://picsum.photos/100/100?image=1069" height="100" style="--width:100">
If it's not totally necessary for the img tag to be utilized (and the image is always the same aspect ratio if it's dynamic) then you could use a div with a background image, and give it height: 0; and padding-bottom: 100% (or whatever percentage that would create the appropriate aspect ratio) and modify it that way with css transforms
After exhaustively trying every permutation I could think of, I do have a solution of sorts. It requires two things I was trying to avoid (a container & inline styles), but it works as part of a system. Some additional background: I work on a web app that lets users set a base font size (think 12, 14, 16, or 18pt) and then also handles zooming at on top of that with a range from a 10% to 300% for low vision users. We have some images (mostly math expressions) that are embedded within the surrounding page content as SVGs. At default print and zoom levels an SVG with the number '3' in it is the same size as plain text number 3 next to it. But things get mismatched as the other variables start to change. The technique described below, once in place, will let us have fine-grained control over how these images match up with surrounding text regardless of print size or zoom level.
Here's a link to solution in codepen https://codepen.io/spicedham/pen/pxzYYe and a variation using... variables https://codepen.io/spicedham/pen/MPgxxo.
Here's the CSS:
.container {
display: inline-flex;
vertical-align: middle;
border-left: solid .05em transparent;
border-right: solid .05em transparent;
}
.scaleMe {
transform: scale(1.1);
margin: .05em 0;
}
And here's the what the images and containers look like:
<span class="container" style="font-size: 300px;"><img class="scaleMe" src="svg.svg" width="300" height="100" alt="" style="font-size: 100px"/></span>
<span class="container" style="font-size: 100px"><img class="scaleMe" src="svg.svg" width="100" height="200" alt="" style="font-size: 200px"/></span>
The problem I ran into whether I used calc() or transform:scale() was that I could not get content to reflow around the resized image consistently - an image scaled up would overlap adjacent content. It was possible if all the images were the same size or they all had the same proportions, but that's not something I can count on in our system.
The other problem was that using percentages as units, while the logical choice, does not work as you'd expect.
So the solution was to create a stand-in relative unit of em. I took the width of the image (say 300px) and set it as the font size for the container. I then took the height of the image (say 100px) and set it as the font size of the image. This allows me to prop open the container to occupy the same space as the scaled image. Gets around the limitation of not being able to use percentages for border widths and accurately set the equivalent of a percentage for top and bottom margins on the image.
Related
I want to display a bunch of images stored on a server. The images are taken from a user's phone and the dimensions and aspect ratio are unknown.
I just want to have an image fully fill a DIV while maintaining its aspect ratio. If the image is wider than taller, I want the image scaled so the height is 100% the Div and the sides would be clipped off. Similarly for if the image is taller than wider, I want the image scaled up/down so the width is 100% of the Div
Hopefully this explains it
I thought this would be pretty trivial, but here i am. I can make an image fit tall or wide but not either depending on the aspect ratio. I've tried several different methods and I am at a loss.
I have a Stackblitz Example here.
I have a 2x2 grid, and I would like to get the images to fill those grids. Some images need to be rotated. I'm not sure why they need to be as the look normal on my computer. I have a hardcoded flag to force a rotation on some images, but the rotation appears to screw up the css further on.
CSS:
.img-container {
/* height: 150px; */
width: 100%;
}
.img-container img {
height: 100%;
/* height: -webkit-fill-available; */
width: 100%;
object-fit: cover;
}
HTML:
<div class="showBorder img-container">
<img #image class="container-img-objfit2"
[ngClass]="{rotateLeft: rotate}"
[src]="imageURL" />
</div>
How can I fill these DIVs regardless of the aspect ratio?
Can I do any of this inside angular? I tried to get the image size and see if I could set custom class that would handle the rotation, but that didn't seem to work either. The dimension for all my pictures was identical. So no way to distinguish which pictures need rotation.
Or am I going about this all wrong? Ultimately I think I will have a process to scale and crop the images on the server so they are prepared for the client app.
Update:
This sample is an attempt to set the image in the background and use a :before selector to rotate the image. It does not work fully as I cannot change the image dynamically to other images.
You can just set the images as background-image for the div and set its size to cover.
So just remove the img tag and keep your div tag only
<div class="showBorder img-container" [style.backgroundImage]="'url(' + imageURL + ' )'">
</div>
In CSS you will have to specify the height and the size
.img-container {
height: 150px;
width: 100%;
background-size:cover;
}
I like to do a client side crop and resize of an image before displaying it in HTML 5. (The actual react application will allow to select a part of a bigger image that is displayed in a fixed size image window)
I know the offsets in pixels (x and y) in the source image and the scaling factors for width and height needed.
I can easily crop (without scaling)
<div style="overflow:hidden; width:300; height:300;">
<div style="display: inline-block; background: url('test.png') no-repeat; background-position: -10px, -10px;" />
</div>
Scaling works, but cropping get's corrupted when I include scaling
<div style="overflow:hidden; width:300; height:300;">
<div style="display: inline-block; background: url('test.png') no-repeat; background-position: -10px, -10px; transform: scale(10, 10);" />
</div>
CSS clip-path is a pretty versatile CSS property that does exactly what it sounds like you need to do. It can get lengthy, however, so I highly recommend moving to an external stylesheet as opposed to doing this inline.
What I would suggest is that you set the image in a fixed-size container, as you stated, set overflow: hidden; (of course), and crop the image with clip-path. For resizing it, use transform: scale() with one parameter, depending on how much you need to scale it.
Keep in mind that another rule could also be used like CSS object-fit.
I found the following solution
<div style="overflow: hidden; width: 300px; height: 300px;">
<img src="test.png" style="width: 600px; height: 600px; transform: translateX(-300px) translateY(-300px);">
</div>
The important aspects are:
Have a size limiting container (the div) with overflow: hidden
Resize the complete image by scaling the width and height
Crop the needed parts from the resized image (with transform translateX translateY)
Here is a pen to my attempt https://codepen.io/alexyap/pen/VbvGvw
<div id="bg">
</div>
* {
margin: 0;
padding: 0;
}
#bg {
background: url('https://static.pexels.com/photos/198747/pexels-photo-198747.jpeg');
height: 60vh;
width: 100%;
background-repeat: no-repeat;
background-size: 100vw;
}
I nearly had it figured out but I just can't seem to copy how this website https://sierradesigns.com/ did it (check slider images on landing page), mine is cut off on the bottom no matter what value i give the height
By setting the background size to cover you are giving the browser the prerogative to adjust the image until it completely covers the area; it will ignore width and height values you assign.
With contain you allow the browser to decide how to adjust the image so that the entire image fits within the area, which may be based on height or width to accomplish this (depending on the orientation of the image wide or tall).
background-size: 100% 100% is probably what you're looking for, but that will disproportionately adjust the image (ie: stretch or compress depending on orientation). However, it does sound like that's what you want when you say "both cover and contain".
There are many ways to place and scale images used as backgrounds (where background does not necessarily mean the CSS background property)
Below is a simplified example of how I've accomplished this (assuming images that are roughly 700x300 px)
.container-wrap {
width:100%;
}
.container {
position:relative;
padding:42.86% 0 0 0;
/* where padding = the proportion of the images width and height
which you can get by division: height / width = 0.42857 */
}
.container img {
position:absolute;
top:0px;
right:0px;
bottom:0px;
left:0px;
}
it is important that your images maintain a close proportion to each other -- if they are slightly off, the slight distortion shouldn't be visible to most people for most images
Again, there are other methods to accomplish this. The website you linked to applies a similar concept. The concept is the same, method is slightly different (for example they are using width:100% on the images instead of absolutely positioning them), where the concept = "using some sort of method to proportion the images to the container so it will magically scale"
Note that the same method can be applied to video containers (such as from YouTube).
The page that you link is keeping the aspect ratio of the container constant.
You can get this effect using both vw units for width and height (for instance)
#bg {
background: url('http://lorempixel.com/1000/600/');
height: 30vw;
width: 50vw;
background-size: cover;
}
<div id="bg">
</div>
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?
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;
}
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%;
}
You aren't setting width in CSS you mentioned - change max-width to width
How do you scale an image added in :before or :after in CSS?
For example, I have a page which contains a book cover:
<span class="book">
<img src="http://ecx.images-amazon.com/images/I/41t7xMPK%2B6L.jpg" />
</span>
I want to use CSS to make it look more like a book, rather than just a cover. I can use :before to add a second image to do this, but as all books vary in size, I need to be able to scale this image to fit the book cover.
I have tried
.book:before{
content:url("/images/book.png");
position:absolute;
height:100%;
width:100%;
}
but this doesn't work in scaling the image.
you can scale it:
transform: scale(0.7);
but it won't work with px or %.
The generated image is always displayed 1:1. You cannot scale it. When you fix the size of the generated element, that works well. You could check it with the following CSS attributes:
#logo-image:before
{
display: block;
content: url(img/logo.png);
width: 300px;
height: 100px;
border: solid 1px red;
overflow: scroll; /* alternative: hidden */
}
You can see the red border at the specified size, and the image content is clipped. But if you leave out the overflow:scroll, you will see the image exceeding its element.
(Tested on Firefox 11)
Try setting a min-height and a max-height for both of them to the same value, It should then scale the images to the correct size while keeping the correct aspect ratio. (And do that with the width, depending on which one you want to scale)