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)
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'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.
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'm using centered imgs to act as backgrounds for some tiles. I'm trying to have these images scale with their parent div's height and if they are wider then their parent's for them to hide the overflow.
Example:
* I've got it working now. Answers are below, I'm updating this code to display all I needed to use to get it to work *
HTML
<div class="container">
<img class="derp" src="http://gridiculo.us/images/kitty02.jpg">
</div>
CSS:
.container {
height:250px;
width:50%;
}
.derp{
object-fit: cover;
height: 100%;
width: 100%;
}
Here's a near-example: http://codepen.io/chriscoyier/pen/myPMGB
The difference would be that I'm using s and not background-image, and that instead of the img filling the div completely it would fit to the height and hide the width overflow.
I'm trying to avoid using background-image since I'm using a lot of these tiles and making CSS rules for every one isn't going to work.
In order to scale it with the div's height, I'd change the height from px to % - this way, the larger's the div, the larger's the picture. In order to certain the image, i'd use margin in the image css. That'd look like so:
.derp{
height:80%;
width:80%;
margin:10%;
}
.container {
height:250px;
width:50%; /* needed */
/* inner img is centered horizontally */
vertical-align:top;
text-align:center;
overflow-x:hidden;
}
<div class="container" style="background-color:gray"> <!-- The background is there so you could see the image relative to the div -->
<img class="derp" src="http://gridiculo.us/images/kitty02.jpg">
</div>
The best way to keep the aspect ratio of the image is to set the width to auto (and it's the default behavior so you don't need to set explicitly). And with a simple overflow:hidden it works almost as you want it.
The hard part is centering horizontally. You can try this answer :css to center a image horizontally.
However if all your images aren't the same size, you will need to make one rule per image. And in this case putting the image as background-img would be better for semantic and accessibility (because your image doesn't have a sense in the page, it doesn't convey any information, it's decoration). An <img> would be read by a screen reader (the alt attribute), and in your case it wouldn't help a blind people.
Depending on how many browsers you need to support, I'd suggest you use object-fit! Support for it is okay if you can ignore IE, but in case your project qualifies, I see no problem with using it today. Also, there is always a polyfill.
You can find a nice summary on CSS-Tricks.com about the property. It basically works similarly to background-size, but for <img> tags. In your case, object-fit: cover; does the trick.
I made a little demo on CodePen that shows you how it works.
img {
height: 100%;
object-fit: fill;
width: 100%;
}
I'm looking for a way to use a part of a picture to use as a thumbnail without actually resize the image.
It's like you capture a part of the picture and show it as thumbnail
try using CSS overflow to limit the viewport in the div, like so
.preview {width: 60px; height: 60px; overflow: hidden;}
<div class="preview">
<img src="path to big image" alt=""/>
</div>
I think sprites are what you're looking for.
CSS Tricks has some posts on how to use sprites, so I'd refer you to that, maybe starting with the article CSS Sprites: What They Are, Why They’re Cool, and How To Use Them
What you describe seems to be the use-case of the CSS clip method.
img {
position:absolute;
clip:rect(0px,60px,200px,0px);
}
img:hover {
clip: auto; /* 'un-clips' the image and displays it full-size */
}
The main caveat with this technique is that the element to be clipped must have position: absolute; to work.
See (in order of recommendation):
http://www.cssplay.co.uk/menu/clip_gallery
http://www.w3schools.com/CSS/pr_pos_clip.asp
Here's what you want to do... The DIV with the background image works, but that's a DIV. If you want it to still behave like an image layout-wise, you could get your hands dirty with "inline-block" and a matrix of browser incompatibilities, or you could simply use a transparent image with a background image on that. Construct a 1x1 pixel transparent GIF, say it's "pixel.gif." Then all you do is:
<img src="pixel.gif" width="40" height="40"
style="background:url(full_pic.jpg) -90px -90px no-repeat">
In this case 40x40 is your crop size, and (90, 90) is the offset into the full image where you grab the crop from.