CSS Scaling a svg using flexbox - javascript

I got a problem with scaling my svg pictures. Actually, I'm creating a design for a html cardgame.
Here is a picture of the window:
The scaling is correct, because there is enough space in both directions, so the svg fills the space.
But when I'm gonna resize the window and the width gets smaller and smaller, something like that happens:
So, the scaling of the picture svg itself is correct, but html/css thinks that the image is the whole part inside of the displayed border lines. I just took the image with a drag'n'drop to visualize the problem.
HTML: (just a part, here the last row)
<div id="playerRow">
<img id="playerCard2"/>
<img id="playerCard3"/>
<img id="playerCard4"/>
<img id="playerCard5"/>
</div>
CSS:
#playerRow{
display:flex;
flex-direction:row;
justify-content: center;
align-items: center;
background-color: forestgreen;
border-style: solid;
border-radius: 20px;
height: 45%;
}
#playerCard1, #playerCard2, #playerCard3, #playerCard4, #playerCard5 {
min-width:0px;
min-height:0px;
height:90%;
margin:1vh;
border-style: dashed;
border-color: #555555;
border-radius: 15px;
}
I'm quite sure that there is a mistake with the height. Because when I put the height from 90% down to 40% it looks better for the resized width-low window.
I tried to use max-height instead height, but that doesn't make any difference.
What could be the problem? I just want to scale the border lines to the size of the image. I tried also with javascript a kind of rescaling, but the problem is, that I can't get the height of the svg, it always takes the whole part. Furthermore, I also want to know if that problem is possible to solve only in CSS.
EDIT:
The last row with the ratio css trick:

I solved my problem.
First of all, I used the CSS-ratio trick, which is described here: Responsively change div size keeping aspect ratio
But the problem still appeared, because the width was responsible for the resolution. So when the width grows, the height grows too, that's correct, because it always takes care of the defined ratio. The only thing is, that the correct width has to be calculated.
So, everytime the window has been resized, the width has to be recalculated. I'm doing that with javascript:
function correctRatio(card, div){
width =$(div).width();
currentHeight = $(div).height();
wrongWidth = $(div).width();
newWidth = 9/14 * currentHeight;
if(wrongWidth+1 > newWidth){
newWidth = newWidth/(width/100);
}else{
newWidth = 100;
}
$(card).width(newWidth+"%");
console.log("Setted Width:" + newWidth);
}
The 9/14 resp. 14/9 is in my case the ratio 9:14

You should be able to have the card containers keep their aspect ratio using this trick.
Responsively change div size keeping aspect ratio

Related

Any ideas on how to fix image sizing without changing the original image

I have a avatar image for company logos. I want it to be round but due to sizing of the images it cuts off some of the image. I have thousands of these logos and I am looking for any Ideas on how to fix this.
The Ideal end result would be the logo centered in the circle with the least amount of overlap. I though about just adding extra background space and making the image smaller unfortunately the logos have different color backgrounds. Thanks for your time!
div {
border-radius: 50%;
width: 200px;
height: 200px;
outline: 2px dotted black;
overflow: hidden;
}
img {
height: 100%;
}
<div>
<img src="https://www.vectorlogo.zone/logos/stackoverflow/stackoverflow-tile.svg" alt="logo">
</div>
Use object-fit: cover.
Example:
img {
width: 200px;
height: 300px;
object-fit: cover;
}
The CSS object-fit property is used to specify how an <img> or <video> should be resized to fit its container.
This property tells the content to fill the container in a variety of ways; such as "preserve that aspect ratio" or "stretch up and take up as much space as possible".
The object-fit property can take one of the following values:
fill - This is default. The image is resized to fill the given dimension. If necessary, the image will be stretched or squished to fit
contain - The image keeps its aspect ratio, but is resized to fit within the given dimension
cover - The image keeps its aspect ratio and fills the given dimension. The image will be clipped to fit
none - The image is not resized
scale-down - the image is scaled down to the smallest version of none or contain

Avoid CSS-Background-Resize by Chrome-URL-Bar-Toggle with Android

