Using image as a container? - html

Is it possible for me to remove the container div completely and turn the image into the container, retaining the width and height of the image but also keeping the styles of the container that is already in my stylesheet? Any suggestions would be greatly appreciated. Thanks!
.img_zoom_container {
position: relative;
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
max-width: 45%;
}
.img_zoom_window {
border: 2px solid #d4d4d4;
width: 300px;
height: 300px;
position: absolute;
top: 20%;
left: 0%;
margin-left: -200px !important;
transform: scale(0) translateY(-50%);
transform-origin: 0% 0%;
transition: all ease .2s;
}
.img_zoom_container:hover .img_zoom_window {
left: 170%;
transform: scale(1) translateY(-50%);
}
<div class="img_zoom_container">
<img id="main_img_kit" class="prod_img mobile_hideb" height="300" width="300">
<div id="img_main" class="img_zoom_window"></div>
</div>

As Felipe mentioned, if you are trying to display other elements on top of (within) the image, you could always set the image as the background of the container and simply put more containers within the outer container for your other divs.

One method to have a background image push the parent containers width and height would be to use 2 images.
<div class='container'>
<img src='http://via.placeholder.com/350x150' class='pusher' />
<img src='http://via.placeholder.com/350x150' class='animator' />
</div>
They can be the same image just with one at 0 opacity and pointer events disabled. This approach is also easy to make responsive. I set up a demo for you here:
https://codepen.io/cidicles/pen/djMXeW
Hope it helps!

Related

CSS - How to stretch images vertically to fill when parent div doesn't have fixed height. (Without flex)

I have 2 images that have different dimensions. I want them to align horizontally and to fill the same height.
HTML
<div class="background">
<div class="wrapper">
<div class="content">
<img src="./nat-8.jpg" alt="" />
<img src="./nat-9.jpg" alt="" />
</div>
</div>
</div>
CSS
.background {
height: 100vh;
width: 100%;
background-color: grey;
position: relative;
}
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
background-color: white;
}
img {
display: inline-block;
width: 35%;
}
The result I get:
As you can see the first picture has white space left on the top. How do I make it that each picture covers the whole height of parent without setting fixed height on parent?
NOTE: I know that it can be done with flex by setting 'display:flex' on content div. But how do I do it without flexbox?
I tried 'display:table-cell' on images, in one solution I found it was used to make divs fill the entire eight of their parent, but apparently it does not work on 'img' element.
You need to set the height of the parent container, then you can set the height of the image to 100% to fill the space.
You can then use object-fit:cover to keep the image ratio rather than stretching. You can also use object-position:center to keep the positioning centered also.
Not all browsers are compatible with object-fit, so I would suggest swapping out the images for divs with a background-image set.
.background {
height: 100vh;
width: 100%;
background-color: grey;
position: relative;
}
.wrapper{
height:100%;
}
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
background-color: white;
height:100%;
max-height:150px;
}
img {
display: inline-block;
width: 35%;
height:100%;
object-fit:cover;
object-position:center;
}
<div class="background">
<div class="wrapper">
<div class="content">
<img src="https://www.indiewire.com/wp-content/uploads/2019/06/574055-frank_ockenfels-amc.jpg" alt="" />
<img src="https://www.indiewire.com/wp-content/uploads/2019/06/574055-frank_ockenfels-amc.jpg" alt="" />
</div>
</div>
</div>

Firefox - container does not adapt width to content when image is scaled down

I have a weird issue on Firefox, it kind of sounds like this one: https://bugzilla.mozilla.org/show_bug.cgi?id=829958 but it has been fixed few years ago.
I have an big image inside a wrapper having width: auto; height: 100%;. The only constraint applied to the image is height: 100%;.
The image is correctly scaled down on all browsers to the maximum height available. On almost all browsers, the wrapper is also scaled down to the new (and effective) size of the image. This is not the behavior on Firefox (tested on 50+), Firefox does scale down the image but not the wrapper who keep the original width of the image as its own width.
Here is a codepen to better simulate the issue: https://codepen.io/Tronix117/pen/MEogMv
The img-wrapper can not be in display: inline; because of effects applied on it. More intermediate div can be added if needed.
On the codepen, don't mind the fix width of scroll-wrapper it's a dynamic value, as well as all transforms values.
Images can be of various width and height and the CSS should be responsive.
The idea is to produce a coverflow with different images using Swiper lib.
I have been struggling on this all day, so thank you for your help!
CSS
html,
body {
height: 100%;
width: 100%;
}
* {
padding: 0;
margin: 0;
}
#viewport {
position: absolute;
top: 20px;
bottom: 20px;
left: 20px;
right: 20px;
overflow: hidden;
display: block;
perspective: 1200px;
transform-style: preserve-3d;
}
#scroll-wrapper {
display: block;
position: relative;
width: 3000px;
height: 100%;
transform-style: preserve-3d;
transform: translate3d(-500px, 0, 0);
}
.img-wrapper {
display: inline-block;
white-space: nowrap;
overflow: hidden;
width: auto;
height: 100%;
position: relative;
transform-style: preserve-3d;
border: 4px solid red;
}
img {
height: 100%;
}
#img-wrapper-1 {
border-color: blue;
transform: translate3d(0px, 0px, -500px) rotateX(0deg) rotateY(30deg);
z-index: -1;
}
#img-wrapper-3 {
border-color: green;
transform: translate3d(0px, 0px, -500px) rotateX(0deg) rotateY(-30deg);
z-index: -1;
}
HTML
<html>
<body>
<div id="viewport">
<div id="scroll-wrapper">
<div id="img-wrapper-1" class="img-wrapper">
<img src="http://via.placeholder.com/2000x1200" />
</div>
<div id="img-wrapper-2" class="img-wrapper">
<img src="http://via.placeholder.com/2000x1200" />
</div>
<div id="img-wrapper-3" class="img-wrapper">
<img src="http://via.placeholder.com/2000x1200" />
</div>
</div>
</div>
</body>
</html>
Very interesting problem!
It's most likely a bug with Firefox, though I think that it's probably caused by Firefox unable to find the correct reference height value for all the cascaded height: x%; of nested elements.
So I gave #viewport an explicit height value: height: calc(100vh - 40px); instead of an implicit one from top: 20px; bottom: 20px;. And it does work!
Demo: https://codepen.io/anon/pen/eGRYqx

