Why does :before element break layout? - html

I want to display some background images along with some text. Everything should be divided by a | (pipe) to separate the elements.
The pipe is included with an :before selector with the pipe as content.
However it seems that this breaks the layout as the background images are now not longer on the same line as the text. If I remove the content completely it works as expected.
What is the reason for this and how can I fix it?
I've created a small Fiddle as example.

Your layout uses float: left so :before should follow the same rule. For example:
.list-piped:before {
display: block; /* fix */
float: left; /* fix */
content: "|"; /* This breaks the layout */
}
https://jsfiddle.net/infous/1cbeyn84/4/
BTW, Manoj Kumar below has described the real problem. My answer is a possible solution because float: left as well as position: absolute has its own flow.

Why does this happen?
Check out this Image. Technically ::before is part of li(.list-piped) and takes up the whole width, pushing the child items(icons) to bottom.
How to fix?
Apply ::before to child elements or use position: absolute to the current code.
Updated JSfiddle

Related

Add image to the bottom of a adjustable height section

I am trying to created a CSS design on my web app. I am going for a banner that is flapping in the wind. I want the banner to expand/scroll its height so all text will be displayed on the banner but regardless of how tall the banner is, I want to add a ripped section of the banner at the bottom of it. The banner will be the same width in all cases.
Something like the example below (forgive the horrible Paint screenshot):
I can't seem to wrap my brain around how to accomplish this. Any of you smart people have any ideas?
First, I think it'd be helpful if you could provide an example of what you have so far. For example, what's your HTML & CSS for the adjustable-height divs, just without the image at the bottom? Easier to add onto that.
I believe the best way would be to add an image element at the bottom of your adjustable element (assuming it's a <div>). Position it as absolute, and set it relative to the bottom of its parent container. You may have to fiddle with it a bit to get it to work. Don't forget to also set the position of the parent to relative.
If you'd like to see the shoddiest example ever, go here: https://jsfiddle.net/c2ptfv8o/
Good further reading on position: https://developer.mozilla.org/en-US/docs/Web/CSS/position
Give the container element "position:relative" (to create a new positioning context) and some bottom padding (to make space for the image). Then you can either use a background image set to be at the bottom of the container and not repeat vertically or absolutely position an image to the bottom.
You can use pseudo-elements for this. This way you don't require extra markup for each element.
.myDiv {
position: relative;
}
.myDiv::after {
content: url(image.jpg);
display: block;
position: absolute;
left: 0;
top: 100%; /* will be placed immediately where the div ends */
width: 100%;
}
Based on the height of the 'banner curls', set a margin-bottom on .myDiv.
Or directly, without absolute, as long as you don't have paddings:
.myDiv::after {
content: url(image.jpg);
display: block;
width: 100%;
}

Have ::before stretch the full page width

Problem
I'm trying to stretch a ::before element from the very left hand side of the page to the right hand side, even though the element it's attached to is centred and somewhat down the page (and thus does not know what the window size is etc).
Here's a working example of what I want:
http://codepen.io/robcampo/pen/dilCe
Problem with this is that I'm using static values to define the width and left position:
left: -9000px;
width: 99999px;
which isn't ideal. I understand this could be solved if I moved the element to another location on the page, but I need it next to the element it's attached to.
Question
Is there a clean way to make the ::before content span the entire page width without using static values?
Note
There is content above and below this element and it is far down the DOM tree away from the body
I could solve using JS but I want a pure CSS solution
If you remove position: relative from the parent element, you can easily do this.
You can center .title like this instead:
.title {
margin: 0 auto;
}
Then you can adjust the ::before like this:
.title::before {
position: absolute;
left: 0;
width: 100%;
}
Bringing it all together: http://codepen.io/anon/pen/xLKGc
PS: Note that IE8 and before don't support the double-colon (CSS3) notation, so if you need to support IE8, make sure to use a single colon (CSS 2.1), which is supported by other browsers as well, and will probably be for a while.

Vertical centring with :after pseudo-element not working

I'm trying to vertically centre my introWrap container using the :after pseudo-element method (as described at the end of this article). I've always applied this method without any problems, but I can't for my life seem to understand why it doesn't work in this case (http://jsfiddle.net/4yfru/2/).
Right now the introWrap div is at the top, whilst it should really be in the center on the vertical axis. I tried replacing the :after pseudo-element with a span, and it worked perfectly. Something's fishy is going on here and I don't know what.
Could any kind soul please help me out here?
You have the wrong element with the :after applied. You need to apply it to the "wrapping" element, so like this:
#intro:after{
content: "";
display: inline-block;
vertical-align: middle;
height: 100%;
}

Horizontal line inline-block IE7

I would like to put 3 horizontal line in a row.
Does anyone know how to put an horizontal line displaying in inline-block in IE7 ?
Here is my CSS:
hr.small {
width: 28.9%;
margin-right: 6px;
display: inline-block;
vertical-align: top;
zoom: 1;
*display: inline;
height: 3px;
border: 0px;
color: #7c8690;
background-color: #7c8690;
}
but it doesnt works.
here is the JSFiddle Link: http://jsfiddle.net/sRuz3/6/
If anyone has a solution.
Thanks a lot.
Here you go: http://jsfiddle.net/eq3Z2/
It works in IE7 also.
Granted, they aren't HRs. They are DIVs. Trying to render the HR as an inline element
is tripping up IE7 but I don't know of a workaround.
Does it have to be inline-block? Can you not simply float them and set a height if necessary?
Edit - Example:
hr.small {
float:left;
width: 28.9%;
margin-right: 6px; /* Choice: Use border instead or halve the margin for IE7 and lowwer (double margin float bug). */
height: 3px;
background-color: #7c8690;
}
Edit again - Question:
Is this going in a fluid layout and how big is the container? You are setting a dynamic width but a fixed margin, this will cause issues in small scale and introduce unwanted white space to the far right in large scale. If it is a fixed area then consider using a fixed width.
It seems there's a solution if you can wrap the hrs in divs.
Set the div's to display:inline (we could use spans instead but hrs are not valid in spans)¹ and also give the divs hasLayout via zoom:1
See http://jsfiddle.net/YqKDJ/1/
¹ As an aside, there's a reason why hrs are not valid in spans and it's relevant here. An hr is not primarily a way of drawing a horizontal line - it has a specific semantic meaning of "Thematic break". It makes no sense to have two or more hr elements with no content betwwen them - there's nothing for the second thematic break to break from. If you want multiple horizontal lines for presentational purposes, you should use CSS to create them, along the lines of #Cynthia's answer.

IE7 Absolute Position starts at top of line as opposed to other browsers

I created a fiddle that exemplifies the problem:
http://jsfiddle.net/vZtBb/
This is working exactly as I want it, but the problem is that in IE7 the absolutely positioned span (hover-tooltip-container) starts at the top of the line instead of at the bottom like it does in the other browsers. If you add a border to hover-tooltip-container, you can see this.
This is a problem because I want the tooltip to go up, but the anchor to still be exposed. You should be able to mouse over the tooltip as well, but the gap in IE7 makes this impossible.
If there is any way to get the hover-tooltip-container span to start in the same place on the line in IE7, IE8, and FFX, that would be perfect.
Javascript is not a solution.
The most simple thing you could do with the code you already have, is add a star hack to adjust the bottom rule within .hover-tooltip, for IE7.
.hover-tooltip {
display: block;
padding: 15px;
position: absolute;
margin: 0 auto;
bottom: 1em;
*bottom: 0;
width: 100%;
border: 2px outset #c0c0c0;
background-color: #f0f0f0;
text-align: center;
}
However, the double, nested absolute positions of .hover-tooltip-container and .hover-tooltip seem unnecessary.
I did something quite different (also renamed your classes, to much of a hassle to play with those looooooooooong name).
http://jsfiddle.net/vZtBb/16/
I removed the nested absolute positionning : They are the one causing the issue, since element in absolute position are taken out of context. So, 2 solo, nested absolute positionned element means that one element is in nothing (glitchy and really not wanted).
Instead of that, I placed your tooltip box in absolute, but made it start higher than the anchor by use of a negative position (top:-70px). It's sketchy a bit, but you should get my point.
Trying putting this after the .hover-tooltip div:
<div class="clear fix"></div>
and this css:
.clearfix:after {content: ".";display: block;clear: both;visibility: hidden;line-height: 0;height: 0;}
.clearfix {display: inline-block; }
html[xmlns] .clearfix {display: block; }* html .clearfix {height: 1%; }
I was able to solve the problem by having the "container" element float left and have relative position. This achieves the appearance of breaking out of containers but still provides a reference for the tooltip to go up from.