Crop and scale a specific region of an image using CSS (responsively) - html

I'd like to show the user a specific part of an image. Ideally, I'd be able to crop the image on the server, but I'm unable to do so for this application. I'd like a solution that appeared to the user as if the image were in fact cropped on the server, such that it could scale properly as its containing elements got bigger or smaller.
Concretely, say my image is 200px wide by 300px high, and I'd like to show the region of the image that goes in x from 0px to 200px, and in y from 75px to 225px. Therefore I'd want an 'effective image' of size 200px wide by 150px high.
I'm assuming that this will involve background-position and size, but I'm unable to figure out how to use these such that I can:
Show ONLY the desired region of the image.
Can be placed in a container with a fluid width (e.g. width: 50%) and have the size change accordingly.
I've included an example of what I've tried so far here:
http://codepen.io/anon/pen/maCvd
The example has the uncropped image, scaling to the size of its container, which is 75% of 100px. It also shows what I'd like to effectively get out of the CSS -- something equivalent to the physically cropped image, which can also scale to the size of its parent.
It shows my attempt at using background-size, which as you can see, does not scale to the size of its parent.
Thanks for any help!

The only way i can think of doing this is using the clip property. Unfortunately, this can only be applied to inline images that are positioned absolutely.
So, based on the question:
Codepen Example
HTML
<div class="wrapper">
<img class="clipper" src="http://lorempixel.com/output/city-h-c-200-300-8.jpg"/>
</div>
CSS
.wrapper {
width:50%;
height:350px;
margin: 10px auto;
border:1px solid grey;
position: relative;
}
.clipper {
position: absolute;
top:-75px; /* same as top clip */
left:0;
/* top, right, bottom, left */
clip:rect(75px,200px,225px,0px);
}

Related

Responsive image resize and selectively crop it's width with a set of rules

I want a background image to appear at the top part and fully cover the width of a page. As you can see, the image is quite wide and short - https://i.imgur.com/aJb6eBr.jpg. This should be the header image of a page, with the contents of the page appearing below it.
If the browser's width is bigger than the image's original width, the image's width and height should be enlarged proportionally (together with its container - thus pushing downwards the page's contents that appear under the image).
If the browser's width is smaller than the image's original width, the image should retain its original size without shrinking, and be cropped from both sides until a 15% crop is reached from each side (You can see that the image has quite wide green areas on both sides which are safe for cropping).
The tricky part is that once 15% of the crop has been reached from each side, I want the image to start shrinking proportionally to the browser's width, thus the middle 70% of the image will always be seen, and the image will never be cropped more than 15% from each side.
The height of the image (and it's container) should rescale automatically in proportion with the image's width. If the image's height (together with its container) shrinks to be smaller than it's original size, the page's contents are pushed up so the distance between the page's contents and the image is always kept the same.
I'm looking for a clean solution (preferably with CSS only) similar to this:
https://demodern.de/projekte/mediengruppe-rtl
Any ideas guys?
In terms of using CSS it is pretty simple to make everything work as you need. In order to do this you might use the image as it is via and the same image on a parent element's background. But you will have to adjust your CSS to work with this image ONLY. In case if you will try to use another image - you will have to adjust paddings or mediaqueries. Solution that works a kind of ONE time for a specific image, but still, it doesn't use JS at all, which is great. And regarding referencing the image twice - it is not a problem for a browser. It will make only one http request for a single unique media asset so no performance problems from this perspective.
Here is a way how you might do what you want:
.wrapper {
background: url(/images/_m1NuVvd.jpeg) 50% 50% no-repeat;
background-size: cover;
overflow: hidden;
position: relative;
padding-top: 38%;
}
.wrapper img {
transform: translateX(-50%);
left: 50%;
position: relative;
min-width: 100%;
display:none;
}
#media screen and (min-width: 1338px) {
.wrapper {
padding-top: 0;
}
.wrapper img {
display: inline-block;
vertical-align: top;
}
}
<div class="wrapper">
<img src="/images/_m1NuVvd.jpeg" />
</div>
Make sure to use a proper path to your image instead of /images/_m1NuVvd.jpeg.
BTW, in future it will be better to probide links to the images in a way, so those might be reused in jsfiddle. Dropbox doesn't allow to use the image via that link.
Best wishes

Div with max-width and max-height and retain proportions (CSS only)

