Using the :after CSS pseudo-element without inserting content - css

Is it possible to use the :after CSS pseudo-element to offset alignment without actually inserting anything in content: "". It doesn't seem to render unless content is specified so just wondered whether this is possible or if there are any known workarounds.
As an example:-
.nav-primary li.level0 a:after {
content: "";
padding-right: 1px;
margin-left: -1px;
}
As you can see from the example, simply changing the colour of the content would not work in this instance as would still consume space affecting the offset.

It is possible to use an :after pseudo-element with the content property set to the empty string "", but not without setting it all (so that it has its initial value none, which means that the pseudo-element is not generated at all).
The reason why you do not see any effect is that your settings effectively cancel each other out. You set a negative left margin, shifting the element leftwards, but you set an equal amount of padding. The pseudo-element itself is empty and thus invisible, so all that matters is the space that it occupies.
This can be illustrated by drawing an outline. I’m using the value 10px instead of 1px for clarity:
.nav-primary li.level0 a:after {
content: "";
padding-right: 10px;
margin-left: -10px;
outline: solid red;
}
<div class=nav-primary>
<ul>
<li class=level0><a href=foo>bar</a>xxx
<li><a href=foo>bar</a>xxx
</ul>
</div>

I ran into a similar situation which was fixed by adding display: block to the :before styles.

To my knowledge it is possible to use CSS pseudoelements with blank content. The attribute content needs to be specified but can be left blank (as you did in your example code).
I would think that your issue could be related to the display mode - pseudoelements are inline by default. If I understand well what you're trying to achieve, I would go this way:
Set display mode to inline-block.
Specify concrete dimensions of your offset alignment (width, height).
See JSFiddle.

Related

Non-clickable areas in multi-line HTMLanchors

Is it possible to prevent non-clickable area between lines in a multi-line html anchor tag? Here in this example I use line height 1.5 and you can't click between lines.
I know in html5 we can put block-level tags in anchor like <a><div>Link</div></a> but the problem is this part of content can be edited by users and I can't ask them to write their anchor links like this. Is it possible to fix this issue with css only?
CSS:
a {
line-height:1.5em;
}
HTML:
This is a <br> multiline anchor
<br><br><br>
This is a very long anchor displayed as a multiline anchor without BR
DEMO:
http://jsfiddle.net/ergec/F52uY/2/
You can set display: inline-block; or display: block to a, and then it will be clickable.
Example: http://jsfiddle.net/RMXfc/
Or you can increase padding and set negative margin at the same time. This will reduce gap.
Example: http://jsfiddle.net/693z4/
If you give your anchor tags a display: block; you will have a solid clickable area.
a {
line-height:1.5em;
display: block;
}
JSFIDDLE
One problem with display: block; is without a specified width, then entire 100% width is clickable.
The only way to approximate it without messing with the rest of the layout of your text (including the surrounding text of the link) is to add some top/bottom paddings to these links..
So adding padding:3px 0; to your code would fix the issue.
(it will require adjusting, though, in relation to your font-size and line-height)
Demo at http://jsfiddle.net/F52uY/7/

In CSS use "display:none" on the element, but keep its ":after"

