CSS Image overflow hidden without stretch - javascript

I am trying to reduce the thumbnail's height without stretching the image. Despite I wrote my code in React I know is pure CSS.
For example, I used a sample screenshot from Wikipedia, its height is too large to fit "in a thumbnail" so I need to reduce it so a JavaScript library can autoscroll it when hover event is triggered (but this is a future step).
The following image is how the thumbnail should look like:
Instead it displays the whole image, as you can see below:
.image {
width: 200px;
}
.image-link {
height: 400px;
overflow: hidden;
}
<a class="image-link" href="#">
<img src="https://storage.googleapis.com/openscreenshot/A%2FG%2FO/AsjRlWOGA.png" class="image" />
</a>
So, how can I reduce the image's height without stretching it or overflowing the a?

Add display: block; (or inline-block, depending on the situation) to the class of the a tag, otherwise it's an inline element on which your height setting (and with it the overflow: hidden) won't have any effect:
.image {
width: 200px;
}
.image-link {
display: block;
height: 400px;
overflow: hidden;
}
<a class="image-link" href="#">
<img src="https://storage.googleapis.com/openscreenshot/A%2FG%2FO/AsjRlWOGA.png" class="image" />
</a>

I found this answer:
( Overflow: hidden is not working with images ).
You need to add a wrapper element with all scaled images contained as the thing that is affected by overflow.
The images can then be adjusted in relation to that wrapper class.
.image {
width:200px;
height:200px;
overflow: hidden;
}
.image-link {
width: 400px;
height:400px;
background-color:red;
}
.imageScale{
width:200px;
}
<a class="image-link" href="#">
<div class="image">
<img src="https://storage.googleapis.com/openscreenshot/A%2FG%2FO/AsjRlWOGA.png" class="imageScale" />
</div>
</a>

Related

crop GIF images without loosing animation using javascript [duplicate]