Triangular Images

I have two right triangle images that I want to put together like this (solid colors only for example):
I can think of a couple of ways to do this:
Divs with background images, and positioning them on top of each
other
A similar approach to the above, but with images instead of divs
The problem comes from the fact that I want to be able to hover (and click) on each individual triangle and have it change it's state (such as change color on hover).
Both of my above solutions create the problem where one is on top of the other, and I cannot click or hover over the other. I was thinking of doing this with CSS shapes, but those usually involve borders and I don't know of a way to overlay the image on those.
I need to be able to accomplish this with just CSS and HTML, and ideally without an image map.
Is this what you want?
Edit: I didn't notice there was another answer with similar approach, had the answer window opened for awhile, sorry.
.container {
width: 100px;
height: 100px;
overflow: hidden;
position: relative;
}
.triangle {
position: absolute;
width: 100px;
height: 100px;
top: 0;
left: 0;
overflow: hidden;
}
.triangle:hover {
border: 1px solid red;
}
.top_right {
transform: skewX(45deg);
transform-origin: 0 0;
}
.top_right img{
transform: skewX(-45deg);
transform-origin: 0 0;
}
.bottom_left {
transform: skewX(45deg);
transform-origin: 0 100%;
}
.bottom_left img{
transform: skewX(-45deg);
transform-origin: 0 100%;
}
<div class="container">
<div class="triangle top_right">
<img src="http://www.avatarsdb.com/avatars/spongebob_happy.jpg">
</div>
<div class="triangle bottom_left">
<img src="http://www.avatarsdb.com/avatars/say_cheese.jpg">
</div>
</div>
Another option is to use css skew:
your html:
<div class="img-container">
<img src="http://www.natureasia.com/common/img/splash/thailand.jpg" />
</div>
<div class="img-container">
<img src="http://www.worddive.com/blog/wp-content/uploads/2014/06/nature-and-environment-course.jpg"/>
</div>
The css:
.img-container, .img-container img { width: 100%; height: 100%; }
.img-container {
overflow: hidden;
position: absolute;
transform: skewX(-68deg);
}
.img-container:first-child {
left: -.25em;
transform-origin: 100% 0;
}
.img-container:last-child {
right: -.25em;
transform-origin: 0 100%;
}
.img-container img {
transform: skewX(68deg);
transform-origin: inherit;
}
It will probably work better with square images, however you can play around with the skew until it looks right.
Check out this Fiddle or rotating the other way
Again, not 100% sure on browser compatibility tho. If you need to guarantee that all browsers render properly you might be best of using images.

Make 8 rectangular images fill entire screen with native aspect ratio and fluid layout

