Create Centered Circles from Rectangles Images using Bootstrap - html

I have images being passed dynamically to the UI and they can sent as any size size. I then need to scale them to specific sizes depending on which img tag that image is going to be displayed in. These images need to be circles of a statically set size, but not ovals and when they are cropped I want the circle to come from the center of my image.
I have created a circular image using boostrap's img-circle:
<img class="img-circle" src="image.jpg" width="117px" height="117px"/>
I have many of similar images of various sizes being layed out using:
<div class="row" style="margin: -40px 10px 30px">
This is working, except my images are ending up stretched to fit the circle rather than just cropping from it. Is there any simple way I can cause them to crop vs stretch?
I'm hoping I can do this just using my img tag, as using something with "background-image" seems to mess up my layout.
Added a fiddle:
http://jsfiddle.net/jgt1qy7y/1/

You should enclose your image in a parent div.
The only thing .img-circle does is apply border-radius: 50%; It will inherit the width and the height of the chosen element. If those are not equal it will be an oval. In that case you will have to define sizes but then the images will get distorted. So that's why you need a parent div. To set the width and the height, and not distort the image.
.img-circle {
border-radius: 50%;
position: relative;
height: 117px;
width: 117px;
overflow: hidden;
float: left;
margin-right: 10px;
}
.img-circle.hor img {
position: absolute;
left: 50%;
width: auto;
height: 117px;
transform: translateX(-50%);
}
.img-circle.vert img {
position: absolute;
top: 50%;
width: 117px;
height: auto;
transform: translateY(-50%);
}
<div class="img-circle hor">
<img src="http://placehold.it/350x150" />
</div>
<div class="img-circle vert">
<img src="http://placehold.it/150x350" />
</div>

Right, as far as I can answer from the information you've provided, you're setting the image tag to have 117px in both height and width. This is the IMG tag you're changing, and so every image will be stretched TO that specification.
So, you have two options:
1) You can either set a specific width or height and allow the circle to be auto width or height, e.g
.img-circle{
width:auto;
height:auto;
width:117px;
max-height:117px;
}
On this I have set a max height of 117px so that HUGE long ones don't go overboard, but this will make them tiny in the circle http://jsfiddle.net/jgt1qy7y/8/
Or, secondly, you could create a DIV with fixed width 117px by 117px (I'm assuming you're using this as profile pictures or something?), then dynamically modify the style of the DIV to add a background image then configure that in your CSS:
.img-circle{
width:117px;
height:117px;
}
For your div. Then, you can dynamically output the URL of the image into your STYLE of the div
<div class="img-circle" style="background-image:url('echo your url here');"></div>
You can then style the background image by adding CSS to your .img-circle:
.img-circle{
background-size:contain/cover;
background-repeat:no-repeat;
backgrund-position:50% 50%;
}
You'll have to check out cropping an image in javascript if you want the image to fit exactly how you want it, but you get the jist.
Disclaimer: I've never properly learned CSS from websites, I've picked it up as I've gone along... Sorry if this is written badly!

Related

How to align text to image that is auto scaled with object-fit: contain

