Expand Column 1 to max width when column 2 is absent - css

Here is my markup:
<div class="wrapper">
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mi ipsum, gravida quis eleifend at, vestibulum at nibh. Nunc faucibus pellentesque nunc, vitae ultricies nibh interdum eu. Proin a est sed eros suscipit pretium ac sit amet tortor.</p>
<p>Vivamus feugiat, neque non tincidunt iaculis, dolor ipsum convallis libero, condimentum malesuada leo nulla a turpis. Praesent sed metus ipsum. Cras semper condimentum mauris. Nulla eleifend blandit facilisis. Phasellus gravida tempus eros, molestie cursus nisi imperdiet non. Donec dapibus.</p>
</div>
<div class="adverts"></div>
<div class="clear"></div>
</div>
Fiddle here -- feel free to modify and test
I want a CSS solution that makes the content width equal to max available width or max available width - 120px depending on whether adverts div is present or not. The div may or may not be present depending on whether the page is supposed to show ads or not. The solution must work in older versions of IE.

#Salman, if you rearrange the order of the two divs then you can do this without any widths, you just float:right the "adverts" div and don't float the content
as per one of the other answers you cannot right float a div after an unfloated one in IE to achieve this same effect without a width/margin being involved
added: Here's Your example fiddle updated : http://jsfiddle.net/clairesuzy/EqYnw/8/
Example Fiddle
The jQuery just toggles the actual ad-element to show that if there no content in the adverts div it will collapse the overflow usage is explained in the code.
I'm not sure if your "not present" div is the actual "adverts" div or the elements inside it, but this should work for both as the content will default to 100% of whatever is left over
Code for info:
CSS:
html, body {margin: 0; padding: 0;}
.wrapper {
overflow: hidden;/* Makes wrapper contain its floated children */
zoom: 1; /* Makes wrapper contain its floated children in IE6 and below */
border: 1px solid #666;
background: #ddd;
}
.content {
border: 1px solid #000;
background: #fff;
overflow: hidden; /* to not wrap under adverts if content is longer - optional if you want the wrap */
zoom: 1; /* equivalent of overflow for IE6 and below */
}
.adverts {
float: right;
border: 1px solid #00c;
}
/* put any widths on the actual advert element */
.ad-element {width: 200px; height: 30px; background: #0f0;}
HTML:
<div class="wrapper">
<div class="adverts"><div class="ad-element">.</div></div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mi ipsum, gravida quis eleifend at, vestibulum at nibh. Nunc faucibus pellentesque nunc, vitae ultricies nibh interdum eu. Proin a est sed eros suscipit pretium ac sit amet tortor.</p>
<p>Vivamus feugiat, neque non tincidunt iaculis, dolor ipsum convallis libero, condimentum malesuada leo nulla a turpis. Praesent sed metus ipsum. Cras semper condimentum mauris. Nulla eleifend blandit facilisis. Phasellus gravida tempus eros, molestie cursus nisi imperdiet non. Donec dapibus.</p>
<button>Show hide ads div</button>
</div>
</div>

I assume column 1 is the content of div.content, there's at leas two ways you can get this to use max available space when the second column (div.adverts) is empty.
You can let the wrapper and content be non-floating, and let the adverts one float to the right. The non-floated divs should use all available space, and the right float should cause the text to wrap around it. As long as the adverts div (when not empty) is taller than the content it will appear as two columns. (I assume the clear div is a float clearing hack or something?)
You could also use a table (not politically correct, but a lot easier to make it work in older browsers). Let the table be 100% widht, and don't specify any widht for the table cells. An empty cell should use zero space. (This will give a two column layout even if the lenght is different without any complicated css)
In any case: To avoid bugs where defining styles for an empty element causes it to be visible, style the sub elements instead, if they're not present the css will not apply anyway, like this:
/*gives all direct subchild divs 300px widht*/
.adverts>div{ width: 300px; }

You could use the general sibling selector + for the case the .advert div is not in the HTML at all.
Let the .advert float right, and have it before your .content div in the HTML (for CSS selector)
<div class="wrapper">
<div class="adverts"></div>
<div class="content"></div>
</div>
.content
{
float: left;
width: auto;
background-color: cyan;
}
.adverts
{
float: right;
width: 120px;
height: 600px;
background-color: lime;
}
Use the sibling selector to define the smaller width if the .adverts div exists.
.adverts + .content {
width: 130px;
}
This will not work dynamically with show() and hide(). If you require that dynamically, you have to remove the .advert from the DOM.
Here is a fiddle with a demonstration using detach() instead of hide() (worked on a VM in IE6).

Related

Flexbox - Weird img sizing issue

Weird issue keeps happening with this.
I want one of my flex items (an image) to be set to certain dimensions (w:300px h:300px).
When I open it to preview in my browser the image appears squashed up in the container as a flex item would normally behave (the text takes up most of the space.)
As soon as I resize my browser by even 1px the img then resizes to its specified dimensions (w:300px h:300px).
Is this what is supposed to happen? I'm using the Treehouse workspace text editor so I don't know if it's a bug with that or I'm doing something wrong?
Thanks,
.con {
display: flex;
background: gainsboro;
font-size: 1.8em;
}
.con img {
width: 300px;
height: 300px;
margin: 0 10px;
}
<div class="surgery con">
<img src="../img/cloud.jpg">
<p>Lorem ipsum dolor sit amet, urna sollicitudin pede sollicitudin fusce adipiscing vitae. Commodo egestas. Ut tempus, molestie integer in integer, pellentesque sed egestas duis, commodo sapien pellentesque turpis nulla tempor.</p>
</div>
Here's a screenshot of what it looks like when I open to preview:
http://imgur.com/a/Ejp8R
Here's what it looks like as soon as I expand the browser:
http://imgur.com/a/xT5Yr
I suggest you to use min-width property. It will help you to avoid the weird img stretching.
JsFiddle: https://jsfiddle.net/5pbqfyam/
.con {
display: flex;
background: gainsboro;
font-size: 1.8em;
}
.con img {
min-width: 300px;
height: 300px;
margin: 0 10px;
}
<div class="surgery con">
<img src="../img/cloud.jpg">
<p>Lorem ipsum dolor sit amet, urna sollicitudin pede sollicitudin fusce adipiscing vitae. Commodo egestas. Ut tempus, molestie integer in integer, pellentesque sed egestas duis, commodo sapien pellentesque turpis nulla tempor.</p>
</div>

correct notation of css text indent

Problem:
I have to indent my text. I have had a lot of problems with it, so I need to learn how to do it correctly now. On the desktop version the indent is looking fine. The problem is when I see on a responsive point of view, all the text is going out of control. Here is the version I have now:
Here is the version after I do a text indent on an iPhone 5 with the CSS below:
Code:
feature-bar {
background-color: #f8f8f8;
height: 200px;
margin-top: 0px;
text-decoration: solid;
color: red;
text-indent: 100px;
padding-top: 20px;
}
Question:
How do I do a correct text indent, so it is also looking correct on a mobile?
UPDATE
After the answers I found out I can use <li> or vw. On a mobile point of view wanted that the clock 13.00 - 13.20 should stay on one line, and the text should start on the other line. Should I make a mediaquery with something for solving this?
SECOND UPDATE
Example on how it should look on mobile
The standard solution would be using left padding. Don't know what your HTML is like, but this would be something like
ul {
padding-left: 100px;
padding-right: 40px;
outline: 1px solid red;/* just for demo purposes to reveal the padding */
}
li {
padding-bottom: 20px;
list-style: none;
}
<p>Heading</p>
<ul>
<li>first item, showing what it looks like when an item wraps to more than one line asdf asdf asdf asdf sdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf</li>
<li>qwer</li>
</ul>
If you want extra vertical space around the list, you could do one of two things. Here I'm making the total space at the bottom of the ul 30px
ul {
padding-bottom: 10px;/* is in addition to the 20px from the last li */
}
or
ul {
padding-bottom: 30px;
}
li:last-child {
padding-bottom: 0;
}
(The second option can be more reliable: you don't have to think about the math, and the person working on the site doesn't have to remember/know that the last li is contributing padding. Not a big deal in a simple case like this, but useful to keep in mind in cases where the css is more involved)
No matter what you do, you'll probably want to do something like .some-class-name and .some-class-name li instead of the bare ul and li in my examples - otherwise this will style every list on your site!
Note that I'm using bottom padding rather than top - that isn't strictly necessary, but I find favoring bottom padding and bottom margin (as opposed to top) a good habit to get into. Knowing that spacing is almost certainly coming from the upper thing can make things easier to debug and/or adjust
Bonus
Following your update to the question: one way of putting the time on its own line on mobile: wrap the time in some element that displays inline on desktop and block on mobile. span is display: inline by default, making it a handy choice here. A generic solution would be
<li>
<span>mobile own line</span> other stuff
</li>
#media (max-width: yyypx) {
span {
display: block;
}
}
where yyy is your mobile break point. Again, that will probably be .some-class-name span.
Because this is a time value, you can be all beautifully semantic with the time element:
<li><time datetime="13:00/13:30">13:00–13:30<time> other stuff</li>
and then target the time in the css (see http://www.w3schools.com/tags/att_time_datetime.asp and https://stackoverflow.com/a/10403376/1241736)
instead of pixels, use viewport units , specificallyuse vw which is viewport width which will decrease as the width of the screen gets smaller
see here more CSS Units
see snippet below :
or better see here > jsfiddle ( you can resize here better )
.feature-bar {
background-color: #f8f8f8;
height: 200px;
margin-top: 0px;
text-decoration: solid;
color: red;
text-indent: 10vw;
padding-top: 20px;
}
<div class="feature-bar">
Lorem ipsum dolor sit amet, aenean sed egestas ultricies eget ornare, luctus proin malesuada. A ac lacinia. Vulputate molestie suspendisse nullam. Ornare velit ac vitae, duis duis, ac diam pede netus. Ipsum nibh ipsum, phasellus id quis vitae consectetuer blandit dolor.
</div>
<div class="feature-bar">
Nec nulla placerat aliquam nulla urna tellus, ac ligula imperdiet, facilisis laoreet nec egestas, porttitor ante, wisi blandit sit erat. Vestibulum fermentum ac. Amet augue, mattis nec integer lorem lorem. Neque enim, pulvinar leo lorem donec, ac in. Etiam nec vestibulum justo praesent mi, pharetra praesent erat enim et purus sed, vel porttitor morbi voluptatem ante pellentesque ligula. In interdum tellus elit volutpat, purus gravida vitae vivamus ante quis, at amet, urna scelerisque suspendisse quis tortor vestibulum.
</div>
UPDATE after your edit to the question .
use lists :
careful, ul has a default padding , change it to padding-left:5vw so it will get smaller when you resize the window
see snippet below or fiddle here : jsfiddle with list
ul {padding-left:5vw}
br { display:none;} /* if you want all content of `li` to be on same row , time and text */
#media only screen and (max-width: 767px) { /* mobile devices */
br { display:block; } /* time on one row, text on the next rows */
}
<h1>
program for seminar
</h1>
<ul>
<li>13.00 - 13.30 <br />
Lorem ipsum dolor sit amet, non leo arcu risus fermentum at quam. Ac tincidunt vel non, quisque at libero odio ac eu sed, lectus condimentum non scelerisque tortor ligula.
</li>
<li >14.00 - 14.30<br />
Consectetuer diam consequat cursus fusce odio, fusce lacinia quis sit, sed etiam consequat pulvinar. Ut nisl, sed vulputate, dui ut pede varius in aenean, blandit accumsan pellentesque.
</li>
</ul>
This happens because the text-indent only applies to a new rule. Where in your phone's example, the rule gets broken and therefore, goes to the start of the div.
Change text-indent: 100px into padding-left: 100px
In case you have other content that shouldn't be aligned, wrap the content in a span / div and apply the styling to this element.
This is tabular data. Just use a table, it's semantic and requires very little maintenance or media queries.
table {
width: 80%;
margin: auto;
color: red;
}
table tr td {
vertical-align: top;
}
table tr td:first-child {
white-space: nowrap;
}
<table>
<tr>
<td>11:30 - 12:30</td>
<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatum, nihil nam veniam perferendis facilis error.</td>
</tr>
<tr>
<td>12:30 - 13:30</td>
<td>Lorem ipsum dolor sit amet.</td>
</tr>
<tr>
<td>13:30 - 14:30</td>
<td>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iste, nihil!</td>
</tr>
</table>

