fill a div with an image in a responsive way - image

I am looking for a css3 responsive technique to have two side-by-side divs (stacked on smaller screens), one with text, the other one filled entirely with an image. At minimum, the image aspect ratio must be maintained; ideally both divs should always be squares of the same size (even when stacked).
Edit - fiddle:
https://jsfiddle.net/marekjedlinski/zdwdhLmg/
html:
<div class="outer outer-left">
<div class="inner inner-text inner-text-left block-orange">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas pharetra lorem in ligula volutpat euismod. Nullam eu lorem tellus. Donec luctus lacus in felis blandit quis accumsan nulla imperdiet. Phasellus lorem quam, egestas et scelerisque ac, consequat nec diam. Nunc elit elit, venenatis at eleifend eget, feugiat eu elit.</p>
</div>
<div class="inner inner-img">
<img src="image-1-300.jpg" />
</div>
</div>
<div class="outer outer-right">
<div class="inner inner-img">
<img src="image-2-300.jpg" />
</div>
<div class="inner inner-text inner-text-right block-green">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas pharetra lorem in ligula volutpat euismod. Nullam eu lorem tellus. Donec luctus lacus in felis blandit quis accumsan nulla imperdiet. Phasellus lorem quam, egestas et scelerisque ac, consequat nec diam. Nunc elit elit, venenatis at eleifend eget, feugiat eu elit.</p>
</div>
</div>
css:
* {
box-sizing: border-box;
}
html, body {
width: 100%;
font-size: 18px;
margin: 0;
}
.outer {
display: flex;
flex-direction: row;
}
.outer-left {
flex-wrap: wrap-reverse; /* when wrapped, image must sit on top of text */
}
.outer-right {
flex-wrap: wrap;
}
.inner {
flex: 1 1 300px; /* grow, shrink, basis */
}
.inner-img {
background: #563D7C;
text-align: right;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden
}
.inner-img img {
flex-shrink: 0;
min-width: 100%;
min-height: 100%
}
/* below only text styling for text divs, not relevant */
I can get some of the way using flexbox. This is the starting point, the ideal situation:
When the browser window grows however, the images get stretched:
At minimum, I want the aspect ratio to be maintained. It's OK if the image gets clipped, but ideally I would like the squares to grow as squares (both for image and text), so that the image would be proportionally resized.
Now, when horizontal space shrinks and the divs get stacked, the images are again stretched:
Here i still want the image divs and the text divs to remain perfect squares, but at the very least the aspect ratio must be maintained
Ideally, like this:
I can use flexbox or any earlier techniques, but I need this to be fairly compatible, not bleeding-edge (object-fit seems too futuresque, for example).
There are similar questions here and here, and they come close, but do (not solve this specific issue.)

edit ?? your fiddle works fine ?!
if background and object-fit is not the answer and you 'd like to use flex, i believe best is to start with square image and center content aside it.
You can use mediaquery to switch display behavior of divs and reset order.
here is an example:
/* ================================== */
/* DEMO USING A SINGLE FLEX CONTAINER */
/* ================================== */
/* use your own tags, class and sizes */
/* ================================== */
div {
display: flex;
flex-wrap: wrap;
width: 80%;
min-width: 300px;
max-width: 800px;
margin: auto;
}
div > * {
flex: 1 1 340px;
min-width: 50%;
}
div > div {
background: green;
display:flex;
align-items:center;
padding: 1em;
margin: 0;
box-sizing: border-box;
color:white;
}
div div:first-of-type {
order: -1;
background:rgb(148, 98, 39);
}
div:before {
content: "";
display:inline-block;
vertical-align:middle;
padding-top: 100%;
width:0;
}
div p {
display:inline-block;
vertical-align:middle;
max-width:99%;
}
#media screen and (max-width:866px) {
div div , div div:first-of-type {display:block;order:0;}
}
<div>
<img src="http://lorempixel.com/300/300/cats">
<div><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
Mauris placerat eleifend leo.</p></div>
<img src="http://lorempixel.com/300/300/animals">
<div><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus
lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor,
facilisis luctus, metus</p></div>
</div>

Related

CSS drop cap displays differently in Firefox and Safari. How do I adjust for this?

