Shrink Image to fit flex column - html

I have a image that I would like to shrink in a flexbox column layout. I have read a bunch of pertinent threads but I still can't figure it out.
I want the right column to always have the same height of the left column and the image in the right column to fill the height of the remaining space not taken up by the text. Any thoughts? Thank you!
I would like it to look like this:
Codepen here: https://codepen.io/interzonestudio/pen/qBRPxzg
This is my HTML:
<div class="block-one">
<div class="block-one-left">
<img src="https://via.placeholder.com/300x400" alt="">
</div>
<div class="block-one-right">
<div class="block-one-right-top">
<img src="https://via.placeholder.com/300x400?text=Shrink+Me!" alt="">
</div>
<div class="block-one-right-bottom">
<p>Lorem ipsum dolor sit amet, consectetuer diiscing elit, sed diam nonummy nibh dolor it euismod tincidunt ut laoreet dolore.</p>
</div>
</div>
</div>
and this is my CSS:
.block-one {
width: 50%;
padding: 50px;
background: #9ac1e4;
margin: 0 50px 100px 50px;
display: flex;
min-height: 0;
min-width: 0;
max-width: 100%;
max-height: 100%;
}
.block-one-left {
width: 40%;
padding-right: 50px;
}
.block-one-left img {
width: 100%;
}
.block-one-right {
width: 60%;
display: flex;
flex: 1;
flex-direction: column;
}
.block-one-right-top {
height: 100%;
flex: 1;
}
.block-one-right-top img {
height: 100%;
max-width: 100%;
max-height: 100%;
min-height: 0;
min-width: 0;
width: auto;
object-fit: contain;
}

You can achieve this with a tiny piece of javascript to calculate the difference of left img height minus text height and set the right image height to that difference. Just place these 4 lines javascript in a <script></script>-tag just before the closing body tag.
Working example:
var max_height = document.querySelector('.block-one-left').clientHeight;
var text_height = document.querySelector('.block-one-right-bottom').clientHeight;
var shrink_height = max_height - text_height;
document.querySelector('.block-one-right-top').style.height = shrink_height + 'px';
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.block-one {
display: flex;
width: 600px;
margin: 0 50px 100px 50px;
padding: 25px;
background: #9ac1e4;
}
.block-one-left {
height: 300px;
margin-right: 25px;
}
.block-one-left img {
height: 100%;
}
.block-one-right {
width: 225px;
}
.block-one-right-top img {
height: 100%;
}
.block-one-right-bottom {
padding-top: 25px;
}
<div class="block-one">
<div class="block-one-left">
<img src="https://via.placeholder.com/300x400" alt="">
</div>
<div class="block-one-right">
<div class="block-one-right-top">
<img src="https://via.placeholder.com/300x400?text=Shrink+Me!" alt="">
</div>
<div class="block-one-right-bottom">
<p>Lorem ipsum dolor sit amet, consectetuer diiscing elit, sed diam nonummy nibh dolor it euismod tincidunt ut laoreet dolore.</p>
</div>
</div>
</div>
If you want it to be responsive you have to wrap the 4 lines in a function. Because you have to listen for at least two events (image loaded and window resized) it is much cleaner to call the function instead of having the 4 lines twice in your code.
Working example:
var left_img = document.querySelector('.block-one-left img');
function setHeight() {
var max_height = left_img.clientHeight;
var text_height = document.querySelector('.block-one-right-bottom').clientHeight;
var shrink_height = max_height - text_height;
document.querySelector('.block-one-right-top').style.height = shrink_height + 'px';
}
left_img.addEventListener('load', setHeight);
window.addEventListener('resize', setHeight);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.block-one {
display: flex;
width: 100%;
padding: 25px;
background: #9ac1e4;
}
.block-one-left {
width: 40%;
margin-right: 25px;
}
.block-one-left img {
width: 100%;
}
.block-one-right {
width: 50%;
}
.block-one-right-top img {
height: 100%;
}
.block-one-right-bottom {
padding-top: 25px;
}
<div class="block-one">
<div class="block-one-left">
<img src="https://via.placeholder.com/300x400" alt="">
</div>
<div class="block-one-right">
<div class="block-one-right-top">
<img src="https://via.placeholder.com/300x400?text=Shrink+Me!" alt="">
</div>
<div class="block-one-right-bottom">
<p>Lorem ipsum dolor sit amet, consectetuer diiscing elit, sed diam nonummy nibh dolor it euismod tincidunt ut laoreet dolore.</p>
</div>
</div>
</div>

