I have a situation where I have for example little boxes which follow each other one after each other and I want users to be able to toggle the show/hide of these elements, I have got them working like I want, but when the respective box is collapsed/hidden the content below it doesn't collapse upwards as well.
I understand why this is however, it's because using transform it still allocates the space for the element that you transformed out of it's original position; however I couldn't work out another way to do it in the same fashion as using a negative margin-top for some reason didn't animate smoothly like transform does.
CodePen: http://codepen.io/gutterboy/pen/GqRoJY
CodePen (margin-top version): http://codepen.io/gutterboy/pen/WxNGVG
HTML:
<div class="foo">
<header>
Header
Toggle
</header>
<div class="content-wrap">
<div id="content-1" class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cur id non ita fit? Et ille ridens: Video, inquit, quid agas; Quorum altera prosunt, nocent altera. Nulla erit controversia. Neutrum vero, inquit ille. Quis non odit sordidos, vanos, leves, futtiles?
Duo Reges: constructio interrete. Quare ad ea primum, si videtur;
</div>
</div>
</div>
<div class="foo">
<header>
Header
Toggle
</header>
<div class="content-wrap">
<div id="content-2" class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cur id non ita fit? Et ille ridens: Video, inquit, quid agas; Quorum altera prosunt, nocent altera. Nulla erit controversia. Neutrum vero, inquit ille. Quis non odit sordidos, vanos, leves, futtiles?
Duo Reges: constructio interrete. Quare ad ea primum, si videtur;
</div>
</div>
</div>
<div class="foo">
<header>
Header
Toggle
</header>
<div class="content-wrap">
<div id="content-3" class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cur id non ita fit? Et ille ridens: Video, inquit, quid agas; Quorum altera prosunt, nocent altera. Nulla erit controversia. Neutrum vero, inquit ille. Quis non odit sordidos, vanos, leves, futtiles?
Duo Reges: constructio interrete. Quare ad ea primum, si videtur;
</div>
</div>
</div>
CSS (SCSS):
.foo {
margin: 10px;
width: 400px;
header {
padding: 10px;
border: 1px solid #000;
border-bottom: 2px solid #000;
}
.content-wrap {
overflow-y: hidden;
transform-style: preserve-3d;
}
.content {
padding: 10px;
background-color: gray;
transform: translateY(0);
border: 1px solid #000;
border-top: none;
transition: 1s;
&.closed {
transform: translateY(-100%);
}
}
}
JS (jQuery):
$(document).ready(function() {
$('.toggle').on('click', function(e) {
e.preventDefault();
var content_id = $(this).data('content-id');
$('#content-' + content_id).toggleClass('closed');
});
});
Is there anyway to get the boxes below to collapse smoothly at the same time the proceeding box does?
Also note that the boxes are variable height and hence we can't use height, want to avoid hacky solutions like using a really high max-height and preferably avoid using any JS for the animation.
Your problem, delay at starting due to margin : -100% and the div is still not visible at margin : -40%
and
CSS transition do not animate when you add or remove class, It will only animate when you change the CSS properties. And You are directly adding and removing classes.
Here is another way to get this by jQuery :
$('.toggle').on('click', function(e) {
var content_id = $(this).data('content-id');
$('#content-' + content_id).slideToggle('slow');
});
Updated Codepen
Related
I've got a relatively long phrase that consumes way too much space on mobile devices. It looks something like this:
.artificial-phone-viewport {
width: 320px;
height: 500px;
border: 1px solid darkgrey;
}
.container {
width: 100%;
height: 100%;
}
.text {
/*
* Don't want to change font-size, because text
* sometimes maybe shorter and 2.2rem is perfect
* for phrases that are not as long
*/
font-size: 2.2rem;
}
<body class="artificial-phone-viewport">
<div class="container">
<div class="text">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Temporibus saepe illum a magni sequi error fugit dolore neque voluptates in laborum.
</div>
</div>
</body>
What I want is to make this text span at most, let's say, 10rem height. If it can't fit into 10rem of height, it should instead expand horizontally, maybe, overflowing its parent, maybe like this:
.artificial-phone-viewport {
width: 320px;
height: 500px;
border: 1px solid darkgrey;
}
.text {
font-size: 2.2rem;
white-space: nowrap;
}
<body class="artificial-phone-viewport">
<!-- Deleted container to reduce code, it actually
doesn't matter, because it anyway spans
100% width and height of its parent -->
<div class="text">
Lorem ipsum dolor, sit amet consectetur<br/>
adipisicing elit. Temporibus saepe illum<br/>
a magni sequi error fugit dolore neque<br/>
voluptates in laborum.
</div>
</body>
P.S. This snippet is just an example of what I want to see, I don't want any of these <br/>s or white-space: nowrap. Also I want the text to overflow its parent, because I then can use Javascript to scale it propertly, but it is not very relevant for the question, I suppose.
So I figured out a way to do it with Javascript, although I don't like it too much. I just increased the width of the element, until the height was small enough, like this
const text = document.querySelector('.text')
const rem = parseFloat(
getComputedStyle(document.documentElement).fontSize
)
let width = text.clientWidth / rem
while(text.clientWidth > 10*rem) {
width++
text.style.width = `${width}rem`
}
.artificial-phone-viewport {
width: 320px;
height: 500px;
border: 1px solid darkgrey;
}
.text {
font-size: 2.2rem;
}
<body class="artificial-phone-viewport">
<div class="text">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Temporibus saepe illum a magni sequi error fugit dolore neque voluptates in laborum.
</div>
</body>
It's not very nice, but it works for me. If someone finds a way to do it without javascript, I'm open to other solutions
I'm trying to create masonry layout using css grid layout. All items in grid have variable heights. And I don't know what items will be. So I can't define grid-row for each item. Is it possible to start each new item right after end of previous in column?
Code I'm trying:
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, 330px);
align-items: flex-start;
grid-column-gap: 10px;
grid-row-gap: 50px;
}
.item {
background: black;
border-radius: 5px;
}
<div class="wrapper">
<div class="item" style="height:50px"></div>
<div class="item" style="height:100px"></div>
<div class="item" style="height:30px"></div>
<div class="item" style="height:90px"></div>
<div class="item" style="height:80px"></div>
<div class="item" style="height:50px"></div>
<div class="item" style="height:70px"></div>
<div class="item" style="height:40px"></div>
</div>
full codepen here
In your question you are setting the height of each item individually. If you are happy to do this then a Masonry layout can easily be achieved with grid.
Instead of setting a height for each item set grid-row-end so that each item spans a certain number of rows.
<div class="item" style="grid-row-end: span 5"></div>
The height of the item will then depend on the values of grid-auto-rows and grid-row-gap you have set for the grid.
I have made a Codepen here: https://codepen.io/andybarefoot/pen/NaprOB
If you don't want to individually set the grid-row-end value for each item you can use a bit of JavaScript to do it dynamically. I put another "container" div inside each item and measure the height of this container to calculate how many rows the item needs to span. I do this on page load, and again for each item when any images are loaded (as the height of the content will have changed). If you combine this approach with a responsive layout then you should also recalculate on page resize as the width of the columns may have changed and this will affect the height of the content.
Here's my full example with responsive column resizing: https://codepen.io/andybarefoot/pen/QMeZda
If you have items with variable widths you can still achieve a similar effect but the packing of the grid won't be perfect and the item order may be changed to optimise the packing.
I wrote a blog on Medium about this approach in case it is of interest: A Masonry style layout using CSS Grid
You can set span values for grid-row-end dynamically (with a bit of JS, like the one based on my Codepen experiment in the example below) and use the dense keyword for grid-auto-placement:
const gridStyles = getComputedStyle(document.querySelector('.wrapper',null));
const rowHeight = parseInt(gridStyles.getPropertyValue('--grid-row-height'));
const gap = parseInt(gridStyles.getPropertyValue('--grid-gutter'));;
let makeGrid = function() {
let items = document.querySelectorAll('.item');
for (let i=0, item; item = items[i]; i++) {
// take an item away from grid to measure it
item.classList.add('is-being-measured');
let height = item.offsetHeight;
// calcylate the row span
let rowSpan = Math.ceil((height + gap)/(rowHeight + gap));
// set the span value for grid-row-end
item.style.gridRowEnd = 'span '+rowSpan;
// return the item into the grid
item.classList.remove('is-being-measured');
}
}
window.addEventListener('load', makeGrid);
window.addEventListener('resize', () => {
clearTimeout(makeGrid.resizeTimer);
makeGrid.resizeTimer = setTimeout(makeGrid, 50);
});
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, 330px);
--grid-gutter: 10px;
grid-gap: var(--grid-gutter);
--grid-row-height: 10px;
grid-auto-rows: var(--grid-row-height);
grid-auto-flow: row dense;
position: relative;
}
.item {
background: black;
color: white;
border-radius: 5px;
}
.item.is-being-measured {
/* temporary styles for measuring grid items */
position: absolute;
width: 330px;
top: 0;
left: 0;
}
.item > * { margin-left: 20px; }
<div class="wrapper">
<div class="item"><h3>1.1</h3><p>1.2</p></div>
<div class="item"><p>2.1</p><p>2.2</p><p>2.3</p><p>2.4</p><p>2.5</p></div>
<div class="item"><h2>3.1</h2></div>
<div class="item"><h2>4.1</h2><p>4.2</p><p>4.3</p><p>4.4</p></div>
<div class="item"><p>5.1</p><p>5.2</p><p>5.3</p><p>5.4</p></div>
<div class="item"><h2>6.1</h2><p>6.2</p></div>
<div class="item"><h2>7.1</h2><p>7.2</p><p>7.3</p></div>
<div class="item"><p>8.1</p><p>8.2</p></div>
</div>
This is one way to create the Masonry layout using only CSS.
*,
*:before,
*:after {
box-sizing: border-box !important;
}
article {
-moz-column-width: 13em;
-webkit-column-width: 13em;
-moz-column-gap: 1em;
-webkit-column-gap: 1em;
}
section {
display: inline-block;
margin: 0.25rem;
padding: 1rem;
width: 100%;
background: #efefef;
}
p {
margin: 1rem 0;
}
body {
line-height: 1.25;
}
<article>
<section>
<p>Lorem ipsum dolor sit amet, consectetur.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error aliquid reprehenderit expedita odio beatae est.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis quaerat suscipit ad.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nihil alias amet dolores fuga totam sequi a cupiditate ipsa voluptas id facilis nobis.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem ut debitis dolorum earum expedita eveniet voluptatem quibusdam facere eos numquam commodi ad iusto laboriosam rerum aliquam.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat architecto quis tenetur fugiat veniam iste molestiae fuga labore!</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit accusamus tempore at porro officia rerum est impedit ea ipsa tenetur. Labore libero hic error sunt laborum expedita.</p>
</section>
<section>
<p>Lorem ipsum dolor sit.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima asperiores eveniet vero velit eligendi aliquid in.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus dolorem maxime minima animi cum.</p>
</section>
</article>
Note: I didn't made the code, I found it an made some small adaptation,
the original code can be found here.
Please note that, as pointed out by Zen:
[...] the items are laid out top-to-bottom, left-to-right,
whereas what one usually expects (cultural assumptions excused) is
left-to-right, top-to-bottom layout. This is the showstopper for the usual CSS3-columns-based recommendations.
You can accomplish this with column.
.wrapper {
column-gap: 10px;
column-count: 4;
}
.item {
display: inline-block;
background: #000;
width: 100%;
border-radius: 3px;
}
It looks like you were trying to use a combination of flex and grid, which may have been confusing things. As far as I know, flex is relative to the rest of the items on the page, where setting a column affects items falling into those columns.
updated codepen
I'm using Bootstrap 3.3.2 to create two columns. Each column has a heading, a bordered div with text of an unknown length, and an image. I need the bordered divs with text to be the same height, but only when the columns are side by side. If the window is narrow enough for the columns to be stacked, they should not be the same height. How can I achieve this?
I realize I could use JavaScript to set the shortest div's height to be the same as the tallest div's height, but the problem with this method is that when the user decreases the width of their browser window, the text overflows outside of the div.
Here is my code (jsFiddle demo):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Title</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
<style>
.equal {
border: 3px solid #333;
padding: 8px;
}
img {
display: block;
margin: 20px auto 0;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6">
<h1>Foo</h1>
<div class="equal">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. His similes sunt omnes, qui virtuti student levantur vitiis, levantur erroribus, nisi forte censes Ti. Pisone in eo gymnasio, quod Ptolomaeum vocatur, unaque nobiscum Q. Eamne rationem igitur sequere, qua tecum ipse et cum tuis utare, profiteri et in medium proferre non audeas? Duo Reges: constructio interrete. Ex ea difficultate illae fallaciloquae, ut ait Accius, malitiae natae sunt. Est, ut dicis, inquit; Id enim ille summum bonum eu)qumi/an et saepe a)qambi/an appellat, id est animum terrore liberum. An est aliquid, quod te sua sponte delectet?</p>
</div>
<img src="http://placehold.it/350x150" alt>
</div>
<div class="col-md-6">
<h1>Bar</h1>
<div class="equal">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Tum Torquatus: Prorsus, inquit, assentior; Quid, quod res alia tota est? Maximus dolor, inquit, brevis est. Nihilo beatiorem esse Metellum quam Regulum. Honesta oratio, Socratica, Platonis etiam. Duo Reges: constructio interrete.</p>
</div>
<img src="http://placehold.it/350x150" alt>
</div>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</body>
</html>
I know this is similar to this question, but I think it's actually different.
var equal1 = $(".equal1").height();
var equal2 = $(".equal2").height();
if(equal1 < equal2 ){
$(".equal1").height($(".equal2").height());
} else {
$(".equal2").height($(".equal1").height());
}
Please, see this
Demo result
or
Demo with code.
Just with pure CSS you can solve it with flex.
You can add another class to your row class and then apply the styles on that class.
<div class="container">
<div class="row row-eq-height">
<div class="col-xs-6">
...
In the css add:
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap; /*to enable responsiveness*/
}
.row-eq-height > [class*="col-"] {
display: flex;
flex-direction: column;
border: 1px solid green;
}
You can check a demo here.
Updated !
Try DEMO
Using JavaScript
$(".equal2").height($(".equal1").height());
Do Read http://www.ejeliot.com/blog/61
I'm building a HTML document that is supposed to be semantically correct. Therefore, <aside> that is related to the website (i.e. sidebar) should be placed outside <article> and <aside> related directly to the article (if any) should be placed inside <article>.
That's not a problem with the left layout on my image because this will work:
<article>article</article>
<aside>sideabr</aside>
.article, .aside { float: left; }
.article { width: 70%; }
.aside { width: 30%; }
But what if main <h1> of the article is supposed to be placed above the article and the sidebar? I can't just nest the article and the sidebar in <article> because the sidebar is not a side note in the article. And I can't nest header + paragraphs in <article> because the sidebar will not align to paragraphs but to the header like in the first case.
Any idea how the HTML structure of such document should look like?
Most websites good as reference use the left version: http://twentytwelvedemo.wordpress.com/about-2/ so I can't find anything reliable to learn from.
This is how it should look like technically but can this be done in HTML at all?:
By separating article in two: heading and content (just a div) and then floating this content, you can achieve the desired effect.
aside may be floating too (you must then set a width) or be set to overflow: hidden.
You can't add a clearfix on article (or aside will stay below) so you've to put it on parent (here section). Same for background if it must have one.
Demo: http://codepen.io/anon/pen/BAjLr
CSS
section {
width: 500px;
background-color: tomato;
}
/* clearfix */
section:after {
content: '';
display: table;
clear: left;
}
/* article */
h1 {
margin-bottom: 0;
}
article .content {
float: left;
width: 300px;
background-color: lightgreen;
}
/* aside of section */
aside {
overflow: hidden;
color: white;
background-color: darkslateblue;
}
HTML
<section>
<article>
<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id laudantium beatae quae recusandae!</h1>
<div class="content">
<p>article Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nesciunt repudiandae nam commodi iusto ullam neque aliquam ut numquam. Cumque ut tempora consectetur quam velit ad incidunt necessitatibus saepe eos exercitationem.</p>
</div>
</article>
<aside>
<h2>sidebar</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam quae</p>
</aside>
</section>
I want to fit text in a <div> to the width of the <div>, but fit images in the same <div> to the width of the parent <div>
This diagram should make things clear:
(here's the URL if it's too small: http://dl.dropbox.com/u/2792776/screenshots/2012-01-22_1838.png)
I would solve this one of two ways. Here is idea #1:
CSS
#inner {width:400px; position:relative; float:left;}
HTML:
<div id="inner">
<img src="awesomeimage.jpg" alt="this awesome image" />
<p>text goes here</p>
<img src="awesomeimage.jpg" alt="this awesome image" />
</div>
SCRIPT:
<script>
var imgWidth = $(window).outerWidth();
$('#inner > img').css({
width : imgWidth + 'px'
});
</script>
This is assuming you have jQuery loaded up, and that you are using Javascript on your site. If you want to adjust the width of the image, for padding, margins, and borders, do so in the variable.
You can have the image scale with the window, like in the example used in this JS fiddle I created for another question: http://jsfiddle.net/D544n/1/
Idea #2: With Out Javascript.
CSS
#outer {width:100%;} /* Outer becomes irrelevant */
#inner {width:100%;}
#inner img {width:100% !important}
#inner * {width:400px;} /* Set all childs to 400 */
HTML:
<div id="outer">
<div id="inner">
<img src="awesomeimage.jpg" alt="this awesome image" />
<p>text goes here</p>
<img src="awesomeimage.jpg" alt="this awesome image" />
</div>
</div>
The selector for this was grabbed from another S.O. Question.
I don't think you are going to find a clear, simple way to do this. These are my two best ideas, and it could be solved other ways. If you are heading down this path to organize your content, you might want to re-think your strategy at accomplishing your goal.
What if you got rid of the inner div entirely but put a width of 400px on all p tags within the outer div? Then things would flow correctly and the images would be children of the outer div, so they could be limited by its width.
Of course, this could cause some problems if there are a lot of other elements that need to be contained within the 400px area, but if it's just the paragraphs and some headers then you're set.
edit
I refined my approach. I was inspired by Adam Dunn's answer.
All you need to do is wrap each img with a <div class="sanitize">|</div>. Either do it on the server side (recommended) or with a little jQuery wrap call (left for the reader as a homework).
Also don't allow divs only ps.
The secrets are:
Have the border/background in a separate div.border if you need any
Overwrite the max-width to inherit !important
http://jsfiddle.net/HerrSerker/PSPyZ/9/
HTML
<div class="container">
<div class="border"></div>
<div class="inner">
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. .</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut <div class="sanitize">
<img src="http://lorempixel.com/800/200/sports/2" /></div>
</p>
<div class="sanitize"><img src="http://lorempixel.com/800/200/sports/2" /></div>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
</div>
<br clear="left" />
</div>
CSS
.container {
position: relative;
width: auto;
border: 1px solid red;
}
.container > .inner {
border: 1px solid gold;
width: 100%;
min-width: 400px;
}
.container > .inner > * {
max-width: 400px;
}
.container > .inner .sanitize {
position: relative;
max-width: inherit !important;
border: 1px solid green;
width: 100%;
}
.container > .inner .sanitize > img {
display: block;
width: 100%;
}
.container > .border {
width: 400px;
position: absolute;
top: 1px;
left: 1px;
bottom: 1px;
height: 100%;
border: 1px solid silver;
}
First answer
Why not so?
See here for an example: http://jsfiddle.net/HerrSerker/PSPyZ/
With a little bit of js, you can do this with avoiding all the complication.
$(document).ready(function() {
//read every images
$("img").each(function(k,v) {
//get the width parent's parent
var width = $(this).parent().parent().innerWidth();
//use it
$(this).css('width',width);
});
});
Demo
You can use the CSS overflow property to allow the content to overflow the confines of the container. Try overflow: visible on your inner div.
Expanding on Lazarus' answer:
Set overflow:visible; on your inner div. Then use Javascript to set the max-width of images to the size of your outer div, i.e. the browser viewport. Something like this, maybe?
document.body.innerdiv.img.style.maxWidth = window.innerWidth + 'px';
#outer {position:absolute;top:0;left:1%;width:99%;}
#outer img{width:100%;position:absolute;left:0;}
The best I can thik of are the lines above but they wont wrap the text around cause absolute positioned elements are removed from the flow.
I think ellawren suggested the best solution till now : "got rid of the inner div entirely".
You say: "the contents of the DIV are set by users (and they might not use paragraphs)".
However you can run a simple REGEX pattern before stroring "the contents". The pattern will break text in divs/paragraphs where it is nedeed /before or after image tag/. Then you can style images separately.
Maybe there is some dirty css hack but hacks are never the best way to solve a problem.
HTML
<div class="outer">
<div class="inner"><p>Your content goes here</p>
<img src="http://dl.dropbox.com/u/2792776/screenshots/2012-01-22_1838.png" alt="" />
<p>Your content goes here</p></div>
</div>
CSS
.inner { float: left; width: 400px; overflow: visible; }
.inner img { width: 2000px; }
jQuery
var browserWidth = $(document).width();
$('div.inner img').css('width', browserWidth);
May do like this with pure css.
CSS
.container{
max-width:400px;
border:1px solid red;
}
.container > img {
width: 100%;
position:absolute;
height:200px;
}
img + p{
margin-top:200px;
}
Check this http://jsfiddle.net/PSPyZ/5/
Solution: Float the inner DIV left to make it not as wide as the outer DIV, then set max widths for the inner DIV and it's children.
HTML:
<div id="outer">
<div id="inner">
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<img src="image.png" alt="image">
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
CSS:
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#outer {
width: 100%;
height: 100%;
}
#inner {
max-width: 100%;
float: left;
}
#inner > * {
max-width: 400px;
}
#inner > img {
max-width: inherit !important;
}
DEMO: http://pastehtml.com/view/br8c4ht5n.html
(Resizing window shows OP requirements. Gray is outer DIV. Orange is inner DIV. Blue is actual IMG.)
I am sure you have tried this but doesn't this work
Edit:
<script type="text/javascript">
function viewport()
{
var width;
var height;
var e = window,
a = 'inner';
if ( !( 'innerWidth' in window ) )
{
a = 'client';
e = document.documentElement || document.body;
}
width = e[ a+'Width' ];
$('div#inner > img').attr('width', width);
}
</script>
You can read the browser width code from:http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
I just edited a bit and added the jQuery bit
#outer
{
width:100%;
float:left;
}
#inner
{
width:400px;
float:left;
}
<body onload="viewport();">
<div id="outer">
<div id="inner">
Text
<img scr="" />
Text
</div>
</div>
</body>
Example: http://projects.kausweb.com/stack
I am not sure if you wanted javascript thought
I've used the max-width method, in the past, but had to also include a min-width to keep my images from getting too skinny.
Also, if you treat that inner div as a series of content blocks, your document will probably flow a little more intuitively, and you won't need a lot of positioning, etc.
#outer > div { width:400px; border:1px dotted gray; }
#outer > img { max-width:100%; min-width:400px }
<div id="outer">
<div>Inner div block 1 content and whatnot. Inner div block 1 content and whatnot.<div>Nested block within div block 1 with image...<img src="http://jsfiddle.net/img/logo.png"></div></div>
<img src="http://www.alenawooten.com/wp-content/uploads/2012/01/images1.jpg">
<div>Inner div block 2 content and whatnot. Inner div block 2 content and whatnot.<div>Nested block within div block 2 with image...<img src="http://jsfiddle.net/img/logo.png"></div></div>
<img src="http://www.alenawooten.com/wp-content/uploads/2012/01/images1.jpg">
</div>
Here's a jsfiddle: http://jsfiddle.net/B4gKS/
Slide the center divider to see the effect.
I don't think you'll be able to achieve this using pure CSS. Here's an example using a little Javascript.
HTML
<div class="outer">
<div class="inner">
some text some text some text some text some text some text some text some text some text some text some text some text some text some text some text some text some text some text
<img src="http://tinyurl.com/7pl9cw8" />
<p>more text more text more text more text more text more text more text more text more text more text more text more text more text more text more text more text more text more text</p>
</div>
</div>
CSS
.outer {
margin: 40px;
border: 2px solid black;
padding: 10px;
min-width: 404px;
}
.inner {
border: 2px solid black;
width: 400px;
}
JS
function changeWidth() {
var ele = document.getElementsByTagName("img");
var width = (document.getElementsByTagName("div")[0].offsetWidth - 28) + "px";
for(var i = 0; i < ele.length; i++) {
ele[i].style.width = width;
}
}
window.onload = window.onresize = changeWidth;
DEMO
http://jsfiddle.net/XdAPU/