Achieving an Overlapping image in a flex container with object-fit - css

Hey there i have asked a similar question before and was able to achieve it , the thing is that i had to use a png image, the downside is that its way too big.
After some research i found a method using a svg container and a alpha and beta channel of the image.
However the main difficult i ran into is to get object-fit working so the image will always cover the full 50% of its flexbox container... is that even possible? what am i missing..thanks a lot.
https://codepen.io/HendrikEng/pen/RVzYoR?editors=0100
.c-hero {
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
background: grey;
height: 30px * 15;
text-align: center;
&__image {
display: flex;
margin-bottom: -60px;
margin-top: 60px + 19px;
max-height: 682px;
min-height: calc(100% + 140px);
object-fit: cover;
object-position: top;
width: 50%;
}
&__item {
align-self: center;
width: 50%;
}
}
<section>
<div class="c-hero">
<svg class="c-hero__image" preserveAspectRatio="xMinYMin" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="transparentmask">
<image width="100%" height="100%" xlink:href="http://i.imgur.com/n080w42.png"></image>
</mask>
</defs>
<image mask="url(#transparentmask)" width="100%" height="100%" xlink:href="http://i.imgur.com/LTgnz9E.jpg"></image>
</svg>
<div class="c-hero__item">
<p>Lorem Ipsum</p>
</div>
</div>
</section>

Please put the following css to your codepen:
/**
* #define c-hero; weak
*/
.c-hero {
align-items: stretch;
display: flex;
flex-direction: row;
justify-content: center;
background: grey;
height: 28.45vw;
text-align: center;
&__image {
flex: 1 0 auto;
min-height: 130.96%;
}
&__item {
align-self: center;
width: 50%;
}
}