Unexpected behavior changing inline-block and float with media query

I'm creating a responsive page with three elements. The left two elements are set to display:inline-block so they'll appear side-by-side. The third element is set to float:right so it will align to the right side of the page instead of being inline with the other two elements. I have a CSS media query that makes all three elements display vertically when the window is less than 600px wide.
When I shrink the window smaller than 600px and then stretch it out to be wide again, the third element does not display at the top of the page. It floats to the right side of the page, but there is space at the top as if it's placed below the other two elements.
I see this behavior on a Mac in Chrome 43 and Safari 7.1.6, but NOT in Firefox 38.0.5.
Why does this happen?
Is there any remedy?
I realize there are other ways to structure this layout to avoid this issue. I'm more interested in why this behavior occurs than in alternate methods, especially since it only seems to happen in specific browsers.
Here's an illustration of the issue:
Please see the demonstration below. Use the "Full page" button so that you can resize the window to test the media query.
div#image {
display: inline-block;
vertical-align: middle;
width: 30%;
}
div#image img {
max-width: 100%;
}
div#caption {
display: inline-block;
width: 20%;
}
div#text {
float: right;
width: 30%;
}
div#text p {
margin: 0 0 1em;
}
#media only screen and (max-width: 600px) {
div#image,
div#caption {
display: block;
width: auto;
}
div#text {
float: none;
width: auto;
}
}
<div id="image">
<img src="http://lorempixel.com/400/300/abstract/3/" alt="">
</div>
<div id="caption">
Caption goes here.
</div>
<div id="text">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat.</p>
<p>Sed quis velit. Nulla facilisi. Nulla libero. Vivamus pharetra posuere sapien. Nam consectetuer. Sed aliquam, nunc eget euismod ullamcorper, lectus nunc ullamcorper orci, fermentum bibendum enim nibh eget ipsum. Donec porttitor ligula eu dolor.</p>
<p>Proin at eros non eros adipiscing mollis. Donec semper turpis sed diam. Sed consequat ligula nec tortor. Integer eget sem.</p>
</div>
It's because of the float:none - for some reason* it remains stuck when you stretch back - just don't use it and you'll be fine. That div staying floated in a column won't probably make any difference anyway.
*(I suspect browsers may choose to ignore reverting the rules in this case to save on resources, since this sort of resizing is mostly done by developers for testing purposes and not so much by regular users - but it's just speculation)

Image Behind Header and Offset on X and Y

Using CSS, how can I display an image behind some text and also offset it on both the X and Y axis?
I have a design that is 950px wide, so I'm wanting want this image to remain 'in sync' with the rest of the header by placing it in a container that is centered and also 950px wide.
My problem is that instead of the image being 'a layer behind' the header text, it is instead displaying the image in full and pushing the rest of the contents down.
Any help is greatly appreciated.
IMAGE ADDED FOR CLARIFICATION
Thanks,
Andy.
use Percentage values in your background positions in your css
.divName {
background-position: 50%;
}
or using words like top or bottom ...
See the full list of values here
UPDATE;
use the image as a background image instead of inline html image
<div class='content'>
<p> Some content</p>
<p> More content</p>
.... even more content ...
</div>
Now the css:
div.content {
background-image: url('image path');
background-position: 50%;
}
This way the image will always be behind the content, and it will be in the center of the div.
See: http://jsfiddle.net/Fx5q3/
http://css-tricks.com/absolute-positioning-inside-relative-positioning/
https://developer.mozilla.org/en/Understanding_CSS_z-index/Adding_z-index
CSS:
#container {
width: 300px;
margin: 0 auto;
background: #ccc;
background: rgba(127,127,127,0.7);
position: relative
}
#behindImage {
background: url(http://dummyimage.com/150x150/f0f/fff) no-repeat;
width: 150px;
height: 150px;
position: absolute;
top: -30px;
left: -90px;
z-index: -1
}
HTML:
<div id="container">
<div id="behindImage"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis volutpat blandit. Morbi bibendum pharetra bibendum. Fusce sit amet lobortis odio. Proin ultricies, massa vel ornare fringilla, diam sem convallis arcu, nec laoreet massa leo nec dolor. Nullam vel massa ligula. Donec semper eros dapibus nibh dictum egestas ac nec libero. Maecenas et fringilla augue. Phasellus imperdiet urna in sem scelerisque adipiscing.</p>
</div>
Do you mean something like this example?
Oke, that's more clear. Now I'm pretty sure this is what you want.

