http://jsfiddle.net/6rwUC/3/
As you can see on the jsfiddle link, I'm trying to create one layout for image previews. I would like to have resized images keeping original ratio, just cut off what overlays the parent div. How can I do this ?
.image-column {
background: #cecece;
width: 100%;
height: 180px;
overflow: hidden;}
.image-column a img {
position:relative;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;}
If CSS3 is an option, you could use transform with a negative translate of -50% horizontally and vertically, while the element is positioned with left: 50% and top: 50% as follows:
.image-column a img {
position:relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
WORKING DEMO.
Update
According to your update:
I would like to have resized images keeping original ratio, just cut
off what overlays the parent div.
The only pure CSS solution is using the images as background-image for the <a> elements, while you're using background-size: cover;:
<div class="image-column">
</div>
.image-column a {
display: block;
height: 100%;
background: url(http://domain.com/path/to/image.jpg) 50% 50% no-repeat;
background-size: cover;
}
However, if the height/width ratio of the box is lower than the image, you can use the old answer including max-width: 100%; for the image: Online Demo.
And if the height/width ratio of the box is higher than the image, you need to use max-height: 100% for the image: Online Demo.
For dynamic calculation, you'll need to use JavaScript. Here is a similar topic on SO.
Try this out: http://jsfiddle.net/6rwUC/4/
I've simply added max-width: 100%;
Related
I am trying to make a showcase section for a web page. It consists of a div with a (responsive) background image and a header that would be centered horizontally and vertically over this image. I've managed to get the image in and have it be responsive, and I've got the header centered, but my problem arises when the window size becomes smaller.
I'm using position: absolute, the top property, and transform to have it be centered, but the top property only works when height is specified in the parent container. However, when the window shrinks to the point where the image begins to shrink to below its original height, the text does not stay vertically centered, only horizontally (since I'm going off of the original height for top (800px)).
I can't just change the height with a media query since the image size is changing constantly and I can't not use height because then the top property would not work at all, so I'm a bit confused with how to get around this.
Here are the relevant sections of my code:
HTML:
<section class="showcase">
<div class="showcase-container">
<h1 class="centered"><span class="highlight">BR</span> Architects</h1>
</div>
</section>
CSS:
.container {
width: 80%;
margin: 0 auto;
padding: 0;
position: relative;
height: auto;
}
.showcase-container {
width: 80%;
margin: 0 auto;
padding: 0;
position: relative;
height: 800px;
}
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
I might just guess because I don't know how does this really look, but I assumed few things and in a result instead of background image I would just use normal image, make it blocky and display div over it, you will have height preserved in any size, take a look:
.showcase-container {
width: 80%;
margin: 0 auto;
padding: 0;
position: relative;
}
.showcase-container img {
display: block;
width: 100%;
height: auto;
margin: 0 auto;
max-width: 1200px;
}
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #fff;
border-radius: 5px;
padding: 10px 20px;
}
<section class="showcase">
<div class="showcase-container">
<img src="https://source.unsplash.com/random/1200x700" alt="">
<h1 class="centered"><span class="highlight">BR</span> Architects</h1>
</div>
</section>
See MDN's <figcaption> documentation.
<figure>
<img src="/media/examples/hamster.jpg" alt="a cute hamster" />
<figcaption>Hamster by Ricky Kharawala on Unsplash</figcaption>
</figure>
If I'm understanding this right, you're saying you don't need to worry about the image always maintaining an 800px height, you just want the h1 to remain centered. In that case, it's really simple.
Just add your image as a background, setting the background-size to cover, then make sure the container is never larger than the window by setting its height to 100vh, but never taller than 800px by setting its max-height.
.showcase-container {
/* your styles here */
background-image: url('yourimage.jpg');
background-size: cover;
height: 100vh;
max-height: 800px;
}
OR if you need it to be vertically centered in the window independently of the container, you can always change top: 50%; to top: 50vh; and position relative to the body.
It appears that when scaling down an element which previously did not fit in its container, margin: 0 auto will no longer center the element within its parent (note that using transform-origin: center center does not solve this). This is because the auto margins seem to apply before the scaling rather than after (I expected the latter).
While playing with this, I eventually managed to center the element within its container, but only using absolute positioning:
position: absolute;
transform: translateX(-50%) scale(0.5, 0.5);
left: 50%;
This is a very popular technique, but in this particular case, it is important to place the translateX function before the scale function, as these are executed in the defined order.
Following is a snippet of code to illustrate the issue (also on CodePen: https://codepen.io/liranh85/pen/qVewQp)
.container {
border: 3px solid black;
width: 500px;
height: 200px;
margin: 0 auto;
position: relative;
}
.scaled {
background-color: blue;
width: 600px;
/* width: 400px; */
height: 100%;
transform: scale(0.5, 0.5);
/* transform: translateX(-50%) scale(0.5, 0.5); */
margin: 0 auto;
/* position: absolute;
left: 50%; */
}
<div class="container">
<div class="scaled"></div>
</div>
Notice that:
The element is not centered using auto margins when its width is bigger than its container's.
When giving the scaled element a width smaller than its container, it will remain centered after scaling (e.g. try using width: 400px).
When using absolute positioning, as mentioned above, it is possible to center the element.
I'm wondering:
Has anyone else run into this issue?
Is this the best way to center such an element?
Am I correct to say the auto margin cannot be used to center such an element?
You need to use
transform-origin: center;
Take a look at some of the docs on this
https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin
Your suspicions are correct: when the element is too wide to fit within its parent, margin: 0 auto will not horizontally center the element. It will instead cause the element to overflow at the far right edge of its parent.
You can center your element properly by using translateX(-50%) before you scale the element, on top of positioning the element absolutely and using left: 50%. The reason why this works is because by absolutely positioning your child element, you are taking it out of the layout flow of the parent and therefore can position it in the horizontal center of the parent.
Note: This solution assumes that you are using height: 100%. If vertical centering of a non-full-height element is required, update the styles so that you're using translate(-50%, -50% and top: 50%; left: 50%.
Here is a proof-of-concept example based on your code you've provided:
.container {
border: 3px solid black;
width: 500px;
height: 200px;
margin: 0 auto;
position: relative;
}
.scaled {
background-color: blue;
width: 600px;
height: 100%;
transform: translateX(-50%) scale(0.5, 0.5);
position: absolute;
left: 50%;
}
<div class="container">
<div class="scaled"></div>
</div>
Hi I have a fluid container that is based on screen height and width in my website. I would like to have an image fill the container at all times as it expands in any direction based on screen size. The images used will vary in size and aspect ratio.
I have made an attempt with html and css below:
div {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, 0);
height: 80vh;
width: 80%;
background-color: red;
position: relative;
overflow: hidden;
}
img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-height: 100%;
min-width: 100%;
width: auto;
height: auto;
/* max-width: 100%; // If used Image needs to be tall enough to fill div */
/* max-height: 100%; // If used Image needs to be wide enough to fill div */
}
<div>
<img src="http://i.imgur.com/kOY2G57.jpg">
</div>
Without max-height and max-width, this works well if the img is smaller than the container but does not work if the images come out larger as they come out in their natural size and get cropped.
jsfiddle example
Is it possible to accomplish this task with just pure css?
Update
I also would like to avoid using background images as a solution and see if this is possible with just the img tag in place at the dom so as to avoid programing the img tags if possible.
Instead of using the <img> tag you can just give the <div> a background image with background-size: cover property. The background image will maintain the aspect ratio while covering the entire div container at all times.
<div></div>
div {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, 0);
height: 80vh;
width: 80%;
background: red url("http://i.imgur.com/kOY2G57.jpg") center center;
background-size: cover;
position: relative;
overflow: hidden;
}
Use object-fit for images to achieve the same result akin to background-size cover, contain:
.imgFit {
object-fit: cover; /* cover, contain */
display: block;
width: 100%;
height: 100%;
}
Use like:
<img class="imgFit" src="" alt="">
I want to center an full screen image vertically.
I can't define image in CSS because the image depends on URL parameters.
<div>
<img src="photo.jpg">
</div>
div {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
If I define my image CSS like this:
div img {
width: 100%;
height: 100%;
}
My image will stretch and be deformed in height to fit on screen.
If I define my image CSS like this (just without defining height):
div img {
width: 100%;
}
My image will not stretch/be deformed, but it will start at top: 0 of the image. What I want is the image to be centered vertically and the overflow of it's height to be hidden.
Basically I want the same behaviour I would get in CSS with background centered:
background: url(photo.jpg) no-repeat center;
background-size: cover;
EDIT: I forgot to mention that CSS object-fit: cover works on this but I'm looking for a more cross-browser solution since this property does not work in every browsers.
Try this css
div {
position: fixed;
top: 50%;
left: 0;
width: 100%;
height: 100%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
EDIT
also its a bad practice to give the image both height and width. this will always override the aspect ratio of the image and stretch it in some direction.
use this for img
div img {
width: 100%;
}
This will first position the division 50% form top. i.e. the image will now have its topmost part at 50% of the page height then the translate property will move the image upward by 50% of its height essentially centering the image
How about this:
div {
position:fixed;
top:0;
left:0;
width: 100px;
height: 100px;
border:1px solid red;
text-align:center;
line-height:100px;
overflow:hidden;
}
img {
vertical-align:middle;
border:1px solid black;
}
<div>
<img src="https://www.smallbusinesssaturdayuk.com/Images/Small-Business-Saturday-UK-Google-Plus.gif">
</div>
If you allow js, you can do this (assuming the image has id 'img'):
#img {
width: 100%;
position: absolute;
top: 50%;
}
A negative margin top needs to be set using js or jQuery (on resize):
$('#img').css('margin-top', '-'+($('#img').height()/2)+'px');
I have a small block and image width larger than the block. I want to block center equals image center.
Image center and block center must be on 1 vertical line. And i want to see only central part of image.
Instead of use negative margin on your image, you can use the transform property
.img-container{
width:100px;
overflow:hidden;
}
.img-container img{
transform: translateX(-50%);
}
https://jsfiddle.net/7gk07eLm/2/
you can do this way
html
<div class="img-container">
</div>
css:
enter code here
.img-container{
max-width: 100px;
min-height: 580px;
background-repeat: no-repeat;
background-position: center;
background-image: url(http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701);
}
I can think of two ways of doing this:
Instead of <img> tag you can use background css property with background-position set to center, and with background-size set to cover, on <div>; in your case it's going to be something like this:
.img-container {
width: 100px;
height: 500px;
background: no-repeat center /cover url("path_to_your_image");
}
Height property must be set!
If you want to stick with <img> tag it's going to look something like this:
.img-container {
width: 100px;
height: 500px;
overflow: hidden;
position: relative;
}
.img-container img {
position: absolute;
right: -1000%;
left: -1000%;
top: -1000%;
bottom: -1000%;
margin: auto;
}
The crazy numbers in right, left, top and bottom positions for image are because of small size of parent <div> and big size of image itself - the percentage is based on width and height of parent block, so in this case right: 100%; will be 100px, that's why you need bigger numbers for positioning a much larger image in a smaller parent block.
Values can be tweaked, of course, as long as they are equal image will be centered.
In both cases height must be set, or it won't work!