I'm struggling to find the right combination of CSS to help ensure my drop cap on my blog posts display the same in all browsers. I primarily use Safari and do my design work there. How it renders in Safari is my preference.
In Firefox, the drop cap hangs low and the text doesn't wrap around the letter. I added a negative bottom margin and now the text wraps. But it is still hanging too low. I really want this consistent.
What can I do to remedy this? Thank you.
This is my website here.
Create Drop Cap : Float the first character of the para to the left.
.firstcharacter {
float: left;
color: #903;
font-size: 75px;
line-height: 60px;
padding-top: 4px;
padding-right: 8px;
padding-left: 3px;
font-family: Georgia;
}
<p>
<span class="firstcharacter">L</span> orem ipsum dolor sit amet, consectetur adipiscing elit. Mauris tristique lobortis orci ac lacinia. Fusce eu purus eget diam vehicula auctor nec eu elit. Morbi consequat facilisis orci vel malesuada. Donec ultrices
molestie sollicitudin. Aliquam pharetra libero enim. Donec et suscipit massa. Donec dui odio, dignissim non sodales et, tincidunt a sapien. Phasellus elit nibh, adipiscing sed blandit vel, interdum et arcu.
</p>

Forcing image to be in same line as column of text

I'm not sure what I'm doing wrong here. I'm trying to force an image to be in the same line as a few columns of text, but it keeps shifting down like in this image: http://imgur.com/Hs43rXF. The left image is what I want it to look like, but I get the right image.
I've already tried display:inline and floats, but neither works. This is my code:
.page {
margin-top:50px;
padding-left:50px;
padding-right:50px;
position:relative;
width:1000px;
height:450px;
}
.leftcolumn {
margin-top:50px;
margin-left:0px;
width: 250px;
}
.middlecolumn {
margin-left:300px;
margin-right:320px;
margin-top:50px;
float:left;
display:inline;
}
.verticalimage {
margin-right:0;
margin-top:0;
float:right;
display:inline;
vertical-align:middle;
}
<div class="page">
<div class="leftcolumn">text <br> text <br> text</div>
<div class="middlecolumn">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet lorem velit. Nullam et metus eget nunc egestas laoreet et quis ligula. Vivamus lobortis sodales pulvinar. Nunc malesuada pretium ornare. Aliquam ut erat at magna pellentesque elementum. Fusce facilisis lorem et tortor euismod bibendum.</div>
<img class="rightverticalimage" src="picture1.png"/>
</div>
Thanks.
I tried this for ya. I took stuff out just so you understand the code. You can edit at your liking.
CSS
.page {
margin:5%;
width:100%;
height:450px;
}
div {
width:25%;
margin-left:3%;
float:left;
background-color:red;}
I made the BG red just so you can see where the div starts and stops
HTML
<div class="page">
<div>text <br /> text <br /> text</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet lorem velit. Nullam
et metus eget nunc egestas laoreet et quis ligula. Vivamus lobortis sodales pulvinar. Nunc
malesuada pretium ornare. Aliquam ut erat at magna pellentesque elementum. Fusce facilisis lorem
et tortor euismod bibendum.</div>
<div>
<img class="rightverticalimage" src="picture1.png"/>
</div>
</div>
Put the IMG in a div to help control it better.
Id also download FIREBUG onto Firefox cuz it helps with that stuff.
You're mixing a couple of different methods here. Firstly as you may have noticed with your leftcolumn, if you make a div display:inline it won't hold its width. This is because in order to render with a width or margins, an element must be block level (which divs are by default). Additionally, setting the left margin on the middlecolumn with the left div already there will set its left hand side to be at 550px within the container (250 for the leftcolumn and an additional 300 for left margin), margins and widths are cumulative.
So then two ways to do this are (I've left out your extra margins for brevity):
Using floats:
.leftcolumn
{
width: 250px;
float:left;
}
.middlecolumn
{
width: 250px;
float:left;
}
This will leave the two divs as block elements allowing them to behave as they normally would, setting the width on the two columns and continue the flow around them, since the image is an inline element, it will continue to flow as well. What this approach does do however is leave the container only as high as the image element since a floated element doesn't sit in the page flow in the same way.
Using display: inline-block
.leftcolumn
{
display: inline-block;
width: 250px;
}
.middlecolumn
{
display: inline-block;
width: 250px;
}
This will set the divs as inline-block allowing you to set a width on them, but rendering them as an inline element. The benefit of this is that the .page element will get the height of the divs automatically. It does, however break in ie7 since that doesn't render inline-block elements correctly.
I've intentionally left adding the width onto the image element since it will be the same across both approaches (just set display:block and float it, or set display: inline-block)

Image max-width (non floated) use space next to floated div?

The site I'm working on will display lengthy articles on screen. The site is responsive so everything you see on screen will re-size and re-flow to accommodate different screens. Previously we had a two column layout where the articles would be in the left floated div. And a side bar of shorter content would be in the right hand floated div.
It was decided that since the right hand content was so short there was lots of wasted white space beneath it. I was asked to try and incorporate the right hand column into the left hand div so the text would wrap around it.
That part was pretty easy, I just floated the now embedded right hand column into the article and the written text wrapped around it.
See this JSFiddle:
http://jsfiddle.net/TheMonkxx/2aucA/1/
Here is the HTML for the page:
<div class="parent">
<div class="right_content" align="right"></div>
Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Maecenas vitae nunc arcu. Cras tortor velit, consectetur
quis consectetur vel, ultrices eu nisl. Pellentesque convallis orci ligula,
id pharetra mauris. Vestibulum eleifend, turpis eget commodo dapibus, diam
magna nunc auctor elit, nec molestie libero quam quis mi. Donec interdum
velit non arcu sollicitudin eu ullamcorper lectus venenatis. Vivamus at
lacus magna. Proin in diam semper urna fermentum molestie sit amet sit
amet augue. Nulla sit amet massa eu risus laoreet laoreet eget sed erat.
Aliquam quis enim in odio porta consequat. Ut egestas urna et erat iaculis
et aliquam libero auctor.</div>
Here is the CSS
.parent {
border: 1px solid green;
width: 200px;
float: right;
}
.right_content {
width: 25%;
height: 150px;
float: right;
background-color: red;
margin: 0 0 7px 7px;
}
The problem comes in when I try to add images to the article content. Since the site is responsive, I want the images to have max-width: 100% applied. However when I do that the images go 100% of the parent container and push any written content beneath the images gets pushed after the right hand column. See this fiddle:
http://jsfiddle.net/TheMonkxx/2a66J/
Here is the updated HTML for the page:
<div class="parent">
<div class="right_content" align="right"></div>
<img src="http://www.thetop22.com/wp-content/uploads/2012/01/Black-Keys-Banner-3.png"
/>
Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Maecenas vitae nunc arcu. Cras tortor velit, consectetur
quis consectetur vel, ultrices eu nisl. Pellentesque convallis orci ligula,
id pharetra mauris. Vestibulum eleifend, turpis eget commodo dapibus, diam
magna nunc auctor elit, nec molestie libero quam quis mi. Donec interdum
velit non arcu sollicitudin eu ullamcorper lectus venenatis. Vivamus at
lacus magna. Proin in diam semper urna fermentum molestie sit amet sit
amet augue. Nulla sit amet massa eu risus laoreet laoreet eget sed erat.
Aliquam quis enim in odio porta consequat. Ut egestas urna et erat iaculis
et aliquam libero auctor.</div>
And the updated CSS:
img {
max-width:100%;
}
.parent {
border: 1px solid green;
width: 200px;
float: right;
}
.right_content {
width: 25%;
height: 150px;
float: right;
background-color: red;
margin: 0 0 7px 7px;
}
Giving the image a pre-defined width fixes the layout but it causes problems for the responsive nature of the site. I also will have some articles which have images at various places in the copy, so I can't always predict an image will be beside the right hand column.
Any ideas or suggestions how I can get the desired layout and keep the responsive aspect working? Thanks!
Although this is old, I've just figured out a good and simple solution using jQuery.
CSS Part
First we need to set all the images to be small so they can fit next to the floating div. let's say 75%;
.parent img {
max-width:100%;
width: 75%;
}
jQuery Part
Then we want to reset the width of all images below the floating div:
jQuery(document).ready(function(){
var h = jQuery(".right_content").height(); //get floating div height (let's say it's dynamic).
jQuery('.parent img').each(function(){ //loop through all images in content
jQuery(this).removeAttr('style') //remove any disturbing inline styles. optional.
var p = jQuery(this).position(); //get each .wp-caption position
var top = p.top; //top position
if(top > h){ //if img is below the floating div
jQuery(this).css("width", "initial") //change img width to original (or anything you like)
}
});
});
hope it help somehow.
Without a script with which to do some calculations, you might have to settle for smaller images.
http://jsfiddle.net/2a66J/2/
img {
max-width:72%;
float: left;
}
Technically, your site isn't "responsive". It's "fluid". If it was responsive you could set fixed max-widths based on viewport size and have 100% image width for all scenarios. The minor drawback is that you aren't usually using 100% of the available viewport width for your page with a responsive design.
One way to look at this, however it is not very efficient and be very bloated if you are working with lots of images.
If what you posted on jsFiddle is all that you have to work with, then my suggestion is to add a around said article image. You will then constraint this to a percentage and either float it left or right with a secondary class.
HTML
<div class="article_image article_image_flleft"><img src="http://www.thetop22.com/wp-content/uploads/2012/01/Black-Keys-Banner-3.png"
/></div>
CSS
.article_image{
width: 50%;
}
.article_image_flleft{
float: left;
}
Fiddle:
http://jsfiddle.net/D8ELj/1/
As isherwood points out, setting various viewports at be more beneficial in the long run.

Scroll one vertically centered DIV without scrolling the other in the same box

Been working on this all night, had no idea it would be so hard. My goal is explained in words within this fiddle, if you just wanna skip to that: http://jsfiddle.net/6VZeD/
Basically, I want a floated, fixed-size testimonial box to contain two elements, a.part and .full, both of which are vertically centered, even with multiple lines. When .full overflows, causing a scrollbar, I want to scroll .full while a.part remains vertically centered. I can't absolutely position a.part because it needs to center vertically at any size. So I wrapped a.part in an absolutely positioned element, but that scrolls along with .full. No bueno.
I left some elements out of the fiddle for simplicity, but in case it matters, I'm using jQuery isotope to position the fixed-size boxes, and I'm expanding the boxes (width, height, top-margin, and left-margin change) on hover. So I'm happy to add divs within .testimonial, but I can't wrap anything around .testimonial (though I can add classes to it). I started exploring jQuery solutions involving .hide() and .offset() but things started to get messy, especially because I'm using CSS transitions heavily. So I'm hoping to avoid Javascript if possible.
Here's the fiddle HTML:
<div class="box praise testimonial">
<div class="abs1">
<a class="part" href="#">stay vertically centered!<br/>even if you scroll!</a>
</div>
<div class="abs2">
<div class="full">
<p>This text is larger than its containing box, and I want a scrollbar to appear. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae nisl at justo sodales congue. Praesent sed arcu sit amet dolor molestie venenatis. Curabitur et consequat libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed posuere lectus nec est viverra faucibus scelerisque massa fermentum. Donec ultricies bibendum tincidunt. Sed sit amet mi massa, a egestas arcu. Maecenas vitae libero metus. Proin dolor lorem, molestie ut ullamcorper sit amet, varius sit amet urna. Nunc aliquet scelerisque dui, et tristique quam molestie vitae. Etiam ac justo sapien. Etiam ipsum ante, porttitor posuere placerat id, congue quis neque. Nunc et elementum odio. Sed vulputate semper erat, a lobortis dolor porttitor ut.</p>
</div>
</div>
</div>
<div class="box praise testimonial">
<div class="abs1">
<a class="part" href="#">stay vertically centered!<br/>even if you scroll!</a>
</div>
<div class="abs2">
<div class="full">
<p>this<br/>should<br/>stay<br/>centered<br/>too!</p>
</div>
</div>
</div>​
And the CSS:
body {
    color: #fff;
}
a { color: #fff; font-size: 18px; font-weight: bold; text-decoration: none; }
.box {
    display: inline-block;
    position: relative;
    float: left;
    overflow: hidden;
    margin: 20px;
    background: #777;
}
.testimonial, .testimonial .abs1, .testimonial .abs2, .testimonial a.part, .testimonial .full {
    height: 250px;
    width: 250px;
}
.testimonial:hover {
    overflow: auto !important;
}
.testimonial a.part {
    display: table-cell;
    vertical-align: middle;
    text-align: right;
}
.testimonial .abs1 {
    position: absolute;
    top: 0;
    left: 0;
}
.testimonial .abs2 {
    position: absolute;
    top: 0;
    left: 0;
}
.testimonial .full {
    display: table-cell;
    vertical-align: middle;
    opacity: 0.5
}
Any help would earn my undying appreciation.
Try out the solution in this fiddle which also centers mulitple lines of text over images.

Max width doesn't work in a flexible box model in firefox?

I'm trying to make a layout using the new css3 flexbox model. I want a page that occupies 100% of the height, using has a fixed footer and header and the remaining content is on a column in the middle. The content column should occupy 100% of the width up to a fixed maximun width. Also, everything should be aligned in the center.
I managed to build it exactly to spec in this demo wich works great in chrome or any webkit based browser. But it breaks in firefox, where adding the "max-width" property makes everything a fixed column aligned to the left.
Can anyone enlight me on why this is not working in firefox? Is it a different interpretation of the spec, or is it an error in my code?
This is the HTML of the demo:
<div class="container">
<div class="header">Header</div>
<div class="content">
<div class="fixed">
<h1>Title</h1>
<div class="someText">
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla vehicula sodales risus quis rhoncus. Donec suscipit lorem ante. Nullam tempor, lorem sit amet faucibus dictum, est nisl aliquam felis, a tempor arcu massa sit amet felis. Donec a blandit mi. Sed posuere, lacus eu scelerisque porttitor, turpis sem aliquam nulla, ut rutrum sem libero a felis. Morbi nec sodales odio. Nulla facilisi. Sed consectetur pellentesque arcu, in laoreet nulla semper ac. Pellentesque vulputate sem eget eros condimentum in malesuada dui convallis. Vivamus tristique velit id justo laoreet vestibulum. Nulla orci nisl, vulputate vitae facilisis sit amet, ultricies id massa. Sed eget faucibus magna. Integer a leo sem, hendrerit fermentum libero.</p>
<p>In gravida faucibus dui, quis bibendum est ornare nec. Cras ac metus a dui rhoncus mattis. Nulla ut hendrerit est. Cras sed sem felis, venenatis tincidunt ipsum. Vestibulum id sodales ligula. Nunc sit amet neque vel ante aliquam commodo. Aenean elit felis, imperdiet sagittis lacinia ut, tincidunt accumsan arcu. Vivamus dapibus ligula a est convallis eget tincidunt libero interdum. Nunc mattis, odio et tincidunt egestas, orci ante pharetra nulla, hendrerit ultrices nunc ipsum nec sem. Vestibulum egestas leo pulvinar massa mollis sit amet dapibus velit venenatis. Etiam molestie posuere lacinia. Nam ut nulla elit, ac tincidunt tellus. Nulla mollis metus id ante accumsan et mattis est ultricies. Morbi nec nunc nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
</div>
<div class="footer">
<div class="fixed">Footer</div>
</div>
</div>
and this is the CSS:
body, html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
background:black;
}
.container {
height: 100%;
width: 100%;
display: -webkit-box;
-webkit-box-orient: vertical;
display: -moz-box;
-moz-box-orient: vertical;
}
.header, .footer {
background-color: #32403C;
height: 40px;
width: 100%;
margin: 0;
line-height: 40px;
vertical-align: middle;
text-align: center;
color: #FFF;
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
display: -moz-box;
display: -webkit-box;
-webkit-box-flex: 0;
}
.content {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-flex: 1;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-flex: 1;
-webkit-box-align:center;
-moz-box-align:center;
box-align:center;
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
}
.fixed {
background:#787;
-moz-box-flex: 1;
-webkit-box-flex: 1;
box-flex: 1;
width:100%;
max-width:480px;
overflow:hidden;
display: -webkit-box;
display: -moz-box;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
}
.someText {
-webkit-mask-image: -webkit-linear-gradient( black, black 75%, transparent 95%);
-moz-box-flex: 1;
-webkit-box-flex: 1;
box-flex: 1;
overflow:scroll;
}
.content { background: #876; }
.colorLight { background-color: #A6687B; }
.colorMedium { background-color: #8C605F; }
.colorDark { background-color: #735E5A; }
What you're using in Gecko there is the XUL flexbox model, which has nothing to do with the old CSS flexbox drafts you were apparently reading (which also have nothing to do with the current flexbox drafts, which use a totally different display value, etc).
In particular, display: -moz-box has been around for 10+ years and has whatever behavior it has, while the flexbox draft you were reading is much newer and has behavior that's quite different from the -moz-box behavior. The WebKit flexbox implementation postdates the first W3C drafts or is contemporaneous with them, so is closer to what those drafts talks about. But again, the current drafts are completely different from those early ones...

Resources