I'm building a Wordpress theme that will use imported posts from another site.
These posts have images that vary in size and aspect ratio.
There are predefined areas on the new theme where these image must fit, and fill the area, with centering and without letterboxing.
Without breaking the semantics of the img tag by using background images, I've put together a few techniques I've seen elsewhere to scale images and fit/center them to a panel, like this:
CSS:
.fillwidth {
width: 100%;
height: auto;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.fillheight {
height: 100%;
width: auto;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
div {
border: 1px solid black;
overflow: hidden;
position: relative;
}
JS:
<script src="http://localhost/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> </script>
<script>
(function($){
$('div').each(function() {
var fillClass = ($(this).height() > $(this).width())
? 'fillheight'
: 'fillwidth';
$(this).find('img').addClass(fillClass);
});
})(window.jQuery);
</script>
HTML:
<div>
<img src="test.jpg" />
</div>
So basically the JS determines the aspect ratio, the image is fit to the box and a transform centers it.
Now my question is, on a high traffic Wordpress site, would you recommend allowing the user's browser to do this resizing on the front end, or should the theme create multiple versions of uploaded images to fit the various panels on the site in advance? With modern browsers what is the impact of asking the browser to do the scaling and resizing of images?
Related
I want to center an image with unknown width and height in the browser window without any resizing. If the image is wider than the browser width, which I expect it to often be, I want to crop the image rather than resize it. There should not be a horizontal scrollbar.
CSS only solutions are preferred, but PHP is acceptable and JS less desirable but still welcome. Using background images is not ideal.
This question is very similar and I would answer it if I could: Resize browser width and cover photo must retain the center of cropped image
This code block gives a sense of what I've tried, but may not be very helpful:
.banner-container {
display: block;
position: relative;
height: 450px;
overflow: hidden;
}
.banner {
position: absolute;
left: 50%;
margin-right: -50%;
transform: translateX(-50%);
/*height: 450px;*/
/*
display: table-cell;
vertical-align: middle
*/
/*justify-content: center;*/
/*margin: 0 auto;*/
/*object-fit: cover;*/
}
<div class="banner-container">
<img class="banner" src="https://i.stack.imgur.com/ppDo7.png">
</div>'
You can use an img element which I see you prefer.
This snippet uses one of the methods you tried to center it - to get the left/right centering it moves the img to have the left as the center of the div, then moves it back by half its width.
It does not try centering vertically as the requirement seems to be to have the img height the full height of the banner, but this could of course be changed if wanted.
Note that to stop overflow being shown with a scrollbar the correct setting is overflow: hidden, not hide as in the given code.
.banner-container {
display: block;
position: relative;
height: 450px;
overflow: hidden;
}
.banner {
position: absolute;
left: 50%;
transform: translateX(-50%);
height: 100%;
}
<div class="banner-container">
<img class="banner" src="https://i.stack.imgur.com/ppDo7.png">
</div>'
For clarification, this is the CSS that worked in my situation:
.banner-container {
position: relative;
height: 450px;
}
.banner {
height: 100%;
object-fit: cover;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
As described in the comment to A Haworth's answer, Imagify was replacing <img> tags with <picture>, which interferes with the style structure. Since Imagify's optimizations are used in current posting habits and the conversion to <picture> is generally desired, I avoid the conversion simply by only using .webp images for this banner.
(This is for desktop. Smaller screens get different images and have modified behavior for better performance and appearance.)
I am working on a WordPress website and have styled the templates header in CSS. I've given it a different background image and it's working, the only problem I have is on mobile.
On mobile there seems to be a white gap to the right of the image and I was wondering if anyone knows a solution to this?
You header element—
<header id="home" class="header menu-align-center" itemscope="itemscope" itemtype="http://schema.org/WPHeader">
</header>
has a min-height:100px set. Increase that number until the image goes all the way across. Try 112px.
For images I learned for myself that it works best to define the container using an aspect ratio, so that it's forced to take up the space you want it to. And then make the image position: absolute inside the container and force it to fill the parent container using object fit: cover and set both lengths to 100%. The image will then automatically fill 100% height or width whatever of both is required:
<div class="image-container">
<img src="...">
</div>
.image-container {
&:before {
/* create a 1px bar inside the container and stretch it according to padding-top */
content: "";
width: 1px;
margin-left: -1px; /* 1px bar with -1px margin will make sure no space is taken */
float: left;
height: 0;
padding-top: 50px / 150px * 100%; /* height / width ratio. So this would result in 3x as wide than high. 100% always refers to the width of the container which makes this trick work */
}
&:after { /* to clear float */
content: "";
display: table;
clear: both;
}
img {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
}
}
You can then also make the container switch aspect ratio by simply changing the .image-container:before{padding-top:;} in your media queries.
Also note that at best the <div> container would be replaced with a <picture> tag providing some different image sizes. Then you have performance increased and no extra DOM nodes as you need the picture tag anyways.
I am looking for something that would allow me to render an uploaded image with a 3D perspective and a wrap effect like here.
This will be in the form of a cropping preview using a jQuery library such as jCrop
Currently I was able to achieve the 3D perspective using Reflex.js but looking for a more subtle solution with the wrapping effect as well.
Any help will be appreciated :)
Thanks in advance!
Your requirement of IE9 support basically mandates a canvas approach if you want to keep it client-side. You could of course do the rendering server-side and AJAX load the rendered image back in which will work in every browser.
If you decide that you can dump IE versions less than 10 (or at least just show them the normal photo without the transform then you can do the wrap-around effect with a combination of CSS 3D Transforms and CSS2 clip. Something like:
<!DOCTYPE html>
<style>
body { margin: 100px; position: relative; }
.edge { width: 20px; height: 196px; background-size: auto 100%; position: absolute; left: 30px; top: 2px; transform: perspective(600px) rotateY(-45deg); transform-origin: right; }
.panel { position: absolute; left: 31px; top: 0; clip: rect(auto,auto,auto,20px); }
.panel>img { width: 350px; height: 200px; transform: perspective(600px) rotateY(30deg); transform-origin: left; }
</style>
<div class="edge" style="background-image: url(my_image.jpg)"></div>
<div class="panel"><img src="my_image.jpg" /></div>
To break that down, we’ve loaded the user’s image and dropped it into the page, along with a div with the same image set as a background. That div is set to be a thin width and a height that’s almost as tall as the main image. We can use the background-size property to foce the background image to fit the div even if it’s taller.
We then absolutely position those two so that they’re next to each-other. The CSS2 clip property lets us clip off the left 20px of the image so that at this point the div and img look like one image together.
Finally, we set a perspective and transform-origin for each block and rotate them away from each-other around the Y axis. Because of the clipping we have to fudge the .edge block to be slightly smaller than originally (with a 200px tall image I had to drop it to 196px to look good) but that works pretty nicely for me.
Obviously you’d need to fill in the vendor prefixes (-moz-, -ms-, -o-, -webkit) and I’ll leave the shadow as an exercise for the reader (a simple background on the container would probably do).
Wondering if anyone has a solution for this.
I would like to present an archive of thumbnail images oldest at the bottom and newest at the top. I would also like the flow itself to be reversed... something like this:
The page should be right aligned, with future images added to the top of the page. I am creating the page dynamically with PHP pulling image filenames from a MySQL DB. The catch here is I would love this layout to be fluid, meaning most PHP tricks for counting images and building the HTML accordingly go out the window.
Is there a way to do this with Javascript or even just CSS?
See: http://jsfiddle.net/thirtydot/pft6p/
This uses float: right to order the divs as required, then transform: scaleY(-1) flips the entire container, and lastly transform: scaleY(-1) again flips each individual image back.
It will work in IE9 and greater and all modern browsers.
CSS:
#container, #container > div {
-webkit-transform: scaleY(-1);
-moz-transform: scaleY(-1);
-ms-transform: scaleY(-1);
-o-transform: scaleY(-1);
transform: scaleY(-1);
}
#container {
background: #ccc;
overflow: hidden;
}
#container > div {
float: right;
width: 100px;
height: 150px;
border: 1px solid red;
margin: 15px;
font-size: 48px;
line-height: 150px;
text-align: center;
background: #fff;
}
HTML:
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
..
</div>
CSS Flexible Box Module was made for this type of thing. See a quick example I whipped up: http://jsfiddle.net/c6QLC/2/ (look at this in Firefox)
Now the bad news: you can't really rely on it yet. Not only is the spec being rewritten, the current implementation doesn't support box-lines (which I did include in the example), which would allow the items to be in multiple rows as opposed to being overflow.
The new spec is being written into dev versions of some browsers, so it will happen. It's just a matter of time.
In the meantime, perhaps something like Isotope might fit your needs.
Should you want to check out the spec, you can find it here: http://www.w3.org/TR/css3-flexbox/
This can be solved with jquery masonry plugin. It's a bit like isotope but free of charge for private and commercial users.
Ok, so I'm trying to implement a sliding video thumb gallery linked to a lightbox similar to the home page of reason.com but I would like to do it in pure CSS if possible. I already have the code complete for the lightbox which is basically pure CSS with a javascript:void function linking thumbs to the lightbox.
My issue is that I plan on updating the videos daily since it is for an article database and would rather not have to capture the video thumbs for every video upon updating.
Is there a way to dynamically capture thumbs of videos with a PHP script and including the script in my javascript:void link that will display the thumb for my lightbox? I'm basically trying to find a work around for capturing and resizing the thumbs for all of the videos in my thumb slider because this would be increasingly teadious to do on a daily basis.
Thanks in advance for any suggestions!
CSS:
.black_alpha{
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=80);
}
.video {
display: none;
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
padding: 16px;
border: 16px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
HTML:
<body>
**I want each thumb to link to this** <a href = "javascript:void(0)" onclick =
"document.getElementById('light').style.display='block'document.getElementById
('fade').style.display='block'">
<div id="light" class="video"> **this should show the video of the thumb clicked**
<a href = "javascript:void(0)" onclick = "document.getElementById('light').style.display='none';
document.getElementById('fade').style.display='none'"></div>
<div id="fade" class="black_alpha"></div>
</body>
I thought the thumb slider would have been irrelevant so I didn't include it.
You can use ffmpeg to capture images from video. It's easy to use and just needs to be installed on your server. You can run the ffmpeg commands from php using exec() (note: this may need to be enabled in your php.ini)