OK here's a challenging one! I really want to see if this can be accomplished with CSS only if possible.
I have a unique layout that requires images to be sized and positioned based on their parent container. If the image exceeds it's parent in height or width I need it to reduce size to fit. At the moment I'm using max-width and max-height together and it's working fine. The image resizes to fit and of course keeps it's aspect ratio.
Now here's the tricky part. I need to add a special shadow to this image that cannot be accomplished with CSS box shadows. The shadow uses PNG image. The shadow needs to be sized and positioned in relation to the image - meaning it falls at the bottom of the image and it equals the width of the image.
Normally I would achieve the shadow with ::after and size and position it relative to it's parent element, which works perfectly Except it's parent is the image and images do not allow ::before or ::after.
So as far as I can tell, the only way to achieve this is to wrap the image in another container so I can use that container as the parent elements and positioning reference for the shadow layer. But I cannot find a way to make that container div behave in the same way as the image in terms of the max-width and max-height sizing while still maintaining it's aspect ratio.
The best methods for maintaining aspect ratios use padding top, which works brilliantly when the width is the only important factor. But the padding-top technique doesn't allow for the container to have a max-height.
So I'm looking for a CSS technique that will allow a block element to maintain its aspect ratio, and have max-width and max-height at the same time. Similar to how an image would behave in this situation.
I've scoured the internets for a solution and haven't seen anyone describe this exact situation. Would be extremely grateful to anyone who can assist.
Added 1 Sept 2017:
I should mention that it's more than just the shadow I need to position relative to the image. There are some other elements as well that need to be positioned in this way, and those other elements are not simple background images. So while Lightbender's solution is great for the shadow, it doesn't solve the bigger issue at hand. I need a container around the image that I can use as reference to position other child elements.
While before and after won't work (easily) but you can still use padding and a background image and it will work exactly the way your current setup works.
img.fancyshadow {
height: auto;
width: auto;
max-width: 100%;
max-height: 100%;
padding: 0 10px 10px 0; /* adjust as needed */
background: url('path/to/your/shadow');
box-sizing: border-box;
}
I don't have a Mac handy, so I've only tested this in Firefox, Chrome, and IE, can anyone confirm Safari as well?
So I would like to see a simple example of what you are attempting as a starting point but you mentioned that the images need to be sized/positioned based upon the size of their container.
Here is an starting example of something like that. Not sure if it can be modified to suit your issue. Let me know and I can tweak.
When needing to have responsive images, I never use IMG tags. Setting the background image in CSS provides much more control on responsive sites/apps.
Documentation on background-size:
cover Scale the background image to be as large as possible so that the background area is completely covered by the background image. Some parts of the background image may not be in view within the background positioning area
contain Scale the image to the largest size such that both its width
and its height can fit inside the content area
$(function() {
$('.banner').resizable();
});
.banner {
background-image: url('https://s-media-cache-ak0.pinimg.com/originals/15/ae/a6/15aea601612443d5bddd0df945af6ffd.jpg');
background-size: cover;
background-position: center;
height: 175px;
width: 100%;
}
p {
color: #666;
}
.ui-resizable-se {
box-shadow: -1px -3px 10px 3px white;
}
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<h1>Resize the image using the black triangle at bottom right of image</h1>
<p>Note how the image fills the container and the position is always centered (you can control where the position is, doesn't have to be in the center)</p>
<div class="banner">
</div>

Background scale so part of image fills div

I have an image (let's say it's 100px by 100px). I want to use the image as the background of a div, however I only want the first 50px by 50px to be visible (the other three 'corners' will be used as other backgrounds). I also want to scale the image so that the piece of the image I specify fills the div. For example, if my div is 150px by 150px, i'd want to crop by image to 50px by 50px, and then render it as 150px by 150px.
I can render the image in the background like so (using react): <div style={{width: '5vh', height: '5vh', background: 'url(./image) 0px 0px'}}></div>, however this does not scale the image back to the size I want it. How can I achieve the effect I desire?
Is it described in the image below, where the black square is the div, and the red is the content I want visible in the background, while the blue & red are the entire source image.
This is similar to this question, however that answer is several years old and does not rescale the image either.
To divide the image in four you need to double it's dimensions (in relation to the containing div)
background-size:200% 200% ;
Then you use background-position to choose the portion you need:
div{
background-image: url('http://lorempixel.com/output/abstract-q-c-100-100-9.jpg');
height: 150px;
width: 150px;
background-size:200% 200% ;
background-position: 0 0; // is top-left
/* background-position: 100% 100%// is bottom-right */
}
<div>
PS: reactwise you need to camelCase the hyphened properties( ex: background-size will become backgroundSize )

Responsive grid using image sprite as CSS background image

Wow, this was harder than I anticipated!
We're trying to use an image sprite as CSS background image on a responsive website in a grid.
Please check out our jsfiddle of the scenario.
So essentially, when this is resized, the background images from the sprite need to be resized to fit the parent container (<span>).
I have converted the background image to a data:image thinking this would be the first step (although I'm not sure) and now not really sure how I can make the background images from the sprite respond.
Everything I have tried so far ends up displaying the full sprite image in each container in the grid.
You're using absolute pixel values and background sizes in fluid setting.
Try converting your background-positions to a fluid unit (like percentage) and adding background-sizes to allow the spritesheet to resize with the container.
By removing the inner height of the image container and applying a padding, you can make the container's height ratio stay the same:
.credits-grid li span.image {
background: url(../images/credits.png) no-repeat;
padding-top: 90%;
height: 0;
overflow: hidden;
background-size: 500% auto;
}
Then by calculating the percentage coordinates of the sprite's location instead of the pixel value, you can allow it to freely move into place as the container changes size:
.credits-grid li span.image.c10 {
background-position: -26% 50%;
}
You can see this in action on this fiddle here: http://jsfiddle.net/nsvka987/2/

Twitter BootStrap Background Image

I have a fixed nav bar at the top and a container with a full width Background spanning span12. but since the content of the background image is crucial for the layout for visual cue. i want the whole image to be displayed at all times irrespective of the window size.
Which is the best way to construct the image or set of images to achieve the same.
Large Monitor
Medium Monitor
Small Size
I have a form that will be displayed to the right of the image. Hence making it a little tricky for me to get the image working.
Link: play.mink7.com/minkstock/
If I understand correctly, you want just to have a maximum size (or percentage) that your image can reach. Try, instead of a background image, using a <img> element like so:
img{
max-width: 100%; /* or any other value */
height: auto;
}
Is there any reason you chose to set the background image using css?
If i change the #landing-page-bg div to
<div id="landing-page-bg" style="background-image: none; width: auto; text-align: center;">
<img src="http://play.mink7.com/minkstock/images/landing_page_bg.jpg">
</div>
It produces the desired effect you want (minus some red background you set).
If you wanted to then overlay items on the image you could use relative div positioning.
Do something like background: url(images/landing_page_bg.jpg) 77% 0 fixed no-repeat; for your small media query.