I have 8 identical, rectangular photos that I want to seamlessly fill my entire web page (even during resizing) in two rows, and I am not sure how to do that.
Basically I was going to make a div and put in all of the images at 25% width of the parent, (That way the fifth image will flow down to the second level).
However, I am not sure if I should set the width: 100% or height: 100%. The images are have more length than width, and I have to preserve that aspect ratio. Obviously if someone's browser window is a square they can't fit seamlessly, I am just wondering what strategies people have used to get this four seamless row appearance.
Thanks
Putting my comment into a more well thought out answer this morning. This one uses image elements as opposed to CSS backgrounds.
Try something like this, perhaps?
http://jsfiddle.net/d58Az/
<div class="container">
<div class="one"><img src="http://placehold.it/350x150" /></div>
<div class="two"><img src="http://placehold.it/350x150" /></div>
<div class="three"><img src="http://placehold.it/350x150" /></div>
<div class="four"><img src="http://placehold.it/350x150" /></div>
<div class="five"><img src="http://placehold.it/350x150" /></div>
<div class="six"><img src="http://placehold.it/350x150" /></div>
<div class="seven"><img src="http://placehold.it/350x150" /></div>
<div class="eight"><img src="http://placehold.it/350x150" /></div>
</div>
And then in your CSS:
.container {
width: 100%;
height: 100%;
}
img {
width: auto;
height: 100%;
position: absolute;
left: 50%;
top: 50%;
-moz-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
-o-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
.one,
.two,
.three,
.four,
.five,
.six,
.seven,
.eight {
position: absolute;
overflow: hidden;
}
.one, .two, .three, .four {
top: 0;
bottom: 50%;
}
.five, .six, .seven, .eight {
top: 50%;
bottom: 0;
}
.one, .five {
right: 75%;
left: 0;
}
.two, .six {
right: 50%;
left: 25%;
}
.three, .seven {
right: 25%;
left: 50%;
}
.four, .eight {
left: 75%;
right: 0;
}
In certain browsers the two rows won't line up absolutely perfectly, so I might try overlapping them a tiny bit (eg. Give .one, .two, .three and .four a bottom value of 50.5%).
Note that if you care about IE 8 you'll likely need to position the image with JS instead of CSS, as transform is not supported.
edit: To answer your question, "Is it absolutely necessary to set right and left offsets?" – not both of them, no. However I'm using them instead of declaring explicit widths. Setting left: 25%; and right: 50%; is more or less equivalent to left: 25%; width: 25%; It's just a matter of preference, really!
http://jsfiddle.net/HexM4/1/ <- this is probably not what you want...right?
http://jsfiddle.net/HexM4/3/ <- how is this?
div {
width: 25%;
float: left;
}
img {
width: 100%;
display: block;
}
4 divs, 4 columns, each one 25% in width with 2 images stacked inside of it verticaly. To prevent ugly whitespace, "display: block;" on img elements as well.
P.S.: Of course if all images in one row have the same height, you're settled. Any of those 2 jsfiddles should make you happy.
EDIT: Oops, misunderstanding?
Of course you cannot always fill 100% of both width and height (and not more than 100%!) with 2 rows of images, at least not without affecting their aspect ratio. Or cutting them in half here or there, in case you add many many images to each column in my example (+"overflow: hidden;" on parent div, which is absolutely positioned (or fixed) and sized at 100% of height and 100% of width of user's browser window). No solid solution I can possibly think of.
tl;dr: aspect ratio of user's viewport can, and does differ from one to the other. No, you can't always fit the same 8 pictures in it without changing their aspect ratio.

Issue with CSS Enlarge on Hover Effect

I found a nice tutorial for making my images enlarge (like a zoom effect) on hover. The main difference between my needs and a tutorial is that I want my all images contained in a single box like container. So when I implemented the tutorial I realize that part of the enlarged image gets cut off when you hover. The effect is constrained to the container. I would like a way for the zoom to go wherever it needs to go on the page. (So you can see the whole zoomed image)
Here is my implementation of the tutorial: http://mulnix.contestari.com/wp/example225/1.php
JSFiddle: http://jsfiddle.net/dsRAH/
Original Code
Remove the overflow: hidden and all other overflows,
than for your images containers DIV remove float:left; and add display:inline-block;
* {
margin: 0;
box-sizing: border-box;
}
.wrapper {
position: relative;
background: #000;
color: #fff;
z-index: 0;
}
.photos {
position: relative;
display: flex;
flex-flow: row wrap;
}
.photo {
box-shadow: 0 0 0 2px #444;
margin: 5px;
position: relative;
max-height: 200px;
transform: translateZ(0);
transition: transform 0.5s;
}
.photo:hover {
z-index: 1;
transform: translateZ(0) scale(1.6);
}
.photo img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.photo-legend {
position: absolute;
bottom: 0;
width: 100%;
padding: 1em;
background: rgba(0,0,0,0.3);
}
<div class="wrapper">
<div class="photos">
<div class="photo">
<img src="https://placehold.it/200x150/0bf" />
<div class="photo-legend">TEST DESCRIPTION</div>
</div>
<div class="photo">
<img src="https://placehold.it/200x200/f0b" />
</div>
<div class="photo">
<img src="https://placehold.it/200x150/bf0" />
</div>
</div>
</div>
It's not perfect but it's a start. I changed the overflow:hidden; in the wrapper to visible. I also put your code into jsfiddle so people can tinker with it.
http://jsfiddle.net/m8FXH/
You can try to use z-index. An element with greater z-index is always in front of an element with a lower z-index. If you main container is not overflow:hidden than you can try this out.
here is an example where you can see how it works. Hope that is helpful.
https://developer.mozilla.org/en-US/docs/Web/CSS/z-index
I would suggest giving your divs one of the following classes:
colleft for the ones that are at left column
colright for the ones that are at right column
rowtop for the ones at the top row
rowbottom for the ones at the bottom row
And then assign them the following properties
.colleft {
transform-origin-x: 0%;
}
....
transform-origin-x: 100%;
transform-origin-y: 0%;
transform-origin-y: 100%;
(respectively)
That will make the zoom go in the desired direction.
evan stoddard modified fiddle