Though the question suggests of using overlapping images the actual scenario if I interpret it correctly is to have an image and a filled container side by side. The image to be used is the one having a little transparency at it's bottom. So while our eyes might differentiate the difference, for a browser its just the whole image.
Since you want the Height of the container next to the image = to be of the height of the image - the height of the transparent/white region.
There are few ways it can be achieved
1) Using 2 separate images:
The part which looks like it's overlapping can be a different image with absolute positioning having z-index greater than the background image element.
The background image element and the next filled-container can have the same height.
2) If we have a fixed height for image then we can for this particular case use 86% of the image height for the other half. It will produce the same illusion. 86% because the background fully covered is 86% of that of the whole image. Yeah I measured the pixel ratio using GIMP.
This particular case has more to do with the image size you are using rather than some programming skills. Though what you seek can be achieved.
To replicate that I created this responsive solution in codepen.
.wrapper {
max-width: 1200px;
margin: 0 auto;
}
.hero-img {
background-image: url(http://i.imgur.com/CkwLRd0.jpg);
background-size: cover;
background-position: bottom;
background-repeat: no-repeat;
width: 100%;
height: 100%;
}
.banner {
display: flex;
}
.half {
width: 50%;
height: 400px;
}
.red {
background: indianred;
}
.text-holder {
height: 86%;
}
<div class="wrapper">
<div class="banner">
<div class="half">
<div class="hero-img"></div>
</div>
<div class="half">
<div class="red text-holder"></div>
</div>
</div>
</div>
Please note that the wrapper is set to max-width: 1200px due to the relative image size used.
Let me know if it solved your issue or if you need some more help.

Related

How to make absolute element in relative element responsive?

I have problem with change size while manipulating browser size. I need to keep one column on another so I use relative + absolute combination.
I'm wondering if there is an option with only CSS to make such element responsive.
<div class="clock">
<div id="apDiv3" class="opening">
<div class="clock">
<img id="apDiv2" class="clock" src="./assets/stoper-01.png" usemap="#image-map">
<img id="apDiv1" class="clockArrow" src="./assets/stoper-01-arrow.png">
<map name="image-map">
<area area settings>
...
</map>
</div>
</div>
</div>
div.clock {
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
img.clock {
position: relative;
}
.clockArrow {
position: absolute;
}
You could try using the CSS calc() function like the given eg.
.top-img{
...
width: calc(var(--background-img-width) - var(--offset));
...
}
Here, add --background-ing-width to your :root and apply it in .background-img's width. Then you can add --offset in your :root and add to .top-img as shown and tweak these two variables to your liking.
I'm wondering if there is an option with only CSS to make such element responsive.
Here's a sample:
.wrapper{
height: 100vh;
margin: 0 30%;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
min-width: max-content;
}
.circle{
background-image: url(https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fc1.staticflickr.com%2F1%2F694%2F23104548209_fed5c6d1cd_b.jpg&f=1&nofb=1);
height: 50vh;
width: 50vh;
border-radius: 50%;
background-size: 100% 100%;
display: flex;
align-items: center;
padding: 1.3vh;
}
.rec{
flex: 1;
height: 15vh;
background-image: url(https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.cameraegg.org%2Fwp-content%2Fuploads%2F2012%2F09%2FSony-DSC-RX1-Sample-Image.jpg&f=1&nofb=1);
background-size: 100% 100%;
}
<div class="wrapper">
<div class="circle">
<div class="rec"></div>
</div>
</div>
You can make use of viewport height and width to make the elements responsive. More on units here.

CSS: Element in flexbox container won't appear unless it or the container are assigned a specific height

I'm trying to create a vertical line inside a flexbox container div, and am finding that unless I give either the line or the container a specific height (like 100px instead of a percentage), the line won't show. Examination with devtools shows that the line has 0 height, even though the container has a non-zero height. I'm guessing that maybe the rendering engine somehow doesn't know about the container's height at the time it's rendering the line? I'd like to find a way to make this work with percentages in order to make the container and line responsive.
jsfiddle: [https://jsfiddle.net/jjorsett/d0852yhx/25/][1] Set .line's height units to px and it will show up.
css and html:
<div class="container">
<img class="image" src="http://via.placeholder.com/100x250"/>
<div class="line">
</div>
</div>
.container {
background: yellow;
display: flex;
height: auto;
justify-content: space-around;
align-items: center;
}
.line {
border-left: .25em solid #f60;
height: 50%;
}
.image {
object-fit: contain;
width: 25%;
}
[1]: https://jsfiddle.net/jjorsett/d0852yhx/25/
Just remove align-items: center; from your container and height: 50% from your child and see the magic.
.container {
background: yellow;
display: flex;
height: auto;
justify-content: space-around;
}
.line {
border-left: .25em solid #f60;
}
.image {
object-fit: contain;
width: 25%;
}
<div class="container">
<img class="image" src="http://via.placeholder.com/100x250"/>
<div class="line">
</div>
</div>
When you align your item in the center it will automatically shrink your child container according to the children of your child div.
For the benefit of anyone else coming across this, I got the behavior I wanted by using javascript as follows (fiddle here: https://jsfiddle.net/jjorsett/d0852yhx/62/)
<div class="container">
<img class="image" src="http://via.placeholder.com/100x250"/>
<div id="line">
</div>
</div>
.container {
background: yellow;
display: flex;
height: auto;
justify-content: space-around;
align-items: center;
}
#line {
border-left: .25em solid #f60;
height: 50%;
}
.image {
object-fit: contain;
width: 25%;
}
window.onresize = adjustLineSize;
window.onload = adjustLineSize;
function adjustLineSize() {
var line = document.getElementById("line");
var desiredLineHeight = line.parentElement.clientHeight/2;
line.style.height= desiredLineHeight + "px";
}

how to put text over image without absolute positioning

I am using bootstrap for layout, one of the difficulties I have run into is about how to put the text over image. I have tried all things I can do such as using background-image which does not work. One of the approaches is to place image as relative and put the text in the absolute position.
However for my issue, I can't use absolute position because I have so many images and texts' lengths are varied. So I have to solve issue this by using align-center..
If someone is familiar with this issue, could you give some advice for this problem.. I have to put the text over the image on the very center vertically and horizontally.
<div class="row justify-content-center">
<div class="col-sm-auto">
<img src="img/1.jpg">
</div>
<div class="col-sm-auto">
<img src="img/2.jpg">
</div>
<div class="col-sm-auto">
<img src="img/3.jpg">
</div>
</div>
If the image source isnt changing, then you can try setting background: url(img/1.jpg) from CSS and adjust its position using background-position
Check out the fiddle here.
http://jsfiddle.net/yktvod54/2/
html
<div class="row justify-content-center">
<div class="col-sm-auto image-1">
text1
</div>
<div class="col-sm-auto image-2">
text2
</div>
<div class="col-sm-auto image-3">
text3 with longer text
</div>
css
.col-sm-auto {
color: lightgreen;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.col-sm-auto.image-1 {
width: 200px;
height: 150px;
background:
url("https://vignette.wikia.nocookie.net/disney/images/8/89/Cute-Cat.jpg/revision/latest?cb=20130828113117");
background-size: cover;
}
.col-sm-auto.image-2 {
width: 200px;
height: 200px;
background: url("https://vignette.wikia.nocookie.net/disney/images/8/89/Cute-Cat.jpg/revision/latest?cb=20130828113117");
background-size: cover;
}
.col-sm-auto.image-3 {
width: 250px;
height: 250px;
background:
url("https://vignette.wikia.nocookie.net/disney/images/8/89/Cute-Cat.jpg/revision/latest?cb=20130828113117");
background-size: cover;
}
Set the image as a background to a div, make that div display:flex; justify-content: center; align-items: center; and give it a width/height. The flex alignments will push everything to the center of the div, but it needs a height/width or the div will only be the size of the text. Add flex-wrap: wrap; and the text will wrap around, but there isnt a nice breakpoint like with word-break
I can't use absolute position because I have so many images and texts' lengths are varied
You can use relative lengths for positioning you texts so they will be centered whatever their size.
You will need the translate CSS function as well.
.image-wrapper {
width: 400px;
position: relative;
}
.image-wrapper img {
width: 100%;
height: auto;
}
.image-wrapper figcaption {
width: 100%;
position: absolute;
top: 50%;
transform: translateY(-50%);
text-align: center;
font-size: 2em;
color: white;
}
<figure class="image-wrapper">
<img src="https://image.ibb.co/n5wsKU/bg3.jpg" alt="A nice pic!">
<figcaption>A text that fits on one line</figcaption>
</figure>
In case you still don't want to use absolute positioning, here is another solution using a background-image instead of an img tag:
.image-wrapper {
width: 400px;
height: 300px;
display: flex;
}
.image-wrapper.image-01 {
background: url('https://image.ibb.co/n5wsKU/bg3.jpg') center center / cover;
}
.image-wrapper p {
margin: auto;
font-size: 2em;
color: white;
}
<div class="image-wrapper image-01">
<p>Some text</p>
</div>

Background image size inside flexbox not the same between Chrome and Firefox

I have an interesting issue where the background image of an element is not showing up the same between the two browsers. Chrome 65, FF 59.
I'm using the technique to show a ratio of the background image using padding-top percentage, where height is zero.
A codepen is also included.
https://codepen.io/anon/pen/OvGeeJ
A quick thing to note. The content div was only for visually knowing when the flex container ended.
It seems like the way % is calculated is different.
body{
border: 0;
padding: 0;
margin: 0;
}
.flex{
display: flex;
position: relative;
width: 100%;
flex-direction: row;
flex-wrap: wrap;
height: 300vh;
background: black;
align-items: flex-start;
}
.stickybg{
height:0;
width: 100%;
background-image: url(https://i.imgur.com/8bKkEfR.jpg);
background-size: 100% auto;
background-repeat: no-repeat;
padding-top: 19%;
}
.content{
height: 100vh;
background: #111;
}
<div class="flex">
<div class="stickybg"></div>
</div>
<div class="content"></div>
As dholbert said in a comment, it appears FF beta 60 has the issue fixed.
A workaround is to use VH or VW units which in my case would simulate the same thing.
Replacing
padding-top: 19%;
for
padding-top: 19vw;

Make an image shrink to available height without expanding its parent

I'm trying to create a two-column section where:
Columns have same width (responsive)
The height of block is defined by the height of image contained in left column after it stretches to 100% of it's parent.
In the right column there are several elements one of which is a link containing image.
I want that link with image from last paragraph to shrink it's height containing original image aspect ratio without stretching the it's container when the image has portrait orientation.
Not sure it its possible with plain CSS. Tried with flexbox and grid layout but I must be missing something.
I prepared a fiddle: https://jsfiddle.net/Kuznets/8u6c70ku/3/
* { box-sizing: border-box }
.wrap { max-width: 80%; margin: 0 auto; }
.container { display: flex; }
.left, .right {
flex: 0 0 50%;
border: 1px solid black;
}
.left {
position: relative;
display: flex;
align-items: flex-end;
}
.left div.left-text {
position: absolute;
color: white;
padding: 1em;
font-size: 200%;
}
.should-set-height {
width: 100%;
}
.right {
display: flex;
flex-direction: column;
align-items: center;
justify-content:space-between;
}
<div class="wrap">
<div class="container">
<div class="left">
<img class="should-set-height" src="https://dummyimage.com/200x240/aaaaaa/ffffff" alt="">
<div class="left-text">
This is a beautiful slogan
</div>
</div><!--/.left-->
<div class="right">
<header>Product title</header>
<a class="fit-height" href="javascript:void(0)">
<img class="should-shrink" src="https://dummyimage.com/200x400/aaaaaa/ffffff">
</a>
<div class="price">$ 19.99</div>
<button class="button-black">Add to basket</button>
</div><!--/.right-->
</div><!--/.containter-->
</div><!--/.wrap-->
One way you could accomplish this would be to have the left image set to have width: 100%, height: auto; then use a background image for the right container.
Here's a quick demo on CodePen: https://codepen.io/patriziosotgiu/pen/NaBmZe?editors=1100
You could also add extra rules, like for instance a min-width for the left column, or have those columns fit in one column for mobile.
Note: I assumed the left image to be larger than 200x240px

Resources