I have a viewport that takes up about 75% of the screen and I fit single images of varying aspect ratios into it using the object-fit: contain css. Above the image I have text labels for the file name & type. I want to keep these aligned to start at the left most edge of the image and end at the right most edge. I could do this easily before by aligning them to the <img> tag.
One side effect of using object-fit: contain is that the <img> element is bigger than the viewable picture, so when I try to align text to the <img> it can appear that the text is floating off of the image.
How can I align the text to the viewable image, when the img tag is expanded to fit the whole viewport but the actual picture is autoscaled inside the img tag using object-fit: contain?
The solution is very much dependent on markup, fixed widths and/or heights etc.
Assuming you don't know their width/height in advance, you'll need a script, as in below sample.
Updated: I added the opacity so the image and text display's at the same time.
If you do know them, you still need to work out a bunch of CSS animation rules, covering their ratio and animation setting to make it look good, which can be done, though it will take some work. In the end of this answer is a sample how to set an element size based on the same way fit-content calculate size.
document.querySelector('img').addEventListener('load', function(e) {
document.querySelector('.image-text').style.cssText = 'width: ' + e.target.width +'px; opacity: 1;';
})
.image-wrap {
position: relative;
height: 200px;
overflow: hidden;
border: 1px dashed gray;
margin-bottom: 10px;
}
.image-wrap img { /* fit-content replacement */
position: relative;
max-height: 100%;
max-width: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
div.image-text {
opacity: 0;
margin: 0 auto;
}
<div class="image-text">Some text we want to size and break at the same width as the image</div>
<div class="image-wrap">
<img src="http://placehold.it/500x400" alt="some image here" />
</div>
Here is another post about getting an images both natural and scaled size:
object-fit: get resulting dimensions

Resizing an image so that it fits in it's container

I have a div profile_pic which has the following CSS:
#profile_pic{
position:absolute;
border:1px solid #E1E3E4;
left:25px;
top: 25px;
width: 200px;
height: 200px;
}
Since profile picture for my application can be any image (of any size), the div or image, should be flexible to adapt to one another. I have tested a profile picture with the dimensions of 300px width and 300px height and the image renders perfectly in the the div. However, when I upload a picture with say, 550px width and 400px width the image is appearing "squashed" which is understandable.
There are two options, 1. resizing the image so that the whole image appears in the div and 2. cropping the image so that the image adapts to the div size. I do not mind adopting either of these approaches but I am unable to implement how these approaches in code.
I have tried to set:
#profile_pic {width: 50%}
#profile_pic img {width:100%}
But it just does not work. How can I get the div (or image) to always fit in the div's size without the image losing it's quality?
You could just add background-size:contain; to the div that has the image (assuming you are setting the background image the image you want.
losing quality is another thing, scaling say a 50x50px image to 100x100 is going to lose quality, so it would probably be best to set a minimum size the profile picture can be.
You may set max-width and max-height in order to resize image to fit inside the box without overflow, add line-height and text align to center image in case it has not the same box ratio.
#profile_pic,
.profile_pic2 {
position: absolute;
border: 1px solid #E1E3E4;
left: 25px;
top: 25px;
width: 200px;
height: 200px;
line-height: 197px;
/* since image is the one and single child */
text-align: center;
border: solid;
/*demo purpose */
}
.profile_pic2 {
left: 250px;
}
.profile_pic2 +.profile_pic2 {
left: 450px;
}
#profile_pic img, .profile_pic2 img {
max-width: 100%;
max-height: 100%;
vertical-align: middle;
/* set on middle baseline setted at 200px */
}
<div id="profile_pic">
<img src="//lorempixel.com/640/480">
</div>
<div class="profile_pic2">
<img src="//lorempixel.com/480/640">
</div>
<div class="profile_pic2">
<img src="//lorempixel.com/480/480">
</div>

Fill a div with an image respecting aspect ratio