Is it possible to not display an element, as with display:none, but continue to display the :before and/or :after?
I tried
#myspan {display:none}
#myspan:after {display:inline; content:"*"}
but that didn't work. I'm trying to have CSS replace the content of a span with an asterisk, without introducing jQuery.
No, it is not possible.
Pseudo elements are rendered like children:
<span id="myspan">whatever<after></span>
And display:none hides the element including all children.
EDIT 1
JavaScript is your best option in my opinion. Even without jQuery changing text is not hard:
document.getElementById("myspan").innerHTML = "*";​
Demo
EDIT 2
However, if you really want to do it with CSS, you can use negative text-indent to hide the text and relative positioning to show the asterisk:
#myspan {
text-indent: -9999px;
display: block;
}
#myspan:before {
content: '*';
position: absolute;
top: 0;
left: 9999px;
}
Demo
​
I think a very easy approach to doing this is to exploit the visibility property. But note that a "hidden" element still takes up the space. But if you are okay with that, just make make the parent element "hidden" and pseudo element "visible":
#myspan {visibility:hidden}
#myspan: after {visibility:visible}
Once you have the visibility taken care of, feel free to play around with the position so that excess space is avoided.
Something like,
myspan {
visibility: hidden;
position: relative;
}
myspan:after {
visibility: visible;
position: absolute;
left: 10px;
}
It's definitely possible. Use font-size: 0px instead of display: none:
#myspan {
/* display: none; */
font-size: 0px;
}
#myspan:after {
/* display: inline; */
font-size: 16px;
content: "*"
}
A demo is here.
In this case you can only use px/pt for the display text font units.
Use:
#myspan {font-size:0}
#myspan:after {font-size:16px; content:"*"}
If you have a min-font size specified, it won't work (browser setting). I'd only use this method for things like previous and next buttons so that screen readers will read "Previous", but you want to replace it with a \276e. So plan for what it will look like with the text showing up.
As explained by #bookcasey, setting display: none on an element unavoidably hides the :after or :before pseudo-element too (because they are not really something displayed after or before an element but content added inside the element, after or before its real content).
But the goal of replacing an element’s real content by generated content is in principle possible, according to the old (2003) CSS3 Generated and Replaced Content Module draft, by simply setting content on the element, e.g.
#myspan { content: "*"; }
So far, only Opera supports this. But a special case where the replacing content is an image is supported by WebKit browsers, too:
#myspan { content: url(asterisk.png); }
It is possible, but you need to use visibility:hidden instead of display:none.
See the answers in the following question for more detail:
How can I replace text with CSS?
You need to break them into multiple content DIV blocks because the style is inherited by child elements. So it's not possible once the parent display style is defined.

&::before Pseudo element not aligning properly - CSS(3) Box Model - LESS