Related

How do I create a border over div with content?

I have to create a div over which there is a 3px border, and this boundary is positioned over the content in the div, how can I do this without knowing the size of the block?
An example is in the image below:
My code: https://codepen.io/pen/yLObXvv
HTML:
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-md-4">
<div class="case-study">
<div class="case-study-image">
<img src="https://images.unsplash.com/photo-1551434678-e076c223a692?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80" class="img-fluid" alt="Intro image"/>
</div>
<div class="case-study-content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
</div>
</div>
</div>
</div>
CSS:
body {
background-color: #04142d;
}
.case-study {
color: #fff;
display: flex;
margin-top: 2rem;
flex-direction: row;
background-color: #0E53DD;
border-radius: 1rem;
overflow: hidden;
}
.case-study-image {
flex: 0 0 50%;
width: 50%;
}
.case-study-image img {
height: 100%;
max-height: 20rem;
object-fit: cover;
oject-position: 0 0;
}
.case-study-content {
flex: 0 0 50%;
padding: 1rem;
}
Please Use CSS ::after Selector with position: absolute
The coordinates of an absolute positioned element are relative to its parent. It is positioned automatically to the starting point (top-left corner) of its parent element.
body {
background-color: #04142d;
}
.case-study {
color: #fff;
display: flex;
margin-top: 2rem;
flex-direction: row;
background-color: #0E53DD;
border-radius: 1rem;
position:relative;
max-width:500px;
}
img {
max-width:100%;
}
.case-study-image {
flex: 0 0 50%;
width: 50%;
}
.case-study-image img {
height: 100%;
max-height: 20rem;
object-fit: cover;
oject-position: 0 0;
}
.case-study-content {
flex: 0 0 50%;
padding: 1rem;
}
.case-study:after {
content: '';
border: 3px solid yellow;
position: absolute;
width: calc(100% - 6px);
height: calc(100% - 6px);
border-radius: 5px;
right: -10px;
top: -10px;
}
<div class="case-study">
<div class="case-study-image"> <img src="https://images.unsplash.com/photo-1551434678-e076c223a692?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80" class="img-fluid" alt="Intro image"/> </div>
<div class="case-study-content">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<!DOCTYPE html>
<html>
<head>
<title>style</title>
<style>
div {
width: 200px;
height: 200px
background-color:white;
}
.move {
transform: (30px, 180px)
background: transparent;
border: 3px solid red;
}
</style>
</head>
<body>
<div class="move"></div>
<div></div>
</body>
</html>
you can use this and try to style it the way you want

Div position of "button" depends on content height

I'm working on the sidebar where we have a logo at the top and some bottom div. The middle div "content" has overflow: scroll and contains paragraph(s). So what I need... If I have only one paragraph (or two p) the button div should be positioned absolutely at the bottom of the content and if I have more paragraphs which have a bigger height than "content" div so then the button div will have position static (so will be scrollable).
And I need it only by CSS. Is it possible?
We need IE11+ support.
<div class="sidebar">
<div class="logo">logo</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tempor egestas ornare. Suspendisse potenti. Integer non euismod nulla. Quisque pretium est sit amet congue rhoncus.</p>
<div class="button">
Button
</div>
</div>
<div class="bottom"></div>
</div>
.sidebar {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 300px;
background-color: grey;
}
.logo {
position: absolute;
width: 100%;
height: 55px;
background-color: red;
}
.bottom {
position: absolute;
bottom: 0;
width: 100%;
height: 100px;
background-color: green;
}
.content {
position: absolute;
top: 55px;
bottom: 100px;
overflow-y: scroll;
}
.button {
display: inline-block;
padding: 1em 0 1em;
text-align: center;
width: 100%;
border-radius: 50px;
background-color: white;
}
You can use flexbox. Add this to your CSS:
.content {
display:flex;
flex-wrap: wrap;
}
.button {
align-self: flex-end;
}
That will render the button always at the end of the content div.