Is it possible to fill a div with an image such that at least one image dimension is 100% and the other dimension is either wider or equal size as the div, whilst respecting the image's aspect ratio.
An example could use the classes wide and tall like this:
<div class="tall">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Klaproos.jpg/266px-Klaproos.jpg"/>
</div>
<div class="wide">
<img src="https://groenevrijdag.files.wordpress.com/2013/11/klaproos2.jpg"/>
</div>
div {
width: 400px; height: 400px;
display: block;
overflow: hidden;
border-radius: 50%;
display: inline-block;
}
div.tall img { width: 100%; margin-top: -50%; }
div.wide img { height: 100%; margin-left: -50%; }
https://jsfiddle.net/7tuod6vu/
I'm looking for a pure HTML+CSS solution which works for responsive rectangular (not necessarily square) divs. For this particular reason, Javascript would be a pain as one would need to determine whether the width or height should be 100% on every resize. Server side wouldn't even be an option.
Does a pure HTML+CSS solution exist for this?
EDIT Should have been clear about this from the beginning, sorry about that :( I'm not looking for the background-image solution, since it does not allow base64-inhtml representation of images. Moreover, I think background-image's are semantically different from <img>s.
Consider using the CSS object-fit property.
5.5. Sizing Objects: the object-fit
property
The object-fit property specifies how the contents of a replaced
element should be fitted to the box established by its used height and
width.
Here are two of the values:
cover
The replaced content is sized to maintain its aspect ratio while
filling the element's entire content box.
contain
The replaced content is sized to maintain its aspect ratio while
fitting within the element's content box.
So, with cover the image retains its aspect ratio and covers all available space. Of course, this means that much of an image may be cropped off-screen.
With contain the aspect ratio is also maintained, but the image scales to fit within the box. This means that an image may have whitespace on the left and right, or top and bottom.
Browser Compatibility
As of this writing, object-fit is not supported by Internet Explorer. For a workaround see:
Neat trick for CSS object-fit fallback on Edge (and other browsers)
fitie - An object-fit polyfill for Internet Explorer
object-fit-images - Adds support for object-fit on IE9, IE10, IE11, Edge and other old browsers
Polyfill (mostly IE) for CSS object-fit property to fill-in/fit-in images into containers.
More information
MDN object-fit property
CSS-Tricks object-fit property
object-fit browser support # caniuse.com
Here is the solution without using background images and with HTML and CSS only: http://codepen.io/anon/pen/JGGObQ
(change overflow to visible in the .container1 rule to see the full pictures. The numbers in them are their original size in pixels.)
It uses position: absolute on the images, and depending on the format (two classes, as suggested by yourself) a top or left of 50% that moves the position reference into the (horizontal or vertical) center, and a transform : translate setting that moves the position reference point of the image back from that center by 50% of their own size, which results in centering:
.container1 {
position: relative;
float: left;
margin-right: 50px;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
border: 1px solid red;
}
img.landscape {
position: absolute;
width: auto;
height: 100%;
transform: translate(-50%, 0);
left: 50%;
}
img.portrait {
position: absolute;
width: 100%;
height: auto;
transform: translate(0, -50%);
top: 50%;
}
<div class="container1">
<img src="http://placehold.it/750x500/09d/fff" class="landscape">
</div>
<div class="container1">
<img src="http://placehold.it/600x900/0d9/fff" class="portrait">
</div>
This is not the exact solution, but it could be an implementation that you could try to make your code work. Here is an example:
As you can't predict the aspect ratio of the image here is what I would do:
HTML:
Set the div tag to 'fill':
<div class="fill"></div>
CSS:
This will place your image as the background, and stretch it to fit the div size without distortion.
.fill {
overflow: hidden;
background-size: cover;
background-position: center;
background-image:"path/to/image.jpg";
}
You could set the images as the div's backgrounds instead and use backkground-size:cover
https://jsfiddle.net/3x5x0v24/

CSS: How can I set image size relative to parent height?

I am trying to figure out how to re-size an image so that it keeps it ratio of width to height, but gets re-sized until the height of the image matches the height of the containing div. I have these images that are pretty large and long (screenshots), and I want to put them into a 200px width, 180px height div for display and without re-sizing the images manually. To make this look good, the sides of the image need to overflow and be hidden with the containing div. This is what I have so far:
http://jsfiddle.net/f9krj/2/
HTML
<a class="image_container" href="http://www.skintype.ca/assets/background-x_large.jpg">
<img src="http://www.skintype.ca/assets/background-x_large.jpg" alt="" />
</a>
CSS
a.image_container {
background-color: #999;
width: 200px;
height: 180px;
display: inline-block;
overflow: hidden;
}
a.image_container img {
width: 100%;
}
As you can see, there is grey color showing on the images parent container which should not be shown at all. In order for that container to be filled completely, the width needs to be overflowed equally on both sides. Is this possible? Is it also possible to account for an image that is also too tall?
Original Answer:
If you are ready to opt for CSS3, you can use css3 translate property. Resize based on whatever is bigger. If your height is bigger and width is smaller than container, width will be stretch to 100% and height will be trimmed from both side. Same goes for larger width as well.
Your need, HTML:
<div class="img-wrap">
<img src="http://lorempixel.com/300/160/nature/" />
</div>
<div class="img-wrap">
<img src="http://lorempixel.com/300/200/nature/" />
</div>
<div class="img-wrap">
<img src="http://lorempixel.com/200/300/nature/" />
</div>
And CSS:
.img-wrap {
width: 200px;
height: 150px;
position: relative;
display: inline-block;
overflow: hidden;
margin: 0;
}
div > img {
display: block;
position: absolute;
top: 50%;
left: 50%;
min-height: 100%;
min-width: 100%;
transform: translate(-50%, -50%);
}
Voila! Working: http://jsfiddle.net/shekhardesigner/aYrhG/
Explanation
DIV is set to the relative position. This means all the child elements will get the starting coordinates (origins) from where this DIV starts.
The image is set as a BLOCK element, min-width/height both set to 100% means to resize the image no matter of its size to be the minimum of 100% of it's parent. min is the key. If by min-height, the image height exceeded the parent's height, no problem. It will look for if min-width and try to set the minimum height to be 100% of parents. Both goes vice-versa. This ensures there are no gaps around the div but image is always bit bigger and gets trimmed by overflow:hidden;
Now image, this is set to an absolute position with left:50% and top:50%. Means push the image 50% from the top and left making sure the origin is taken from DIV. Left/Top units are measured from the parent.
Magic moment:
transform: translate(-50%, -50%);
Now, this translate function of CSS3 transform property moves/repositions an element in question. This property deals with the applied element hence the values (x, y) OR (-50%, -50%) means to move the image negative left by 50% of image size and move to the negative top by 50% of image size.
Eg. if Image size was 200px × 150px, transform:translate(-50%, -50%) will calculated to translate(-100px, -75px). % unit helps when we have various size of image.
This is just a tricky way to figure out centroid of the image and the parent DIV and match them.
Apologies for taking too long to explain!
Resources to read more:
https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/translate
https://css-tricks.com/centering-css-complete-guide/
Change your code:
a.image_container img {
width: 100%;
}
To this:
a.image_container img {
width: auto; // to maintain aspect ratio. You can use 100% if you don't care about that
height: 100%;
}
http://jsfiddle.net/f9krj/5/
Use max-width property of CSS, like this :
img{
max-width:100%;
}
you can use flex box for it.. this will solve your problem
.image-parent
{
height:33px;
display:flex;
}
If you take answer's Shekhar K. Sharma, and it almost work, you need also add to your this height: 1px; or this width: 1px; for must work.
For me the easiest way to do it without using position absolute, translate.
<div class="img-container">
<img src="yoururl" />
</div>
the CSS should look like this :
.img-container {
height:100px;
width:100px;
overflow:hidden;
}
.img-container > img {
width:100%;
height:100%;
object-fit:cover;
}
If all your trying to do is fill the div this might help someone else, if aspect ratio is not important, is responsive.
.img-fill > img {
min-height: 100%;
min-width: 100%;
}

How to dynamically center image inside a smaller container?

I have a gallery slider, with random images from the forum. So, the size is pretty random but the gallery(container frame) itself is fix sized. So, we decided to set the image height to a fixed size but the width is set to auto. This way, the image will not be squeezed inside the container if its ratio different is too much from the container ratio.
Then, I set the container's text-align to center in order to center the image. But, this only works for images smaller than the container. If the image is still bigger than the container (after resize), the image is aligned to the left instead.
The jsffidle example.
NOTE: Using background-image is not a solution because resizing background image currently is still not supported by many browsers (especially IE and some Chinese browsers).
Hope there is enough information here. So, how do I center the image in this situation?
I have found another solution
<style type="text/css">
.container {
width:600px; //set how much you want
overflow: hidden;
position: relative;
}
.containerSecond{
position: absolute;
top:0px;
left:-100%;
width:300%;
}
.image{
width: 800px; //your image size
}
</style>
and in body
<div class="container">
<div class="containerSecond">
<image src="..." class="" />
</div>
</div>
This will center your image whenever your container is bigger or smaller. In this case your image should be bigger than 300% of container to not be centered, but in that case you can make with of containerSecond bigger, and it will work
You would use max sizes:
img {
max-width: 200px;
max-height: 200px;
}
Take a look: http://jsfiddle.net/fabianhjr/zW6eh/
Edit: still having centring problems, I will get back to you on that.
I had similar problem, but the solution was about to crop right and left margin, while the image should be centered. Smaller images are stretched.
My solution is also in this JS Fiddle: http://jsfiddle.net/david_binda/9tTRQ/
HTML
<div class="thumb-wrapper">
<a href="" title="" class="img">
<img src="http://upload.wikimedia.org/wikipedia/commons/4/40/Tectonic_plate_boundaries.png" alt="" />
</a>
</div>
CSS
.thumb-wrapper{
width: 200px; // desired thumbnail width
height: 150px; // desired thumbnail height
overflow: hidden;
position: relative;
margin: 0 auto;
}
.thumb-wrapper .img{
display: block;
position: absolute;
width: 300px; // should be wider than final thumbnail
height: 150px; // desired thumbnail height
left: 50%;
margin-left: -150px; // half of above defined width eg. 300/2 = 150
}
.thumb-wrapper .img img{
width: auto !important;
max-width: 300px !important; // should be wider than final thumbnail
min-width: 200px !important; // desired width of thumbnail
height: 150px !important; // desired thumbnail height
margin: 0 auto;
display: block;
}​
The solution that I've found is:
img{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);//You have to add all the prefixes
//of transform
}
div.container{
position:relative;
overflow:hidden;
}
Okay, I think this is your best solution.
You set your wrapper around each image to display: table; and then one more wrapper inside that with a display: table-row; and set your img's to display: table-cell
This way you can resize anyway you like while keeping the ratio.
http://jsfiddle.net/zW6eh/17/
You can also simply set your height: to 200px; This will keep your width auto by default.