I am currently using background-image: url() with background-size: contain in order to have an image fill it's container. This works well for large images, as they are automatically reduced in size to fill the space without clipping or stretching the image, irrespective of the relative aspect ratio of the image and the container.
However if the image is smaller than the container in both height and width, the image will be expanded, which often makes the images appear fuzzy or pixelated.
Is it possible in CSS to have smaller images display in their original size, whilst retaining the above behaviour for larger images?
I expect I could code something in Javascript to compare the image and container size, and apply a different style, but I wondered if there was a pure css solution?
This is for a photo gallery type application on a public website so needs to support all the current commonly used browsers.
You need to compare the background image height with the container element height and apply background-size property accordingly.
See below code OR fiddle
HTML
<div id="example1">
<h1>Lorem Ipsum Dolor</h1>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
<p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
</div>
CSS
#example1 {
background-image: url('http://www.w3schools.com/css/img_flwr.gif');
background-repeat:no-repeat;
background-size: contain;
padding: 15px;
}
JS
var image_url = $('#example1').css('background-image'),
image;
// Remove url() or in case of Chrome url("")
image_url = image_url.match(/^url\("?(.+?)"?\)$/);
if (image_url[1]) {
image_url = image_url[1];
image = new Image();
// just in case it is not already loaded
$(image).load(function () {
//alert(image.width + 'x' + image.height);
if($('#example1').height() > image.height ){
alert("background height is smaller than it's containner height");
$('#example1').css('background-size', 'auto');
}
});
image.src = image_url;
}
Fiddle
https://jsfiddle.net/guruling/ujwu5zvn/
A pure CSS solution is only possible with different HTML
If you can switch to using <img> tags instead of background images, you can make the image stretch the container to certain extent and cut off anything that doesn't fit.
You simply need to turn the logic around and let images be whatever size they want to be initially, up to a limit defined by max-width. Images larger than this size will be downscaled to fit the container, while images smaller than this will keep their original size and their container will wrap them nicely.
You can also define a max-height on your container to keep your layout tidy and clip the parts of the image that would overflow it.
The HTML:
<div class="container">
<img src="whatever.jpg" class="dont-uglify-pls"
</div>
The CSS:
.container {
max-width: 10em; /* or whatever limit you want your images to start downscaling at */
max-height: 10em; /* or whatever your layout looks like */
overflow: hidden;
}
.container .dont-uglify-pls {
width: 100%;
height: auto;
display: block;
}
If you need more content in there
Simply slap position:relative on the container and fill it with absolutely positioned elements.
Related
I've read a few solutions with similar titles but none with a solution to this layout.
I have 3 content blocks which all stack beneath each other at most screen widths.
However, when content become overly wide, I want to display a slightly different format.
I want to display the media to the right and the title and text to the left with the text directly beneath the title. It currently sits below the media block (as per the snippet).
anyone know how I can fix it?
.content {
overflow:hidden;
}
.chart {
height: 200px;
width: 200px;
background-color: red;
}
.title, .text {
float:left;
}
.media {
float:right;
}
<div class="content">
<h3 class="title">This is a reasonably long title</h3>
<div class="media">
<div class="chart"></div>
</div>
<p class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non urna est. Quisque sed dolor ac ex aliquet aliquet. Integer ornare, velit vitae iaculis faucibus, nulla libero molestie sem, eget placerat augue massa vitae justo.</p>
</div>
There are 2 things you need to do:
1) You need to add a width for your text block, cause now it's 100% and it takes 100% of parent block width - so no floating will be.
2) You need to add to text block a clear property with left value - cause you don't need it to be floated by the headerfrom the left side.
It's all you need to solve the issue:
.text {
clear: left;
width: 50%; /* put your own width (no matter percents or pixels), but it must be less than (parent block width - media width)*/
}
Check here the example: https://codepen.io/fox_hover/pen/8f838b7799db7a3ed4f4d742097440ef
While both previous answers do work to some degree, both fail to fully address the initial question.
The first, requires a change in the order of elements and the second applying a fixed width which was restrictive.
The final solution is in 2 parts so that it works with multiple screen sizes and media queries.
Firstly I changed the order of the elements as per answer 1. This enabled me to achieve the layout required for my 8 column (wide layout). I applied this styling using an 8 column only media query.
For all other screen sizes, I use display flexbox, which allows me to restore the order I require.
First post on stackoverflow, and i hope you guys are able to help me out.
I have a picture, which is resized responsively, but i keep getting some annoying spacing because of my relative padding with 0.5em. This means i have two scenarios according to my window size. 1: The spacing fits, like this, or 2: I an annoying space in the bottom because of the em padding like this.
So my question is, is there a way, to make sure that the distance from image to right text is the same as distance from image to bottom text? I wouldn't mind, if my picture expanded a bit in height, so the distance's always the same.
I've tried with some different divs, and some different approaches in terms of responsiveness, but i can't get anything to work. Hope you guys can help me out.
HTML:
<div class="panel-body">
<div class="img-exp">
<img src="http://placehold.it/100x100">
</div>
<div class="text-exp">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
CSS:
.panel-body {
text-align: justify;
background-color:black;
padding:0.5em;
}
.img-exp {
position: relative;
float: left;
width:45%;
overflow:auto;
height:auto;
padding:0 0.5em 0.5em 0; /*top right bottom left */
}
.img-exp img{
max-width: 100%;
height: auto;
/*
height:auto;
max-width: 100%;*/
}
Thanks in advance.
It is produced because you have padding-bottom: 0.5em, so when you see the second example and if a line doesn't fits completely you will have that gap.
You need to make perfect calculations with the font-size, the line-height and the number of lines that the height of the image can fit. For example:
Imagine that your image is 100x100, your font-size is 10px and your line-height is 15px. 100 / 15 = 6.66666666666 so it fits 6 lines of text and the last line will occupy 0.6 lines (60% of a normal line). To avoid this, you need to make another calculation.
If in this same calculation, you change the line-height to 20px, you'll obtain: 100 / 20 = 5, it means, 5 exactly lines and nothing in the bottom, so the text doesn't make a gap with your image.
I have always thought that the background-image of an element appears in the element itself, its padding and border but not its margin. However, while trying to get something else to work I discovered this seems to not be the case and the background-image is appearing in the margin.
body {
background: url("https://www.google.co.uk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
background-size: contain;
background-repeat: no-repeat;
border-width: 1px;
border-style: solid;
border-color:red;
margin: 50px;
}
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
https://jsfiddle.net/rz52z14r/
As can be seen, the background is appearing in the margin. Additionally, if I add in overflow: hidden the overflow is not actually hidden. Again, I was under the impression the overflow is anything outside the bounds of the element, i.e., element and padding not including the margin.
So, overall: why is the background image appearing in the margin? And why is the overflow not hidden?
EDIT: there have been a few similar answers to the question; all of which provide a solution to the situation. However, the situation is fictional. What I would like to know is why does this behaviour occur on the <body> tag but not any other tag?
The reason why this occurs is because the root element is treated as a special case when rendering the background. In effect, the background is not being applied to the body but to the canvas:
The background of the root element becomes the background of the canvas and covers the entire canvas, anchored (for 'background-position') at the same point as it would be if it was painted only for the root element itself. The root element does not paint this background again.
The background (http://www.w3.org/TR/CSS2/colors.html#background)
But the root element in this case would be the html element wouldn't it? Well, the following states that it is preferred to apply the background to the body rather than the html element:
For HTML documents, however, we recommend that authors specify the background for the BODY element rather than the HTML element.
The background (http://www.w3.org/TR/CSS2/colors.html#background)
If the background-color and background-image of the html element is transparent and none respectively the rules regarding the canvas apply to the body element instead:
For documents whose root element is an HTML "HTML" element or an XHTML "html" element that has computed values of 'transparent' for 'background-color' and 'none' for 'background-image', user agents must instead use the computed value of the background properties from that element's first HTML "BODY" element or XHTML "body" element child when painting backgrounds for the canvas, and must not paint a background for that child element. Such backgrounds must also be anchored at the same point as they would be if they were painted only for the root element.
The background (http://www.w3.org/TR/CSS2/colors.html#background)
So, to make a background on the body respect the margins simply add a background-color to the html element in CSS:
html {
background-color: red;
}
body {
background: url("https://www.google.co.uk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
background-size: contain;
background-repeat: no-repeat;
border-width: 1px;
border-style: solid;
border-color:red;
margin: 50px;
}
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
Apply background-image to your container, not to your body.
p {
background: url("https://www.google.co.uk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
background-size: contain;
background-repeat: no-repeat;
border-width: 1px;
border-style: solid;
border-color:red;
margin: 50px;
}
See : https://jsfiddle.net/rz52z14r/9/
I'm not quite sure what you are trying to do but the background image you have is sitting in the .body tag. And not the .Body p
https://jsfiddle.net/rz52z14r/12/
so i have my index.html and a canvas.css
body{
}
#canvasHIPPO{
display:block;
margin:0px auto 0px;
width:100%;height:100%
background-image:url('http://www.pcl.co.nz/site/pclimaging/images/Big%20Print%20Carry.jpg')
}
in my index.html:
<div id="container">
<canvas id="canvasHIPPO" width="800" height="600" display="block"></canvas>
</div>
I would like to know how to:
1) center the canvas ontop of the background city image, despite 2) different screen sizes and/or 3) maintain the same aspect ratio.
I was pretty sure the margin:0,auto should have fixed the (1) and centered the canvas ontop of the background image...what am i missing?
Thanks!
Are you trying to centre the image horizontally or vertically?
If you are centring it horizontally, in your css it should be:
#content {
background-image: url('http://www.pcl.co.nz/site/pclimaging/images/Big%20Print%20Carry.jpg');
}
#contentHIPPO {
margin: 0 auto;
display: block;
width: 800px;
height: 600px;
}
and in your html:
<div id="content">
<div id="contentHIPPO">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</div>
</div>
This will cause the div to be centred horizontally, with the image repeating in the background. If you want the image to be re-sized to the browser window, you would need to use javascript to get the size of the window.
Why not you use
display: webkit-box;
The new css3 provide more properties follow the tutorial
http://www.w3schools.com/css3/default.asp
If it's a small project, you can always convert your hex colours (#FFFFFF) to RGB and Alpha (where the alpha channel is transparency), which looks something like this rgba(255,255,255,100). However, if you've got hundreds, or even thousands, of instances of colour references, you're probably better off Googling a tutorial.
I am trying to put an image as the background and would like it to align to the right, but not closely align to. Something like margin-right:10px. Is it possible to do that in pure css, without explicitly adding a margin to the image?
I had several attempts, but all failed...
http://jsfiddle.net/cA7Un/1/
Thanks in advance!
You could use a percentage, but this is only good if you know the width of the container will stay the same:
background-position: 95% center;
Otherwise, you could add 10 pixels of whitespace to the right of your image in an image editor like Photoshop.
To use the example you put on jsfiddle:
I declared the following extra style:
.rss
{
background-image: url('http://tipabsorb.com/index/wp-content/plugins/category-specific-rss-feed-menu/rss_small_icon.png');
background-repeat: no-repeat;
float: right;
width: 16px;
min-width: 16px;
max-width: 16px;
height: 16px;
min-height: 16px;
max-height: 16px;
margin: 10px;
}
This uses the same image, but adds an extra div to your your markup. This method gives you the image as a background image, and then with the margin you can position it as far from which ever side you want (by also changing the float if you want it on left hand side).
<div class='test' style='width: 300px; height: 100%'>
<div class="rss">
</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
</div>
The positioning of the "rss" div before you normal markup is important as this affects the flow. Could also do it by positioning the div absolutely with a relative parent.
Finally I deleted the background from the ".test" class, as it has now been moved to the "rss" class.
I hope this helps.