Two column div layout, with one taking the remainder

Given the following html:
<body>
<div style="float: left; background: red">Hi</div>
<div style="float: left; background: blue">Hi again</div>
</body>
I want the 2nd div to take the remainder of the width off the page. Setting width 100% will make it wrap to the next line, and I don't know what else to set to fix it. The left column needs to be sized according to its content, while the right takes the reminding horizontal space.
I know I can do this with tables, but in the actual application, this causes other problems in IE6. In the application the left column is a tree, while the rest is the main view. The tree can be collapsed. In addition there are popup divs using Dojo. When a popup div is showed and moved, the right column (in table form) expands to overlap the left column in IE6. Yeah, this is a bug in IE, so I am trying to find an alternative layout to fix this issue. It works with divs, but now the main view doesn't expand to fill the screen in other browsers.
Here is a better broken version. I need to fix it so that table doesn't extend the page width and adds a horizontal scroll for this:
<div style="float: left; background: red; padding: 5px; margin: 5px;">Hi</div>
<div style="background: blue">
<table width="100%"><tr><td bgcolor="green">
Hi again
</td></tr></table>
</div>
This sounds precisely like the sort of problem flexbox is able to fix. Below I'm using standard flexbox syntax, but some legacy browsers may require prefixes in order to function properly.
<div class="columns">
<div class="column">
<p>Hello, World.</p>
</div>
<div class="column">
<p>Content Area</p>
</div>
</div>
.columns {
display: flex;
}
.column:nth-of-type(2) {
flex: 1;
}
This gives you the results you are looking for: one column that grows with its content, and another that simply takes up the remaining space. One suggestion here would be to apply a min-width value to the flexed column to prevent it from getting too small.
Demo: http://codepen.io/anon/pen/LglvH
Try this:
<body>
<div style="float: left; background: red; width: 200px; ">Hi</div>
<div style="background: blue; margin-left: 210px; ">Hi again</div>
</body>
This way your right div will take up the remainder of the space. But you will have to watch out for clearing.
In this solution, we have an auto-filling #left element which will fit #container. #right will be absolutely positioned over #left such that it always at the top right of #container. Furthermore, we have padding-right: Xpx; on the #left container so that its content never slips underneath #right.
CSS
#container {
position: relative; /* used to make the #right element absolutely position relative to #container */
}
#right {
width: 100px; /* define width */
position: absolute;
right: 0px;
top: 0px;
}
#left {
padding-right: 100px; /* match defined width */
}
HTML
<div id="container">
<div id="left"></div>
<div id="right"></div>
</div>
It looks like you need a table. I think you should try to solve your issues with ie6 and tables instead.
Try this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css">
* {
margin:0;
padding:0
}
html, body {
height:100%
}
#left {
background:red;
float:left;
height:100%;
overflow:hidden
}
#right {
background:blue;
height:100%
}
</style>
</head>
<body>
<div id="left">
<p><img src="http://www.google.be/intl/en_com/images/logo_plain.png" alt="Google" /></p>
</div>
<div id="right"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras suscipit massa vel nisi suscipit tincidunt. Proin tortor massa, pellentesque eget pharetra et, rutrum eu purus. Pellentesque iaculis justo a erat ultricies sodales. Nunc eu justo felis. Nullam fermentum erat sed ligula interdum consectetur imperdiet odio sagittis. Mauris sodales magna ornare dui imperdiet pretium. Donec augue erat, suscipit at aliquet vel, sodales id lorem. Aenean id fermentum est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam erat volutpat. Proin hendrerit ligula a neque placerat condimentum at ornare odio. Etiam metus augue, fringilla malesuada vestibulum eget, gravida sed mauris. Pellentesque non orci eget libero placerat vehicula. Vivamus iaculis bibendum risus, ac venenatis tellus consequat convallis. Nam tristique eros quis odio commodo venenatis. Suspendisse volutpat euismod mi eu facilisis. Quisque malesuada libero quis est suscipit et cursus augue rhoncus. Pellentesque molestie convallis nibh at pretium.</p></div>
</body>
</html>
There is only a little gap between the div's in IE6.

Resources