When viewing a website with Chrome for Android, the height of the view-area changes as soon as scrolling causes the URL-bar to hide. When using a fixed background image, this results in annyoing resizing of the image, initially when scrolling down, and also when the user scrolls up again, which enables to URL-bar again.
This topic has already been discussed here:
Background image jumps when address bar hides iOS/Android/Mobile Chrome
There was also a 'fix' announced, that recommends the use of vh instead of % to describe the height of the image:
https://developers.google.com/web/updates/2016/12/url-bar-resizing
Given now a site that contains a fixed background image:
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="content">
<div style="padding-bottom:2000px; width:100%;">Test</div>
<div>Test again</div>
</div>
</body>
</html>
using the following CSS:
html, body {
margin: 0;
padding: 0;
}
div {
color:white;
font-size: 30px;
}
#content {
background: url(https://images.freeimages.com/images/large-previews/01a/technology-background-1632715.jpg) no-repeat right 15% center fixed;
background-size: cover;
}
will rescale the background image as described above, using Google Chrome for Android. Here is a Fiddle.
The methods determined to solve this (see linked JS-thread) make use of JavaScript to determine the window height after resizing of the window has taken place and then update the image height. However, it won't stop the background image from resizing without leaving a part of the page blank.
In order to keep the background image in place, two methods seem suitable:
preventing the URL-bar to hide
render the image with an initial offset to be able to compensate the image shift
Preventing the URL-bar to hide
In order to keep the URL-bar visible all the time, I created a fixed-div that contains a scrollable div-container:
<div id="content">
<div id="fixed">
<div id="scroller">
<div style="padding-bottom:2000px; width:100%;">Test</div>
<div>Test again</div>
</div>
</div>
</div>
CSS:
#fixed {
height:100vh;
width:100vw;
overflow:hidden;
}
#scroller {
overflow-y: auto;
height:100vh;
}
The idea is that since the user is not scrolling the website-body, the URL-bar won't disappear. This Even though this works on my emulator, it doesn't work on a real Galaxy S20. A user would be able to hide the URL-Bar after scrolling to the bottom of the page (the div).
Rendering the image with an initial offset to be able to compensate the image shift
The other idea was to draw the background image 'deeper' by default:
background-size: auto calc(100vh + 100px);
If there is "unused" space on top of the image, it should be possible to catch the resize- or touchmove-event, compare the new window height to the initial window height and then compensate the offset. Unfortunately, this will only affect the y-dimensions of the image and I would probably need to do the same for the x-axis or rescale the image again. However, when trying to determine the current image size in JavaScript (using jQuery, see this thread), I ran into another error; retrieving the image-size via $('#background').css('background-size') returned just auto and ignored the second part.
Most threads about this topic are older than five years. Can someone enlighten me and tell me there is a way to manage this by now?
Update:
I was able to eliminate the resizing using the following technique:
Assuming portrait-mode is active, I calculated the image width from the scaled image height and set the background-size to pixel values:
var initHeight = '';
var initWidth = '';
var imageHeight = 982;
var imageWidth = 1500;
var cssHeight;
var cssWidth;
$(window).on('resize', function () {
if (initHeight == 0) {
initHeight = $(window).height();
initWidth = $(window).width();
cssHeight = parseInt($('#content').css('background-size').split(" ")[1].slice(0,-2));
cssWidth = cssHeight / imageHeight * imageWidth;
$('#background').css('background-size', cssWidth + "px " + cssHeight + "px");
}
Now the background image won't scale, but it will move vertical when toggling the URL-bar.
To get rid of this, I make use of the second method described above and draw the background image with an initial offset:
background: url(../images/bg.jpg) no-repeat right 15% top -100px;
background-size: auto calc(100vh + 200px);
As soon as a resize-event occurs, I update the background image position:
let newHeight = $(window).height();
let newWidth = $(window).width();
let diff = newHeight - initHeight;
$('#background').css('background-position', "85% " + (startHeightOffset + diff) + "px")
This seems to work in my emulator. The background image stays in place now. However, when switching devices, I noticed that this approach works only for devices that have no toolbar in the bottom. Emulating a Galaxy S9, which has a URL-bar on the top as well as a toolbar on the bottom, the background image gets shifted too much, since the space acquired by both toolbars (top and bottom) will be added to the top of the image. In order to make this work, I would need to determine the height of the top URL-bar only and I genuinely don't know if this is possible.
Again, in order to solve this problem, one of the following problems must be solved:
reliably prevent hiding of the URL-bar
determining the height of the bottom toolbar
Update 2:
I was able to prevent hiding of the URL bar like so:
html, body {
margin: 0;
padding: 0;
height: 100%;
overflow: scroll;
}
body {
-webkit-overflow-scrolling:touch;
}
#content {
width: 100%;
height: 100%;
background: url(https://images.freeimages.com/images/large-previews/01a/technology-background-1632715.jpg) no-repeat right 15% center fixed;
background-size: cover;
}
#fixed {
height:100%;
width:100vw;
overflow:hidden;
}
#scroller {
overflow-y: auto;
height:100vh;
}
The background image stays in place, since the URL-bar will never collapse. However, this isn't the ideal solution and it would be great if there would be a way to make this work without the need of preventing the URL-bar to collapse.