I want to show an image from an URL with a certain width and height even if it has a different size ratio.
So I want to resize (maintaining the ratio) and then cut the image to the size I want.
I can resize with html img property and I can cut with background-image.
How can I do both?
Example:
This image:
Has the size 800x600 pixels and I want to show like an image of 200x100 pixels
With img I can resize the image 200x150px:
<img
style="width: 200px; height: 150px;"
src="http://i.stack.imgur.com/wPh0S.jpg">
That gives me this:
<img style="width: 200px; height: 150px;" src="https://i.stack.imgur.com/wPh0S.jpg">
And with background-image I can cut the image 200x100 pixels.
<div
style="background-image:
url('https://i.stack.imgur.com/wPh0S.jpg');
width:200px;
height:100px;
background-position:center;"> </div>
Gives me:
<div style="background-image:url('https://i.stack.imgur.com/wPh0S.jpg'); width:200px; height:100px; background-position:center;"> </div>
How can I do both?
Resize the image and then cut it the size I want?
You could use a combination of both methods eg.
.crop {
width: 200px;
height: 150px;
overflow: hidden;
}
.crop img {
width: 400px;
height: 300px;
margin: -75px 0 0 -100px;
}
<div class="crop">
<img src="https://i.stack.imgur.com/wPh0S.jpg" alt="Donald Duck">
</div>
You can use negative margin to move the image around within the <div/>.
With CSS3 it's possible to change the size of a background-image with background-size, fulfilling both goals at once.
There are a bunch of examples on css3.info.
Implemented based on your example, using donald_duck_4.jpg. In this case, background-size: cover; is just what you want - it fits the background-image to cover the entire area of the containing <div> and clips the excess (depending on the ratio).
.with-bg-size {
background-image: url('https://i.stack.imgur.com/wPh0S.jpg');
width: 200px;
height: 100px;
background-position: center;
/* Make the background image cover the area of the <div>, and clip the excess */
background-size: cover;
}
<div class="with-bg-size">Donald Duck!</div>
css3 background-image background-size
Did you try to use this?
.centered-and-cropped { object-fit: cover }
I needed to resize image, center (both vertically and horizontally) and than crop it.
I was happy to find, that it could be done in a single css-line.
Check the example here: http://codepen.io/chrisnager/pen/azWWgr/?editors=110
Here is the CSS and HTMLcode from that example:
.centered-and-cropped { object-fit: cover }
<h1>original</h1>
<img height="200" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3174/bear.jpg" alt="Bear">
<h1>object-fit: cover</h1>
<img class="centered-and-cropped" width="200" height="200"
style="border-radius:50%" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3174/bear.jpg" alt="Bear">
.imgContainer {
overflow: hidden;
width: 200px;
height: 100px;
}
.imgContainer img {
width: 200px;
height: 120px;
}
<div class="imgContainer">
<img src="imageSrc" />
</div>
The containing div with essentially crop the image by hiding the overflow.
img {
position: absolute;
clip: rect(0px, 140px, 140px, 0px);
}
<img src="w3css.gif" width="100" height="140" />
Thanks sanchothefat.
I have an improvement to your answer. As crop is very tailored for every image, this definitions should be at the HTML instead of CSS.
<div style="overflow:hidden;">
<img src="img.jpg" alt="" style="margin:-30% 0px -10% 0px;" />
</div>
object-fit may help you, if you're playing with <img> tag
The below code will crop your image for you. You can play around with object-fit
img {
object-fit: cover;
width: 300px;
height: 337px;
}
A small addition to the previous answers that includes object-fit: cover:
object-position
You can alter the alignment of the replaced element's content object within the element's box using the object-position property.
.trimmed-cover {
object-fit: cover;
width: 100%;
height: 177px;
object-position: center 40%;
}
<img class="trimmed-cover" src="http://i.stack.imgur.com/wPh0S.jpg">
img {
position: absolute;
clip: rect(0px,60px,200px,0px);
}
Try using the clip-path property:
The clip-path property lets you clip an element to a basic shape or to
an SVG source.
Note: The clip-path property will replace the deprecated clip
property.
img {
width: 150px;
clip-path: inset(30px 35px);
}
<img src="http://i.stack.imgur.com/wPh0S.jpg">
More examples here.
Live Example:
https://jsfiddle.net/de4Lt57z/
HTML:
<div class="crop">
<img src="example.jpg" alt="..." />
</div>
CSS:
.crop img{
width:400px;
height:300px;
position: absolute;
clip: rect(0px,200px, 150px, 0px);
}
Explanation:
Here image is resized by width and height value of the image. And crop is done by clip property.
For details about clip property follow:
http://tympanus.net/codrops/2013/01/16/understanding-the-css-clip-property/
In the crop class, place the image size that you want to appear:
.crop {
width: 282px;
height: 282px;
overflow: hidden;
}
.crop span.img {
background-position: center;
background-size: cover;
height: 282px;
display: block;
}
The html will look like:
<div class="crop">
<span class="img" style="background-image:url('http://url.to.image/image.jpg');"></span>
</div>
<p class="crop"><a href="http://templatica.com" title="Css Templates">
<img src="img.jpg" alt="css template" /></a></p>
.crop {
float: left;
margin: .5em 10px .5em 0;
overflow: hidden; /* this is important */
position: relative; /* this is important too */
border: 1px solid #ccc;
width: 150px;
height: 90px;
}
.crop img {
position: absolute;
top: -20px;
left: -55px;
}
There are services like Filestack that will do this for you.
They take your image url and allow you to resize it using url parameters. It is pretty easy.
Your image would look like this after resizing to 200x100 but keeping the aspect ratio
The whole url looks like this
https://process.filestackapi.com/AhTgLagciQByzXpFGRI0Az/resize=width:200/crop=d:[0,25,200,100]/https://i.stack.imgur.com/wPh0S.jpg
but the important part is just
resize=width:200/crop=d:[0,25,200,100]
You can put the img tag in a div tag and do both, but I would recommend against scaling images in the browser. It does a lousy job most of the time because browsers have very simplistic scaling algorithms. Better to do your scaling in Photoshop or ImageMagick first, then serve it up to the client nice and pretty.
What I've done is to create a server side script that will resize and crop a picture on the server end so it'll send less data across the interweb.
It's fairly trivial, but if anyone is interested, I can dig up and post the code (asp.net)
<div class="crop">
<img src="image.jpg"/>
</div>
.crop {
width: 200px;
height: 150px;
overflow: hidden;
}
.crop img {
width: 100%;
/*Here you can use margins for accurate positioning of cropped image*/
}
If you are using Bootstrap, try using { background-size: cover;
} for the <div> maybe give the div a class say <div class="example" style=url('../your_image.jpeg');> so it becomes
div.example{
background-size: cover}
I needed to do this recently. I wanted to make a thumbnail-link to a NOAA graph. Since their graph could change at any time, I wanted my thumbnail to change with it. But there's a problem with their graph: it has a huge white border at the top, so if you just scale it to make the thumbnail you end up with extraneous whitespace in the document.
Here's how I solved it:
http://sealevel.info/example_css_scale_and_crop.html
First I needed to do a little bit of arithmetic. The original image from NOAA is 960 × 720 pixels, but the top seventy pixels are a superfluous white border area. I needed a 348 × 172 thumbnail, without the extra border area at the top. That means the desired part of the original image is 720 - 70 = 650 pixels high. I needed to scale that down to 172 pixels, i.e., 172 / 650 = 26.5%. That meant 26.5% of 70 = 19 rows of pixels needed to be deleted from the top of the scaled image.
So…
Set the height = 172 + 19 = 191 pixels:
height=191
Set the bottom margin to -19 pixels (shortening the image to 172 pixels high):
margin-bottom:-19px
Set the top position to -19 pixels (shifting the image up, so that the top 19 pixel rows overflow & are hidden instead of the bottom ones):
top:-19px
The resulting HTML looks like this:
<a href="…" style="display:inline-block;overflow:hidden">
<img width=348 height=191 alt=""
style="border:0;position:relative;margin-bottom:-19px;top:-19px"
src="…"></a>
As you can see, I chose to style the containing <a> tag, but you could style a <div>, instead.
One artifact of this approach is that if you show the borders, the top border will be missing. Since I use border=0 anyhow, that wasn't an issue for me.
You can use Kodem's Image Resize Service. You can resize any image with just a http call. Can be used casually in the browser or used in your production app.
Upload the image somewhere you prefer (S3, imgur etc.)
Plug it into your dedicated API url (from our dashboard)
You can also use a tool called Croppie that can crop images...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link href="https://foliotek.github.io/Croppie/croppie.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"> </script>
<script src="https://foliotek.github.io/Croppie/croppie.js"> </script>
<script src="https://foliotek.github.io/Croppie/bower_components/exif-js/exif.js"> </script>
<style>
#page {
background: #ffffff;
padding: 20px;
margin: 20px;
}
#demo-basic {
width: 600px;
height: 600px;
}
</style>
</head>
<body>
<h1>Crop Image Demo</h1>
<input id="upload" type="file" />
<br />
<div id="page">
<div id="demo-basic"></div>
</div>
<input id="upload-result" type="button" value="Crop Image"/>
<br />
<img id="cropped-result" src=""/>
<script>
var $uploadCrop;
$("#upload").on("change", function () { readFile(this); show(); });
$("#upload-result").on("click", function (ev) {
$uploadCrop.croppie("result", {
type: "canvas",
size: "viewport"
}).then(function (resp) {
$("#cropped-result").attr("src", resp);
});
});
function show() {
$uploadCrop = $("#demo-basic").croppie({
viewport: { width: 100, height: 100 },
boundary: { width: 300, height: 300 },
enableResize: true,
enableOrientation: true,
mouseWheelZoom: 'ctrl',
enableExif: true
});
}
function readFile(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$("#demo-basic").addClass("ready");
$uploadCrop.croppie("bind", {
url: e.target.result
}).then(function () {
console.log("jQuery bind complete");
});
}
reader.readAsDataURL(input.files[0]);
}
else {
alert("Sorry - you're browser doesn't support the FileReader API");
}
}
</script>
</body>
</html>

