Extra line added :after pseudo-element when using HTML5 DTD (versus XHTML1) - css

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.

Related

Why flex content affects positioning of unrelated elements outside flex in Chrome and IE?

I’ve noticed some unexpected layout behaviour of flex content, namely it affects positioning of the unrelated elements on the page.
Scenario: I have div.container and div.content inside. div.container has the display set to inline-flex and centres div.content vertically.
Now, any content (that uses regular flow) I put after the container can’t go higher than the top of div.content.
When I add some free text after the div.container, it is aligned with the div.content top, even though it is completely outside the flex container and should be unrelated to it.
When I add another div.container, it is positioned the way its div.content is no higher that div.content of the previous, unrelated div.container. This container (or rather its div.content) in turn affects the position of the subsequent ones.
https://flex-content-affects-outside.stackblitz.io/
It looks as if the top of a div cannot be placed higher than the top of divs before it in the document flow.
In my case, this doesn’t affect inline-flex containers directly, but rather their content. The vertical position of the flex containers if affected as the result – so that their content is aligned.
This behaviour is visible in Chrome and IE11. On the other hand, in Firefox everything works as expected.
My question is: What causes such a behaviour? Is it in any way standardized?
In the example above isn’t a significant problem, we can wrap all the boxes in another flex to get the expected behaviour. However, I’m afraid that in more complex layouts some unexpected relations between seemingly independent content can ruin the layout.
Edit: I'm adding a code snippet.
.container {
font-size: 30px;
margin: 10px;
width: 200px;
height: 200px;
border: 1px solid #888;
display: inline-flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.container .content {
width: 100%;
text-align: center;
background: rgba(200, 200, 200, 0.5);
}
<div class="container">
<div class="content">
Content.
</div>
</div>
<div class="container">
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
As Paulie_D noticed in the comment, it was caused by vertical-align. Once we specify vertical-align: top everything works as expected.
.container {
font-size: 30px;
margin: 10px;
width: 200px;
height: 200px;
border: 1px solid #888;
display: inline-flex;
align-items: center;
justify-content: center;
overflow: hidden;
vertical-align: top;
}
.container .content {
width: 100%;
text-align: center;
background: rgba(200, 200, 200, 0.5);
}
<div class="container">
<div class="content">
Content.
</div>
</div>
<div class="container">
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
Or, more elaborate one:
https://stackblitz.com/edit/flex-content-affects-outside-baseline-elwwvc?file=style.scss
More precisely, the layout was due to the implicit vertical-align:baseline (in Chrome and IE). The boxes are inline-flex and there were laid out according to the baseline. Once we specify this explicitly the behaviour is consistent among browsers. Another font size in one of the boxes makes it more visible.
https://stackblitz.com/edit/flex-content-affects-outside-baseline?file=style.scss

Difference in rendering of negative text indent layout between Chrome & Firefox

I use padding and a negative text-indent to create an indented layout for responsive forms but now want to make the bottom paragraph a block level element so it always wraps.
The layout works fine when the bottom row is display inline or inline-block but as soon as the bottom row is display block then the entire layout in Chrome changes.
I don't know which browser is right, but it is Firefox's interpretation of the layout that I am after.
This is a simplified version of a layout I use for forms to attempt to fix this problem.
http://codepen.io/rachelreveley/pen/rxxxRj
<div>
<div>
<p class="top">Lorem ipsum dolor sit amet</p>
<p class="bottom">Lorem ipsum dolor sit amet</p>
</div>
</div>
<style type="text/css">
div div {padding-left: 36%; margin: 0; text-indent: -18%; background-color: #cee; width: 300px;}
p {text-indent: 0;}
p.top {display: inline-block; background-color: #ffc;}
p.bottom {display: block; width: 200px; background-color: #fcf;}
</style>
Real world example of how this code is being used.
I have fixed this by changing from using padding to margin on the parent container and then adjusting the sizes after that.

Aligning grid based form elements and their labels

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;}

Div ignoring set width constraints, CSS

all. I have this problem where I have explicitly set out how wide a certain div dhould be, yet it ignores it.
I have a wrapper, and in it I want side by side a sidebar and a content bar. The content bar seem to be pushing away the sidebar and filling up all the space.
Code in Question:
#wrapper{
font-family: "Georgia", serif;
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -2em;
width: 700px;
position: relative;
}
#content{
float: left;
width: 400px;
padding-left: 25px;
padding-right: 50px;
}
#sidebar {
float: right;
width: 175px;
padding-right: 25px;
}
And the HTML is simply
Blah Blah Blah
In a nutshell
I put Lorem Ipsum where content is, and I put some Lorem Ipsum in the sidebar. Element Inspector in chrome shows content to be 700 pixels wide, even though i declared it to be 400px. I dont care about ie6 compatibility really.
http://imgur.com/A1w0a Is how it should look.
Someone said somehting about fiddles. Am I doing this right http://jsfiddle.net/R3Wyw/1/
The big Lorem Ipsum chunk be skinnier, only 400 pixels of text, while the sidebar should move up and slot in beside it.
You've basic HTML and CSS syntax problems in your code:
HTML ending tags should be written </div> and never ever </div id="content">.
Good:
<div id="content" class="something" role="main">
<p>Content</p>
</div>
Bad:
<div id="content" class="something" role="main">
<p>Content</p>
</div id="content" class="something" role="main">
CSS comments must be written /* a CSS comment */, not <-- HTML comment -->
You should try to validate your code in http://validator.w3.org (HTML) and http://jigsaw.w3.org/css-validator/ (CS) before posting (use the Web Developer Toolbar extension on Firefox to do it fast).
Error messages are sometimes a bit cryptic but they're always the same ;) Google for them to get explanations or ask here on SO.
For width problems, I add different background-color to elements and parents, to better see which one isn't as expected (and which one has only floating children and thus no real content in the flow anymore thus no height thus no visible background color...). Like lightblue, lightgreen, pink, lightyellow, etc This and MeasureIt! extension on Fx.

side-by-side, flexible width divs without wrapping?

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.

Resources