I'm trying to add an image with the &::before pseudo element and place it on top of it's parent element by adjusting the padding/margin. I have not be able to place the img "on top" of it's parent element. It resides within the box of the parent. I have tried setting both elements to display:block. I have attempted to use relative/absolute positioning. I have adjusted margins/padding without a solution.
HTML:
<div class="foo">
<div class="title">title</div>
<div class="body">text</div>
</div>
LESS/CSS:
.foo {
display:block;
padding: 1em;
&:before {
background-image: url("bar.svg");
padding: .25in;
background-repeat: no-repeat;
background-position: top left;
background-position: top outside;
background-color: white;
content: "";
display: block;
max-width: (#column + .45in);
margin-left: -.15in;
margin-top:-.5in;
}
}
I would expect adjusting the value of the margins on the pseudo element would produce the expected result. However this is not the case. Is there a limitation I'm unaware of?
Thanks for your time and your help.
First, I assume by "on top" you mean displayed "before" the .foo element. I assume that based on what it appears you are trying to do with your code. Normally, I would interpret "on top" as a higher z-index and overlapping an element, but I don't think that is what you are asking.
Second, unless I am unfamiliar with something (definitely possible), there is no outside keyword for background-position; therefore, that would seem to be an error (though I would not expect it to cause the issue you face).
Third, I would think that your basic premise should be working. This fiddle demonstrates a shifting of the :before element to be "before" its .foo parent. It could be your mixed use of em units and in units is causing some issues. That would not be a good way to insure you get the positioning you want. I would keep your units in em.
Pseudo-elements are displayed inline by default. Also, they are placed within the content area of an element.
To make it appear 'on top' of that element, set the display to block.
Lastly, pseudo-elements should be initialized using the content property.
.foo::before {
content: url(./bar.svg);
display: block;
}

height style property doesn't work in div elements

I'm setting a height of 20px on a <div>, though when it renders in the browser, its only 14px high.
Any ideas?
<div style="display:inline; height:20px width: 70px">My Text Here</div>
You cannot set height and width for elements with display:inline;. Use display:inline-block; instead.
From the CSS2 spec:
10.6.1 Inline, non-replaced elements
The height property does not apply. The height of the content area should be based on the font, but this specification does not specify how. A UA may, e.g., use the em-box or the maximum ascender and descender of the font. (The latter would ensure that glyphs with parts above or below the em-box still fall within the content area, but leads to differently sized boxes for different fonts; the former would ensure authors can control background styling relative to the 'line-height', but leads to glyphs painting outside their content area.)
EDIT — You're also missing a ; terminator for the height property:
<div style="display:inline; height:20px width: 70px">My Text Here</div>
<!-- ^^ here -->
Working example: http://jsfiddle.net/FpqtJ/
This worked for me:
min-height: 14px;
height: 14px;
Also, make sure you add ";" to each style. Your excluding them from width and height and while it might not be causing your specific problem, it's important to close it.
<div style="height:20px; width: 70px;">My Text Here</div>
You're loosing your height attribute because you're changing the block element to inline (it's now going to act like a <p>). You're probably picking up that 14px height because of the text height inside your in-line div.
Inline-block may work for your needs, but you may have to implement a work around or two for cross-browser support.
IE supports inline-block, but only for elements that are natively inline.
Set positioning to absolute. That will solve the problem immediately, but might cause some problems in layout later. You can always figure out a way around them ;)
Example:
position:absolute;
Position absolute fixes it for me. I suggest also adding a semi-colon if you haven't already.
.container {
width: 22.5%;
size: 22.5% 22.5%;
margin-top: 0%;
border-radius: 10px;
background-color: floralwhite;
display:inline-block;
min-height: 20%;
position: absolute;
height: 50%;
}
You try to set the height property of an inline element, which is not possible. You can try to make it a block element, or perhaps you meant to alter the line-height property?
I'm told that it's bad practice to overuse it, but you can always add !important after your code to prioritize the css properties value.
.p{height:400px!important;}
use the min-height property. min-height:20px;

span css help IE7 - How can I set the width?

I have this CSS and I cannot set the width on a span element. Any ideas what I am doing wrong?
#address-readonly
{
margin-left:150px !important;
padding-left:100px;
}
I am using this in 2 areas in my application. Here is the first area:
<tr>
<th colspan="2">Address Details</th>
<th><span id="address-readonly" class="address-readonly"></span></th>
</tr>
And here is the second area:
<div id="addressHeader" class="addressHeader">
<span>Address Details</span>
<span id="address-readonly" class="address-readonly"></span>
I want the address-readonly span to be more right aligned. The padding/margin combo has almost no effect. What should I be doing here? I don't want to add a bunch of non-breaking spaces, but that's basically the effect I am looking for. This particular client has an office full of IE7 machines, so no FireFox or Safari etc... I have tried setting the width of the span as well.
Try this:
#address-readonly
{
display:block;
float:left;
margin-left: 150px;
width: 100px; /* If you want to set the width */
}
or you could use a div and not set the display attribute.
If applicable, you could try using display: block:
#address-readonly {
display: block;
width: 200px;
}
Without floating, the span will be on it's own row. Hope that helps.
Your only choice is a display value of block or inline-block, because inline elements are resized by their content. Also, please note that inline-block is not that well supported.
Guillaume's and Wicked Flea's answer complement each other, but some points are missing.
Only "box elements" can have its width/height attribute set. Span is a inline element, so it will resize it self to fit content.
So, if you want your elements to have width set, you should use a box element. The problem here is that box elements do not line up in the same row by default. You can then use float and margins to align a box element with another box element.
All that being said, it would be good to use Guillaume's answer. BUT some quirks may appear, check this link link about clearing floats.
What would I do: Use the workaround presented in the link, then use both spans as divs, and have them floated to the left, with your widths and paddings set.

Resources