Cropping the top 10% of an image using CSS? - css

How to crop the top of an image has already been described in this question. However, I am trying to crop an image by a percentage when the image dimensions are not known ahead of time. The container's resulting height should then be dependent on the size of the image.
Using the following, I can crop the top of an image, but it requires manually specifying the amount of the image to show in pixels. Is there a way I can specify I want to crop the top 10% of the image without knowing the image size ahead of time?
.container {
overflow: hidden;
position: relative;
height: 370px;
}
.container img {
position: absolute;
margin-left: auto;
margin-right: auto;
bottom: 0;
left: 0;
right: 0;
}
<div class="container">
<img class="img" src="http://placekitten.com/400/500" />
</div>

Here is an idea that rely on scale. You keep the image in-flow (don't use position:absolute) then you scale the container by 0.9 which is 90% of the total height then you scale the image by 1.1 to keep it's original size. This will trim the image by 10% but since transform is only a visual effect you may have space at the top or the bottom of the container (based on the transform-origin)
.container {
overflow: hidden;
outline:1px solid red;
display:inline-block;
}
.container img {
display:block;
}
.cut {
transform:scaleY(0.9);
transform-origin:top; /* The extra space will be on the bottom*/
}
.cut img {
transform:scaleY(1.1);
transform-origin:bottom; /* This should be bottom to cut the top*/
}
<div class="container">
<img class="img" src="http://placekitten.com/300/200" >
</div>
<div class="container cut">
<img class="img" src="http://placekitten.com/300/200" >
</div>
To be more precise we can consider calc() like below:
.container {
overflow: hidden;
outline:1px solid red;
display:inline-block;
}
.container img {
display:block;
}
.cut {
transform:scaleY(0.9);
transform-origin:top; /* The extra space will be on the bottom*/
}
.cut img {
transform:scaleY(calc(1/0.9));
transform-origin:bottom; /* This should be bottom to cut the top*/
}
<div class="container">
<img class="img" src="http://placekitten.com/300/200" >
</div>
<div class="container cut">
<img class="img" src="http://placekitten.com/300/200" >
</div>

I think the best approach to this without Javascript would be to translate the image up a certain percent, then scale it to fill the original height of the container. Anything else will leave a gap at the bottom.
.img_container img {
transform: translateY(-50%) scale(2);
}
https://jsfiddle.net/amoliski/n4ojdzyr/

This should do the trick, using translateY (got that from How can I get the height of an element using css only)
As you can see, the .container does not have a hardcoded height, however, it will load with the original image height, which is 500px, even though the image is loading as 450px (500px - 10%)
.container {
overflow: hidden;
position: relative;
}
.container img {
margin-left: auto;
margin-right: auto;
bottom: 0;
left: 0;
right: 0;
transform: translateY(-10%);
}
<div class="container">
<img class="img" src="http://placekitten.com/400/500" />
</div>

You can do this with a little bit of JavaScript (I've inlined it for simplicity's sake but you could move it to it's own function)
<div class="container">
<img class="img" src="http://placekitten.com/400/500" onload="javascript:this.parentElement.style.height = (this.height * 0.9)+'px';" />
</div>
Here's a working JSfiddle.

An alternative would be to use the top CSS property in a negative fashion on a relative image like the snippet below. This works for an image of an arbitary width and height. Just adjust your top value, accordingly.
html,body{ height:100%; margin:0; padding:0; }
.container {
overflow: hidden;
position: relative;
height: 100%;
width: 100%;
display:flex;
margin-bottom: -10%;
align-items:center;
justify-content:center;
}
.container img {
position: relative;
bottom: 0;
left: 0;
height: 100%;
top: -10%;
right: 0;
}
<div class="container">
<img class="img" src="http://placekitten.com/400/500" />
</div>
To remove the extra bottom margin, just subtract the margin-bottom equal to the amount you subtracted from the top. Here it is margin-bottom: -10%;
Adjust the top value according to your dynamic images. Also note, I added height:100% to your container so you can see the full image but the top part is cropped. I used flex for centering. Test for another image but this time, it is cropped 50% from the top
html,body{ height:100%; margin:0; padding:0; }
.container {
overflow: hidden;
position: relative;
height: 100%;
width: 100%;
margin-bottom: -50%;
display:flex;
align-items:center;
justify-content:center;
}
.container img {
position: relative;
bottom: 0;
left: 0;
height: 100%;
top: -50%;
right: 0;
}
<div class="container">
<img class="img" src="https://www.fujifilm.com/products/digital_cameras/x/fujifilm_x_t3/sample_images/img/index/ff_x_t3_002.JPG" />
</div>

Related

Absolute element moving away from image

Can I somehow make the absolute element stay at the same position all the time even when the parent(relative) image is adjusting its size to screen? At the moment I am using px to use position of elements, its fine on huge screen, but whenever the image gets smaller the absolute elements wont stick to the same position. Also I tried using <img></img> and put elements inside it and make the img as relative, but I think these tags dont work.
.img {
width: 100%;
height: auto;
}
.container {
position: relative;
}
.container > p {
position: absolute;
left: 300px;
bottom: 200px;
}
<div class="container">
<img src="https://pngimg.com/uploads/surfing/surfing_PNG9721.png" class="img">
<p>Im absolute
</p>
</div>
use percentage and for font-size use clamp()
.img {
width: 100%;
height: auto;
}
.container {
position: relative;
}
.container > p {
position: absolute;
left: 22%;
bottom: 48%;
color : white;
font-size: clamp(5px,2vw,3rem);
}
<div class="container">
<img src="https://pngimg.com/uploads/surfing/surfing_PNG9721.png" class="img">
<p>Im absolute
</p>
</div>
Try removing the "position: relative;" of the container. Your p tag is absolute respect the container because of that. Removing relative in container, the absolute is refered to the document.
.img {
width: 100%;
height: auto;
}
.container > p {
position: absolute;
left: 300px;
bottom: 200px;
}
<div class="container">
<img src="https://pngimg.com/uploads/surfing/surfing_PNG9721.png" class="img">
<p>Im absolute
</p>
</div>

Responsive device with image overlay

I'm looking to overlay an image of some content on top of an iPhone, that can scale responsively and fit/remain within the screen area of the device. I haven't been able to find a good tutorial on how I could accomplish this effect. Here is what I've tried so far...
http://jsfiddle.net/mcasavant/VLBAE/1/
<div class="large-5 columns">
<img src="http://www.ikonet.com/en/visuelmobile/images/iphone4.png" alt="" />
<img class="inner" src="http://old.mobilecrunch.com/wp-content/uploads/2010/01/iphone-4-os.jpg" alt="" />
.large-5 {
width: 80%;
position: relative;
}
img {
max-width: 100%;
}
.columns:first-child {
float: left;
}
.inner {
position: absolute;
top: 17%;
left: 1.3%;
padding: 0 12%;
max-width: 76%;
}
.columns {
padding-left: 15px;
padding-right: 15px;
}
However it scales weirdly, and kind of juts out on the left a little. Certainly not very appealing. Ideas?
May I suggest placing the wrapping image as background of the content image instead?
It might need some tweaking but I think it does the job.
http://jsfiddle.net/xC446/7/
<div class="wrapper">
<img src="http://old.mobilecrunch.com/wp-content/uploads/2010/01/iphone-4-os.jpg" alt="" />
</div>
.wrapper { width:200px}
img {
background-image : url('http://www.ikonet.com/en/visuelmobile/images/iphone4.png');
background-repeat : no-repeat;
background-size : 100% 100%;
width : 100%;
height : auto;
padding : 35.5% 7% 46% 8%;
box-sizing :border-box;
-moz-box-sizing:border-box;
}

How to position an image of different size using css?

I have two images of different width and height that need to be positioned bottom centered within the image box. Here is the HTML and CSS example.
<div class="box">
<div class='image'>
<img alt="" src="image.jpg"/>
</div>
</div>
.box {
max-width: 970px;
height: 440px;
}
.box img {
max-width: 100%;
position: absolute;
bottom: 8px;
margin-left: auto;
margin-right: auto;
}
This code works fine for a large image of exact width and height. But when a smaller image is placed within image box, that image is centered bottom right. How can I make both images center bottom?
Thanks for anyone's help!
Here you go... I'll try to explain as we go, but short answer, a fiddle
.box {
/* Just so I could see the parent */
background-color: #bada55;
max-width: 970px;
height: 440px;
/* Needed to make this element positional (so it will contain the absolutely positioned child */
position: relative;
/* Yep, center wasn't necessary here... */
}
.box .image { /* move this to the image wrapper */
position: absolute;
bottom: 8px;
/* Force full width */
left: 0;
right: 0;
/* Center contents (the image) */
text-align: center;
}
img {
max-width: 100%;
}
I found this semantic trick to work pretty well (without any absolute positions)
.box {
margin: 0;
text-align: center;
max-width: 970px;
height: 440px;
border:2px solid red;
}
.box .something-semantic {
display: table;
width: 100%;
height: 100%;
}
.box .something-else-semantic {
display: table-cell;
text-align: center;
vertical-align: bottom;
}
html
<div class="box">
<div class="something-semantic">
<div class="something-else-semantic">
<img src="" width="50" height="40"/>
<img src="" width="120" height="70"/>
</div>
</div>
</div>
fiddle here.

Horizontal center dynamic image in div with absolute position

I have looked all over the web for this answer but it seems to me that in order to horizontally center an image in div with absolute position, I need to know the dimensions of the image, but it's dynamic.
Here is my html:
<header>
<div id="elogo">
<img src="http://www.ftiweb.com/images/eStore/eStore_wht50.png">
</div>
<div id="nav">TOUR | MENU</div>
</header>
<div id="content">
<img class="ipad" src="http://ftiweb.com/images/eStore/Ipad_hand.png">
</div>
<footer>
<div id="foot">© FTIeStore 2013 • Privacy Policy</div>
</footer>
and here is the .css I'm using:
#content {
width: 70%;
height: 80%;
border: 1px solid red;
position: absolute;
bottom: 0px;
left: 50%;
margin-left: -35%;
display: table-cell;
img.ipad {
max-width: 100%;
max-height: 100%;
position: absolute;
bottom: 0px;
display: block;
}
The goal is just to have the image stay at the bottom/center of the page and re-size to fit the browser window. If I'm over-complicating this, please feel free to suggest an alternative.
Here is a link to a js.fiddle:
bottom-centered img - js.fiddle
If you want it to be absolute position do it like this:
http://jsbin.com/aveped/1/edit
img {
width:20%;
display:block;
position:absolute;
left:0;
right:0;
bottom:0;
margin:auto;
}
The parent needs to have position relative, or it will be positioned against the body.
You dont need width for this, I just included width because my image is so big.
left = center position - half the width of the image
img {
position: absolute;
bottom: 0;
left: 50%; /*half the container width*/
margin-left: -250px; /*half the width of the image*/
}

Vertically and horizontally centering text within a div

I have a div that comprises a graphic background overlaid with text. I want to center this element horizontally and vertically. But I can't get the text to center vertically. So far, I have the following code:
<div id="step">
<div id="background">
<img src="buttonbackground.png" class="stretch" alt="" />
</div>
<div>
<h3>some text</h3>
</div>
</div>
In the CSS:
#background {
width: 100%;
height: 100%;
position: absolute;
left: 0px;
z-index: -1;
}
#step {
text-align:center;
color:white;
}
.stretch {
width:200px;
height:40px;
}
Using the table-cell/vertical-align technique I've seen often referenced elsewhere doesn't quite work.
Given that it's an H3 i'm assuming it's a heading so it's probably gonna be one line of text. If that's the case just set the line-heightof the h3to the height of the container.
If instead it's a paragraph you can do this:
#centeredDiv {
position:absolute;
top: 50%;
left: 50%
margin-top:-20px ;(half the height of the container)
margin-left: -100px; (half the width of the container)
}
Don't mix pixels with percentages.
Try:
#step {
text-align: center;
vertical-align: center;
color: white;
height: 40px;
}
EDIT:
Alternatively, you could try explicitly setting the height of #background to 40px instead of 100%. It should achieve the same effect.

Resources