Is it possible to achieve this zoom & pan effect on a direct image and not a div with a background-image?

I found this codepen showcasing a zoom and pan effect for images. As far as I can tell, the code works by assigning a background-image to each div based on its data-image attribute. Is there any way that I can do this on a direct img tag instead of a div with a background-image?
EDIT: This is the kind of mark-up I'm talking about. A container div with an actual img tag inside of it.
Take a look at the CodePen now.
Think i got it to look kinda like you want it
<div class="tiles">
<div data-scale="1.1" class="product-single__photos tile" id="ProductPhoto">
<img class="photo" src="//cdn.shopify.com/s/files/1/1698/6183/products/bluza_dama_39377a_large.jpg?v=1487178925" alt="Last Skirt" id="ProductPhotoImg">
</div>
</div>
You can play with the margin to adjust the image position
div{
width:100%;
height:200px;
overflow:hidden;
}
img{
width:100%;
margin:0%;
transition:0.5s;
}
img:hover{
width:120%;
margin:-10;
}
<div>
<img src="https://cdn.pixabay.com/photo/2015/07/06/13/58/arlberg-pass-833326_960_720.jpg">
</div>
Absolutely. It would involve giving the elements some CSS:
div.product-single__photos {
position: relative;
overflow: hidden;
}
div.product-single__photos > img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: auto;
}
And have the Javascript manipulate the <img>'s width, height, top and left properties.