Scale div like an image

I am trying to scale content within a div based on it's width.
As an example, I have a div:
<div id="container"></div>
I have styling such as:
#container { margin: 0px auto; width: 810px; height: 800px; border: 1px solid #000; }
This presents me with a div 810px wide and 800px tall, nicely centered on screen with an outline.
Let's say I have a banner graphic at the top which should scale with the div, so I have it's width at 100%. Works great.
I have a background graphic for the container div itself set to scale with the width as well, working great.
What I need help with, is let's say I had a heading underneath the banner, but this font size needed to scale with everything else, based on the width of the container. How would I accomplish this?
I am also looking to add other elements such as buttons, which would need to scale.
At the end of the day, imagine and image with a width of 100%, and how it scales proportionately, perfectly. This is how I need the container div and all its children to act, like an image. I hope this makes sense.
I have looked at scaling text like in this link: http://jsfiddle.net/Aye4h/
This is the perfect behavior, but I need more than just text to scale.
Scaling is a complicated matter as some content is vector based or otherwise rendered on-demand, and some content is raster based (e.g., images). If you want to scale an entire element as if it was just an image, then have a look at transform: scale:
#scaled {
border: #f00 solid 5px;
background: #0ff;
height: 500px;
margin: -125px;
transform: scale(0.5);
width: 500px;
}
<h1>This is outside the scaled element</h1>
<div id="scaled">
<h2>Inside the scaled element</h2>
<p>An image:</p>
<p><img src="http://i.imgur.com/3A1Loxw.jpg"></p>
</div>
Keep in mind that the transform is applied after the image has been laid out on the page so all content around it will think it's still at its original size. You can work around this in many other ways, such as by using negative margin values (as I did in the example).

How to make same sized thumbnails

