we have a requirement where form elements are laid out in 3 separate columns. The labels can have varying amounts of text and the form elements will be mainly input boxes and textarea's.
The designers want to ensure that the input elements are vertically aligned correctly.We are unable to use specific padding/margins as this is not flexible when the app is localized.
Please see the image below. The first row shows the issue we are experiencing and the second is how we would like it laid out. The only solution we have thought of is placing the label in a separate row to the actual form element. I cant imagine this would be good for accessibility.
Any tips really appreciated.
Here is a fiddle of the code so far - http://jsfiddle.net/nJZ6Y/4/
<div class="grid_4">
<div class="contents">
<label>TR 1 TD 1</label>
<input type="text" />
</div>
</div>
<div class="grid_4">
<div class="contents">
<label>Bonorum Fermentum Tortor Adipiscing Pharetra</label>
Here is the fiddle: http://jsfiddle.net/nJZ6Y/19/
You have to add a span inside each label, then add these CSS rules.
label {
min-height: 3em;
}
label span {
vertical-align: -3em;
display: inline-block;
}
Fiddle: http://jsfiddle.net/nJZ6Y/18/
I added a box around the label element and aligned it to the bottom. This only works if you know the approximate max-height of the text though. If the text goes longer than that it will fall out of the container and go incognito. Fred's answer is more elegant.
FYI: Bonorum in your lorem ipsum is a funny word...
.label-box {
position: relative;
}
.label-box {
height: 50px;
}
label {
float:left;
width:100%;
color:#fff;
position: absolute;
bottom: 0;
left: 0;}
Related
For a good long while I've been using a really nice column spanning method I stumbled across, wherein I can have a div with the class .boxcontainer and child .box elements, and using an :after pseudo-element on .boxcontainer, my .box columns justify nice and evenly across the page. Here are the all-important definitions:
.boxcontainer {
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
background-color: orange;
}
.boxcontainer:after {
content: '';
display: inline-block;
width: 100%;
height: 0px;
font-size: 0px;
line-height: 0px;
}
Most of my previous projects have been XHTML1 Transitional (which I have subsequently learned uses a limited quirks mode when compared to other DTDs), and using this method in XHTML1 the parent .boxcontainer always wrapped perfectly flush around the child .box elements.
However, working on a new project in HTML5, I've discovered that there appears to be an extra line added underneath the justified .box elements. You can see an example here: http://jsfiddle.net/RZQTM/1/ - click on Fiddle Options and change the DTD to just about anything else and you'll see what I mean - an orange 'band' appears underneath the justified blue boxes.
I think this is down to something in the :after pseudo-element being rendered almost like an additional line of content, but I have no idea how to fix it. Any tips on how to remove the extra space under the boxes would be most gratefully received.
The trick i use to make this extra line to vanish is to apply line-height:0; on parent ,
and reset line-height to 1.2em or whatever line-hight you had setted.
vertical-align:top;/* or bottom */ on :after elements ends up to swallow any vertical gaps left.
one exemple : http://codepen.io/gcyrillus/pen/dlvCp
A work around with extra markup and using CSS table-cells
I sometimes use the following. In the HTML, I add an extra element div.spacer:
<div class="boxcontainer">
<div class="box two">
<h3>This is the title</h3>
Lorem ipsum dolor amit ...</div>
<div class="spacer"></div>
<div class="box two">
<h3>This is the title</h3>
Lorem ipsum dolor amit ...</div>
<div class="spacer"></div>
<div class="box two">
<h3>This is the title</h3>
Lorem ipsum dolor amit ...</div>
<div class="spacer"></div>
<div class="box two">
<h3>This is the title</h3>
Lorem ipsum dolor amit ...</div>
</div>
For the CSS, I use display: table on the parent container and then display: table-cell on the .box child elements:
.boxcontainer {
background-color: orange;
display: table;
width: 100%;
}
.box {
vertical-align: top;
display: table-cell;
background-color: blue;
color: white;
font-family: Trebuchet MS;
}
The demo fiddle is: http://jsfiddle.net/audetwebdesign/xWfk2/
Internally, the CSS re-purposes the .spacer as sibling table-cells and the default spacing tends to be even because the .box elements have a fixed width.
This approach is ideal if the .spacer elements serve a useful purpose (have real content) and if you have other reasons to use table-cells, say vertical positioning control and so on.
I'm trying to layout a page which has anchor elements that I would like on a new line and centered. However these blocks are inside of <p> elements which are beside floating images.
Right:
http://test.sunnysidemarket.ca/right.jpg
Wrong:
http://test.sunnysidemarket.ca/wrong.jpg
So basically I have:
HTML:
<div class="content">
<div>
<img src="..." width="276" height="207" />
</div>
<div class="body">
<p>
...
<a class="mediaset" href="...">Link</a>
</p>
</div>
</div>
CSS:
.content img {
float: right;
}
a.mediaset {
margin: 0 auto;
width: 220px;
display: block;
overflow: auto;
}
Or what you can see in the jsfiddle: http://jsfiddle.net/CVkFw/
The issue is intermittent, sometimes it happens, sometimes it doesn't. What it appears to me to be is a bug in chrome where the overflow and margin properties are calculated but when the floating content loads, sometimes the browser doesn't layout the elements again.
There are ways of solving this using jQuery and modifying my HTML but I would really love to solve this with CSS if at all possible.
My best guess is that this erratic behavior is caused by overflow: visible applied in global.styles.css. The problem:
.node-article .field-name-body,
.node-synced-facebook-content .field-name-body {
overflow: visible;
}
I'm offering this suggestion because when I add this CSS override for overflow: hidden, that component appears to load "more solidly". The fix:
.node-article .field-name-body,
.node-synced-facebook-content .field-name-body {
overflow: hidden;
}
The selector itself might need to be adjusted depending on what it is intended to affect. (I'm obviously not that familiar your page's css code.) Hopefully this points you in the right direction though!
I'm not really sure how to best explain this. I'm trying to have three div elements positioned side-by-side; the first (left to right) is flexible-width, the second is also flexible width, the third is static width and it floated to the right. The first two are inside a div on the same level as the third; that is to keep to total width of the first two under a max-width.
Here is a jsfiddle of what I'm doing.
My problem is that when the text in the middle div is long, the middle div will drop below the first one, instead of having the text wrap. I can't give the middle one a max-width, because the first div is flexible and could get smaller. Any idea how I can go about fixing this?
I know it can be achieved by using a table, but I'd really prefer not doing so unless it's the only easy solution.
Edit: I decided to just do fixed width. The amount of work for required for this just wasn't worth it, especially considering that most of the time, the flexible width would never be used for me anyway.
if you wan a pure css based solution then it might be little difficult and also not much browser compatible. Though you can achieve this by using the css property called display:table ; and display:table-cell;. Again older browser, maybe IE-9 also won;t be able t render this.
Then you should go for the jQuery solution. You can use the following code-
$(document).ready(function(){
var w = 400 - $('.inner_container .left_box').width();
$('.inner_container .middle')css('width',w);
});
Thanks.
The display: table property and related properties, such as display: table-cell, have been supported in IE since version 8 -- as well as all versions of Firefox and Chrome/Safari.
Reference: http://caniuse.com/#feat=css-table
I believe it's the way to go in your case.
HTML
<div class="container">
<div class="inner_container">
<div class="left_box">
<p>Lorem ipsum dolor sit amet</p>
</div>
<div class="middle">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div class="right_static">Hi!</div>
</div>
CSS
.container {
position: relative;
width: 500px;
border: 1px solid #000;
overflow: auto;
}
.right_static {
position: absolute;
top: 0px;
right: 0px;
width: 100px;
background-color: green;
}
.inner_container {
display: table;
width: 400px;
overflow: auto;
}
.left_box {
display: table-cell;
background-color: red;
}
.middle {
display: table-cell;
background-color: #9999FF;
}
DEMO
http://jsfiddle.net/nd7qj/
By the way, you mentioned in your question that the leftmost div should have flexible width, but in the CSS you provided it had fixed width. So I didn't apply a width to it in my code.
I have the following markup:
<li id="CN2787">
<img class="fav_star" src="images/fav.png">
<span>Text, text and more text</span>
</li>
I want it so that if the text wraps, it doesn't go into the 'column' for the image. I know I can do it with a table (which I was doing) but this is not workable for this reason.
I've tried the following without success:
li span {width: 100px; margin-left: 20px}
.fav_star {width: 20px}
I also tried float: right.
Thanks.
EDIT: I want it to look like this:
IMG Text starts here and keeps going... and
wrap starts here.
Not like this:
IMG Text starts here and keeps going... and
wrap starts in the space left for the image.
Very simple answer for this problem that seems to catch a lot of people:
<img src="url-to-image">
<p>Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
img {
float: left;
}
p {
overflow: hidden;
}
See example: http://jsfiddle.net/vandigroup/upKGe/132/
Since this question is gaining lots of views and this was the accepted answer, I felt the need to add the following disclaimer:
This answer was specific to the OP's question (Which had the width set in the examples). While it works, it requires you to have a width on each of the elements, the image and the paragraph. Unless that is your requirement, I recommend using Joe Conlin's solution which is posted as another answer on this question.
The span element is an inline element, you can't change its width in CSS.
You can add the following CSS to your span so you will be able to change its width.
display: block;
Another way, which usually makes more sense, is to use a <p> element as a parent for your <span>.
<li id="CN2787">
<img class="fav_star" src="images/fav.png">
<p>
<span>Text, text and more text</span>
</p>
</li>
Since <p> is a block element, you can set its width using CSS, without having to change anything.
But in both cases, since you have a block element now, you will need to float the image so that your text doesn't all go below your image.
li p{width: 100px; margin-left: 20px}
.fav_star {width: 20px;float:left}
P.S. Instead of float:left on the image, you can also put float:right on li p but in that case, you will also need text-align:left to realign the text correctly.
P.S.S. If you went ahead with the first solution of not adding a <p> element, your CSS should look like so:
li span{width: 100px; margin-left: 20px;display:block}
.fav_star {width: 20px;float:left}
For those who want some background info, here's a short article explaining why overflow: hidden works. It has to do with the so-called block formatting context. This is part of W3C's spec (ie is not a hack) and is basically the region occupied by an element with a block-type flow.
Every time it is applied, overflow: hidden creates a new block formatting context. But it's not the only property capable of triggering that behaviour. Quoting a presentation by Fiona Chan from Sydney Web Apps Group:
float: left / right
overflow: hidden / auto / scroll
display: table-cell and any table-related values / inline-block
position: absolute / fixed
If you want the margin-left to work on a span element you'll need to make it display: inline-block or display:block as well.
setting display:flexfor the text worked for me.
Wrap a div around the image and the span and add the following to CSS like so:
HTML
<li id="CN2787">
<div><img class="fav_star" src="images/fav.png"></div>
<div><span>Text, text and more text</span></div>
</li>
CSS
#CN2787 > div {
display: inline-block;
vertical-align: top;
}
#CN2787 > div:first-of-type {
width: 35%;
}
#CN2787 > div:last-of-type {
width: 65%;
}
LESS
#CN2787 {
> div {
display: inline-block;
vertical-align: top;
}
> div:first-of-type {
width: 35%;
}
> div:last-of-type {
width: 65%;
}
}
I'm trying to have 2 seperate DIV's, one with Right aligned content (the labels) and the other div with Left aligned content (the content for each label).
I am hoping to make each label "connected" with it's child content on the right so that if it gets pushed down by content from above they will still remain together.
What would be the best way to approach setting this type of layout that is cross-browser? (I have provided in a JPG below).
The alignment is going to be tricky if you actually have the right aligned content in that separate div, especially if the content is variable in nature and the height is prone to change.
Very basically, here is what I would do just so that the right hand features always line up with their associated left hand content. You're obviously going to have to tweak it to your taste.
CSS:
ul {
list-style: none outside none;
margin-left: 150px;
}
ul li h3{
position: absolute;
}
ul li span {
position: relative;
display: block;
width: 150px;
text-align: right;
left: -150px;
}
HTML:
<ul>
<li>
<h3><span>Feature 1</span></h3>
<p>Content 1<br />Content 1</p>
</li>
<li>
<h3><span>Feature 2</span></h3>
<p>Content 2<br />Content 2</p>
</li>
</ul>
I literally just threw this into an empty file just to make sure it works. I know it's not exactly what you asked for, but maybe it will give you some ideas.
As I'm being accused of providing an overkill solution, here's a simpler one just using floats:
CSS:
.left, .right {
float: left;
}
.left {
clear: left;
width: 150px;
text-align: right;
}
HTML:
<div class="left">feature</div>
<div class="right">content<br />content</div>
<div class="left">feature</div>
<div class="right">content<br />content</div>
This is semantically a table, and is an appropriate use for the HTML table layout. While it's important to move away from the use of tables for non-tabular layout, a table is still a table, no matter how few rows or columns. A table with two columns and lots of rows is very prevalent in the real world.
Seems you can also have classes within the divs aligned left or right within the parent element.