better way of floating images in a slider without giving big width to parent

Below is my code for simple slider(it currently does not work because I have not implemented javascript yet). Right now this slider has 2 images(with different resolution ofcourse). What I did is I .sliderContainer I gave width 2520px and to .wrapper I set overflow to hidden. This is something normal I do with slider or carousal.
Now what would happen if I add an additional image that is the number of images become 4 or 5 or 6 or 20 lets say. Then I will go inside the code and keep changing the width of .sliderContainer to make it properly work. Now I need a way where I do not have change the width of .sliderContainer everytime but it should happen as new images are added. New images could come from database from server in json object.
How can I achieve this?
Below is my code.
HTML
<div class="wrapper">
<div class="sliderContainer">
<div class="slider"><img src="http://googleplus-covers.com/covers/nature_balloon_ride.jpg" alt=""></div>
<div class="slider"><img src="http://p1.pichost.me/640/10/1326822.jpg" alt=""></div>
<div class="slider"><img src="http://googleplus-covers.com/covers/coludy_mountains_nature.jpg" alt=""></div>
</div>
</div>
CSS
.sliderContainer {
width: 2520px;
}
.wrapper {
overflow: hidden;
}
.slider {
float: left;
}
Here is JSFIDDLE
Here is an example. Give your image and wrapper width:100% and white-space:nowrap to your wrapper
.wrapper {
width: 100%;
overflow: hidden;
white-space: nowrap;
}
.wrapper img {
width: 100%;
}
<div class="wrapper">
<img src="http://googleplus-covers.com/covers/nature_balloon_ride.jpg">
<img src="http://p1.pichost.me/640/10/1326822.jpg">
<img src="http://googleplus-covers.com/covers/coludy_mountains_nature.jpg">
</div>

Dynamically resize side-by-side images with different dimensions to the same height