How can I extend an image's height equidistant beyond its full-width container?

I have an image I'd like to extend beyond its parent container, just on the top and bottom, the same distance. I'm able to achieve this effect on the top, but am not able to do so on the bottom. How can I achieve this effect while still remaining responsive and keeping remaining content within the parent?
I've tried various methods of absolute positioning, but kept breaking the grid. I was able to achieve what I have thus far using negative margins, but only on top.
This is the very basic code I have thus far and here's the jsfiddle.:
.band {
background-color: #ddd;
margin-top: 100px;
}
.contain {
margin: 0 auto;
max-width: 600px;
}
.row {
align-content: flex-start;
clear: both;
display: flex;
flex-flow: row wrap;
overflow: visible;
}
.col {
width: 50%;
}
.col-image {
margin-top: -20px;
}
p {
padding: 20px;
}
img {
display: block;
height: auto;
max-width: 100%;
}
<div class="band">
<div class="contain">
<div class="row">
<div class="col">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
<div class="col col-image">
<img src="https://via.placeholder.com/800x450?text=fpo">
</div>
</div>
</div>
</div>
Another solution using negative margins and absolute positioning on the image:
use negative margins for the offsetting of the second column,
using absolute positioning of the image in the second column ensures that the height is determined by the left column (because the row container is a flexbox and align-items: stretch is the default), and
use object-fit: cover to maintain image aspect ratio.
See demo below:
.band {
background-color: #ddd;
margin-top: 100px;
}
.contain {
margin: 0 auto;
max-width: 600px;
}
.row {
align-content: flex-start;
clear: both;
display: flex;
flex-flow: row wrap;
overflow: visible;
}
.col {
width: 50%;
}
.col-image {
margin: -20px 0 -20px 0; /* negative margin */
position: relative;
}
p {
padding: 20px;
}
img {
display: block;
height: 100%;
width: 100%;
object-fit: cover;
/* absolute positioning */
position: absolute;
top: 0;
left: 0;
}
<div class="band">
<div class="contain">
<div class="row">
<div class="col">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
<div class="col col-image">
<img src="https://via.placeholder.com/800x450?text=fpo">
</div>
</div>
</div>
</div>
Positioning seems to work
.band {
background-color: #ddd;
margin-top: 100px;
}
.contain {
margin: 0 auto;
max-width: 600px;
}
.row {
align-content: flex-start;
clear: both;
display: flex;
flex-flow: row wrap;
overflow: visible;
position: relative;
}
.col {
width: 50%;
}
.col-image {
position: absolute;
top: -20px;
bottom: -20px;
left: 50%
}
p {
padding: 20px;
}
img {
display: block;
height: 100%;
}
<div class="band">
<div class="contain">
<div class="row">
<div class="col">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
<div class="col col-image">
<img src="https://via.placeholder.com/800x450?text=fpo">
</div>
</div>
</div>
</div>
You can also play with background of the band element to simulate this
.band {
background:
url(https://via.placeholder.com/800x450?text=fpo) calc(50% + 160px) 0/auto 100%,
linear-gradient(#ddd,#ddd) center/100% calc(100% - 40px);
background-repeat:no-repeat;
margin-top: 100px;
}
.contain {
margin: 0 auto;
max-width: 600px;
}
.row {
display: flex;
flex-flow: row wrap;
}
.col {
width: 50%;
}
p {
padding:40px 20px;
}
<div class="band">
<div class="contain">
<div class="row">
<div class="col">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
</div>
</div>
</div>

Flexbox divs overlap and responsive

I am trying to make some elements overlap and staggered using flexbox, but I also need it responsive to stack when on mobile. I am new to flexbox and want to see if I can get some help making this responsive. Below is my html and css. As you can see when you run the snippet, it is not how I want it to look. This is my codepen and that is the desktop layout I would like, then I would like the divs to stack as it gets to mobile: https://codepen.io/ascarb1/full/zWZVRw/
Any help is really appreciated.
body {
max-width: 1600px;
width: 95%;
margin: 0 auto;
}
.home-story-container {
display: flex;
margin: 10em auto;
flex-direction: column;
justify-content: space-between;
align-items: left;
float: none;
}
.home-story-container .home-story-text-block {
height: 373px;
width: 618px;
background: #ddd;
align-self: flex-start;
flex-shrink: 0;
margin-left: 15em;
}
.home-story-container .home-story-text-block .home-story-text-content {
width: 60%;
margin: 4em 0 0 4em;
}
.home-story-container .home-story-image-block {
width: 640px;
align-self: flex-end;
flex-shrink: 0;
margin-right: 14em;
margin-top: -23em;
}
.home-story-container .home-story-video-block {
width: auto;
align-self: flex-start;
flex-shrink: 0;
margin-left: 21em;
margin-top: -10em;
}
.home-story-container .home-story-quote-block {
align-self: flex-end;
flex-shrink: 0;
margin-right: 16em;
margin-top: -9.5em;
width: 413px;
}
<div class="col-md-12">
<div class="home-story-container">
<div class="home-story-text-block">
<div class="home-story-text-content">
<h1>Lorem ipsum dolor sit amet</h1>
<br>
<p>Lorem ipsum dolor sit amet, malesuada quisque sit consectetuer adipiscing odit, sed tortor leo nunc, a vel erat ultricies.</p>
</div>
</div>
<div class="home-story-image-block"><img src="http://via.placeholder.com/640x373"></div>
<div class="home-story-video-block"><iframe width="560" height="315" src="https://www.youtube.com/embed/SkgTxQm9DWM?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen=""></iframe></div>
<div class="home-story-quote-block">
<p>Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet<br><span>Lorem ipsum dolor sit amet.</span></p>
</div>
</div>
</div>

How to make text in responsive circle <div> responsive as well

I have dealt with this problem for some days now and it's making me crazy, I want the text inside the circle to move in the same position inside the cirkle div when I make the screen smaller, as illustrated in the picture.
If you have any tips please share!
CSS Code and Html Code:
.circleBase {
border-radius: 50%;
}
.contact-circle {
margin-top: 29%;
margin-left: 4%;
position: fixed;
width: 23%;
height: auto;
padding-top: 23%;
background-color: rgba(255, 86, 86, 0.2);
}
#contact-text {
top: 20%;
bottom: 20%;
left: 18%;
font-size: auto;
position: absolute;
text-align: center;
width: 60%;
opacity: 1;
}
<div class="circleBase contact-circle">
<div id="contact-text">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
</p>
</div>
</div>
Use another method to center the text. Here is an idea with flex:
.circleBase {
border-radius: 50%;
}
.contact-circle {
position: fixed;
width: 23%;
height: auto;
padding-top: 23%;
background-color: rgba(255, 86, 86, 0.2);
}
#contact-text {
top: 0;
position: absolute;
bottom: 0;
left: 10%;
right: 10%;
display: inline-flex;
justify-content: center;
align-items: center;
text-align: center
}
<div class="circleBase contact-circle">
<div id="contact-text">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
</p>
</div>
</div>
Responsive web site - #media (min-width:450px) and (max-width:900px) { css style }
<div class="circleBase contact-circle">
<div id="contact-text">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit</p>
</div>
</div>
Css #media Example
.circleBase {
height:800px;
width:800px;
}
#media (max-width:479px) {
.circleBase {
height: 400px;
width:400px;
}
}