I'm having a hard time now trying to make same sized thumbnails,
I have a simple gallery script that just takes all images out of database and places them to the page with max width 150px and max height 150px.
Now , it looks weird because all images have different shape, is there any way to make them same size without breaking the image apart? The simplest way possible please.
I don't want to have an option on uploading step to chose dimensions for thumbnail.
With img you only have two options: Set a maximum width, or a maximum height. Either way you won't get reasonably-sized thumbnails: If you set the maximum width, then some images will be too tall. If you set the maximum height, then some images will be too wide. If you set both width and height, it'll get horribly distorted, because it will ignore the aspect ratio.
Instead, I suggest making a div of a fixed size and setting the thumbnail as its background-image, then setting background-size to cover. This will give much better thumbnails, as it scales and crops the image to make it fit. If you want to avoid cutting off the image's edges, give the div a background-color and set background-size to contain, which instead scales down the image to make it fit and creates a "letterbox" effect.
Putting it all together (plus thumbnail centring for the crop, and inline-block so it acts like an <img> tag does):
<style>
.thumbnail {
background-color: black;
width: 250px;
height: 200px;
display: inline-block; /* makes it fit in like an <img> */
background-size: cover; /* or contain */
background-position: center center;
background-repeat: no-repeat;
}
</style>
<div class=thumbnail style="background-image: url(image1.jpg);"></div>
<div class=thumbnail style="background-image: url(image2.jpg);"></div>
Here's a jsfiddle demo for cover: http://jsfiddle.net/tbeog5o9/24/
And here's a jsfiddle demo for contain: http://jsfiddle.net/tbeog5o9/25/
There is another nice way to achieve this using object positioning
.thumbnail video, img {
width: 100%;
height: 100%;
object-fit: cover;
}
Please have a look on this article for details
Do all of your images have the same aspect ratio? The aspect ratio is the width divided by the height.
If all images have the same aspect ratio, you can scale them to the same shape by choosing a width and calculating the height, or choosing a height and calculating the width.
If the aspect ratios differ, there is no way to fit the images into the same shape without mangling images. There are two ways to mangle an image:
Cut off part of the image so that it fits your chosen shape.
Squeeze or stretch the image into your chosen shape.
If you don't want to mangle your images, you must preserve their aspect ratios. This means, indeed, that the thumbnails will have different shapes. You may think that this looks weird, but most people think it's even weirder when thumbnails are truncated, squeezed, or stretched in order to fit them into a uniform shape.
My jsfiddle example: http://jsfiddle.net/larryjoelane/tbeog5o9/38/
<img class="resize" src="http://cdn.moneycrashers.com/wp-content/uploads/2012/03/apple-imac-27.jpg"/>
<img class = "resize" src="https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcR-pya5LcLCg82HTG3R36aS9B59SSjNzewp8tAHFZrjFjRb1rXI"/>
CSS:
img.resize{
max-width:150px;/*rendered height will be 103px and width will be 150px*/
}
You will have to change the img tag url's in my example to match your image url's of course and add the class resize to your img tags.
The rendered height of the image will be 103px but the image will not look distorted.

Crop and center arbitrarily-sized image within a div

I have a div within which I would like to put any arbitrarily-sized image, preferably using an img tag rather than the CSS background-image style. I've looked at many other similar questions and none have answered my question.
The way I would like the image to display is this:
If the image is portrait (height is greater than width), the image will have a width of 100% within the div and be vertically centered. The extra height will be outside of the div, but not visible (as in, the image would appear 'cropped'.)
If it is landscape, the properties in #1 would apply, but horizontally instead of vertically.
I do not want to stretch the image. I do want to fill the entire space within the div.
An example of this would be the image boxes that appear on imgur.com.
Try centering it with javascript. Just set the position: absolute, left:50%, top:50% and margin-left:-width/2, margin-top:-height/2
I'm surprised this question doesn't have an easy to find answer anywhere online, but I came up with a (mostly) pure CSS solution that might help someone. The idea is that there are two possible sizes for the image:
Width is 100% of the parent, height is determined by aspect ratio
Height is 100% of the parent, width is determined by aspect ratio
Of these two options, the one that is preferred is simply the bigger one, since the smaller one will leave gaps around the edges. Therefore, we can use a div in between container and image to "calculate" the larger size. Here's my code:
const image = document.getElementById("image");
const sizer = document.getElementById("sizer");
image.onload = () => {
const aspectRatio = image.width / image.height;
sizer.style = `aspect-ratio: ${aspectRatio}`;
};
#container {
position: relative;
overflow: hidden;
width: 400px;
height: 250px;
resize: both;
}
#sizer {
min-width: 100%;
height: 100%;
position:absolute;
left:50%;
top:0px;
transform: translate(-50%,0);
}
#image {
width: 100%;
height: auto;
position:absolute;
left:0;
top:50%;
transform: translate(0,-50%);
}
<div id="container">
<div id="sizer">
<img id="image" src="https://www.industrialempathy.com/img/remote/ZiClJf-1920w.jpg"/>
</div>
</div>
Try dragging around the corner of the image to check how it works.
The only JS required is to fix the aspect ratio of the sizer, and it's quite lightweight (only required when the image src is loaded). I believe this will also work across almost all browsers and versions, since the CSS is very basic.
Hope this helps someone!

Categories