I have two images side-by-side within a block-level container with arbitrarily different dimensions (as in, they could be any two images) that I want to dynamically adjust the width of so that the overall height of the two images is the same. I don't think this can be done in CSS from everything I've seen (although possibly with the flexbox model, but I don't know enough about it to say) so I may need a JavaScript solution, but the ones I came up with failed due to either not knowing the overall height of the bounding box, or the fact that adjusting the height of the images affected the height of the bounding box which meant it was constantly re-adjusting itself.
This is an example of arbitrary image heights: https://jsfiddle.net/c6h466xf/
And this is what I'm trying to achieve (although obviously without hard-coding the widths, I want those to be resolved dynamically): https://jsfiddle.net/c6h466xf/4/
This is what I'm starting with (links to JSFiddle need code):
CSS
div.container {
width: 100%;
}
div.container img {
width: 49%;
}
HTML
<div class="container">
<img src="http://i.imgur.com/g0XwGQp.jpg">
<img src="http://i.imgur.com/sFNj4bs.jpg">
</div>
EDIT: I don't want to set a static height on the container element, because that stops it from responding to the width of the overall page, so that the images resize dynamically to each other and responsively to the width of the page, so their total combined width is always (for example) 80% of the page width whatever the viewing device.
If it's responsive, use percentage heights and widths:
html {
height: 100%;
width: 100%;
}
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
div.container {
width: 100%;
height: 100%;
white-space: nowrap;
}
div.container img {
max-height: 100%;
}
<div class="container">
<img src="http://i.imgur.com/g0XwGQp.jpg" />
<img src="http://i.imgur.com/sFNj4bs.jpg" />
</div>
You could set it by height. Give your container div a fixed height.
Here is a solution for you:
div.container {
height:200px;
}
div.container img {
height: 100%;
}
JSFIDDLE
You have 2 other options to get all your images to the same height:
You can place an overflow:hidden on the container div
Or
Clip your images to the same size: http://www.w3schools.com/cssref/pr_pos_clip.asp
Set a class for your images:
<img src="http://i.imgur.com/g0XwGQp.jpg" class="example" >
<img src="http://i.imgur.com/sFNj4bs.jpg" class="example" >
Then you need to set the height of your container:
div.container {
height:200px;
}
In your JavaScript:
var yourImg = document.getElementsByClassName("example");
if(yourImg && yourImg.style) {
yourImg.style.height = '100%';
yourImg.style.float = 'left';
}
This should be a simple code, check the following:
HTML code:
<table class="Table">
<tr>
<td><img src="images/1.jpg"/></td>
<td><img src="images/2.jpg"/></td>
<td><img src="images/3.jpg"/></td>
<td><img src="images/4.jpg"/></td>
</tr>
</table>
CSS:
table { width: 100%; }
table img {
max-width: 100%; max-height: 100%; padding-left: 5px; border: none;
}

CSS position change on image next to it

So, I have the same image that I need to overlap each other. The first one as you can see has an z-index:1 and the others of 0. But, as the images keep repeating I have to keep creating a new style to make the next one 115px to the right. Is there a css pseudo method to automate this or do I have to revert to using jquery or js to bump it to the right?
<style>
img.overlap{z-index:1;position:absolute;left:670px;}
img.underlap{z-index:0;position:absolute; left:785px;}
</style>
<div class="span12">
<img src="img/blue_btn.png" alt="Home" class="overlap"/>
<img src="img/blue_btn.png" alt="About" class="underlap"/>
<img src="img/blue_btn.png" alt="Services" class="underlap"/>
<img src="img/blue_btn.png" alt="Portfolio" class="underlap"/>
<img src="img/blue_btn.png" alt="Blog" class="underlap"/>
<img src="img/blue_btn.png" alt="Contact" class="underlap"/>
</div>
UPDATE: I was cropping the image as I read this post as I knew that it would be hard to visualize. Here is the nav area. I have cropped the first one and I will repeat them and later change the alpha with jquery.
http://weslice.com/images/nav_complete.jpg
You should try using float and margins instead of absolute positioning.
http://www.w3schools.com/css/css_float.asp
How about using display : inline-block to get your elements to sit next to each-other, then use margin : -*px to overlap the elements:
.span12 a {
display : inline-block;
margin : 0 0 0 -20px;/*this margin is responsible for the overlap between elements*/
/*IE 6&7 Compatibility*/
*display : inline;/*only read by IE7*/
zoom : 1;/*give the element the `hasLayout` property since you can't give it to an element directly*/
_height : 50px;/*only read by IE6, but is necessary to specify a height for IE6*/
}
Here is a demo: http://jsfiddle.net/WJKS5/2/
Update
To stack the element from left to right instead of right to left:
.span12 a {
float : right;
margin : 0 -10px 0 0;/*this margin is responsible for the overlap between elements*/
}
Here is a demo: http://jsfiddle.net/WJKS5/4/
I think this fiddle http://jsfiddle.net/2vUzp/9/ achieves the effect without the need for classes (though it does reverse the order of the menu in the html, but not in what is displayed to the average user). After looking at your sample image, you may not want the "hover" effect in my example, but that can be removed.
CSS
.span12 {
float: left;
}
.span12 a {
position: relative;
margin-right: -30px;
display: block;
float: right;
}
.span12 a:first-child {
margin-right: 0;
}
.span12 a:hover {
z-index: 1;
}
.span12 img { /*for demo*/
display: block;
width: 100px;
height: 20px;
border: 1px solid blue;
background-color: cyan;
}
HTML
<div class="span12">
<img src="img/blue_btn.png" alt="Contact"/>
<img src="img/blue_btn.png" alt="Blog"/>
<img src="img/blue_btn.png" alt="Portfolio"/>
<img src="img/blue_btn.png" alt="Services"/>
<img src="img/blue_btn.png" alt="About" />
<img src="img/blue_btn.png" alt="Home" />
</div>
Since you are trying to accomplish an overlap, floating's probably not going to work. I would recommend you use CSS sibling selectors and write rules specifically for 'img', 'img + img', 'img + img + img', etc. that would increase incrementally. I think that should be the only pure CSS way around it. Doing this with JavaScript would be a breeze.

Categories