I'm trying to come up with some good default styling for <input>s in HTML5 and tried the following:
input::after { display: inline; }
input:valid::after { content: ' ✓ '; color: #ddf0dd; }
input:invalid::after { content: ' ✗ '; color: #f0dddd; }
Alas, the ::after content never shows up. It's not a problem with double- versus single colons for the pseudo-elements; I've tried both. It's also not a problem with having a pseudo-element and a pseudo-class; I've tried it without the :valid and :invalid. I get the same behavior in Chrome, Safari, and Firefox (Firefox doesn't have the :valid and :invalid pseudo-classes, but I tried it without those.)
The pseudo-elements work fine on <div>, <span>, <p>, and <q> elements -- some of which are block elements and some are inline.
So, my question is: why do browsers agree that <input>s don't have an ::after? I can't find anything in the spec that would indicate this.
As you can read here http://www.w3.org/TR/CSS21/generate.html, :after only works on elements that have a (document tree) content. <input> has no content, as well as <img> or <br>.
You can put a span before or after the element. E.g.:
<style>
#firstName:invalid+span:before {
content: "** Not OK **";
color: red;
}
#firstName:valid+span:before {
content: "** OK **";
color: green;
}
</style>
<input type="text"
name="firstName"
id="firstName"
placeholder="John"
required="required"
title="Please enter your first name (e.g. John )"
/><span> </span>
Webkit lets you do ::after on input elements. If you want a way to make it work in Firefox you could try using ::after on the input's label rather than the input itself.
Related
I want to add an em-space just after BR tag so as to achieve text-indent effect. But the following STYLE doesn't work on my Chrome.
Or, any other way to achieve text-indent effect after BR tag?
<style>
br::after {
content: " ";
}
</style>
<p>Note:<br>For this selector to work in IE8, a DOCTYPE must be declared, and you must use the old, single-colon CSS2 syntax (:after instead of ::after).</p>
I managed to do this to add an em space just after BR tag!
<style>
br {
content: '';
white-space: pre;
}
br::after {
content: "\A\2003";
}
</style>
Another problem is that I also want to keep 1em margin-bottom. The following style ALONE works well.
<style>
br {
content: '';
display: block;
margin-bottom: 1em;
}
</style>
BUT, if i mixed the two styles into the following, it doesn't work!!!
<style>
br {
content: '';
white-space: pre;
display: block;
margin-bottom: 1em;
}
br::after {
content: "\A\2003";
}
</style>
You really shouldn't be using a line break (br) tag to break up paragraphs, not in modern web design. See the HTML 5.2 spec for some examples.
Furthermore, there is a CSS property text-indent which also achieves the text indentation you are after.
Basically, use <p> as intended (eg to wrap a paragraph) and then apply text-indent to the p tags.
p {
text-indent: 1em;
}
p.unindented {
text-indent: inherit;
}
<p class="unindented">Note:</p>
<p>For this selector to work in IE8, a DOCTYPE must be declared, and you must use the old, single-colon CSS2 syntax (:after instead of ::after).</p>
<p>Here is another paragraph to show how this applies when you have more than one <p> of content. The text-indent property is supported by all major browsers. (That is, IE 3 and later. Not that IE is a major browser anymore....)</p>
<p>See here for more info: https://developer.mozilla.org/en-US/docs/Web/CSS/text-indent</p>
text-indent is a very old property with wide support across all major browsers and a lot of older ones too. It was first introduced in IE 3, to give a sense of how old it is. See MDN for more information.
I'm trying to come up with some good default styling for <input>s in HTML5 and tried the following:
input::after { display: inline; }
input:valid::after { content: ' ✓ '; color: #ddf0dd; }
input:invalid::after { content: ' ✗ '; color: #f0dddd; }
Alas, the ::after content never shows up. It's not a problem with double- versus single colons for the pseudo-elements; I've tried both. It's also not a problem with having a pseudo-element and a pseudo-class; I've tried it without the :valid and :invalid. I get the same behavior in Chrome, Safari, and Firefox (Firefox doesn't have the :valid and :invalid pseudo-classes, but I tried it without those.)
The pseudo-elements work fine on <div>, <span>, <p>, and <q> elements -- some of which are block elements and some are inline.
So, my question is: why do browsers agree that <input>s don't have an ::after? I can't find anything in the spec that would indicate this.
As you can read here http://www.w3.org/TR/CSS21/generate.html, :after only works on elements that have a (document tree) content. <input> has no content, as well as <img> or <br>.
You can put a span before or after the element. E.g.:
<style>
#firstName:invalid+span:before {
content: "** Not OK **";
color: red;
}
#firstName:valid+span:before {
content: "** OK **";
color: green;
}
</style>
<input type="text"
name="firstName"
id="firstName"
placeholder="John"
required="required"
title="Please enter your first name (e.g. John )"
/><span> </span>
Webkit lets you do ::after on input elements. If you want a way to make it work in Firefox you could try using ::after on the input's label rather than the input itself.
I know there are lot's of questions regarding this query here but none of them provide the solution for me.
HTML
<input id="tb1" type="text" class="note" />
<br>
<p class="note1"> This is not done.</p>
CSS
p.note1:before{
content: "Note:";
}
tb1.note:before{
content: "Enter your number";
}
I am trying with above code and the variation as found on the web but none seems to work for input tag. It's working for p tag.
EDIT: I can't add value attribute to input tag and manage css for the desired result. It's the limitation of the system.
EDIT2: Forget about my css, is there any way that placeholder text is possible without using placeholder attribute and just with plain css for input type="text"
:before creates a pseudo-element that is the first child of the element matched.
The selected element MUST be a container tag. An empty tag like <input> doesn't have any children element.
If you can't edit your HTML code manually, you're still able to that by using JavaScript:
document.getElementById("tb1").setAttribute("placeholder", "Enter your number");
Update
If you want to achieve this by using CSS only, you need to have a container element wrapping your <input> (or come after it).
BUT It doesn't work correctly as placeholder do. You'll not able to check the value of <input> by CSS. If you write something inside the <input>, after blur event, the generated placeholder will be displayed over the <input> again.
HTML:
<label>
<input id="tb1" type="text" class="note">
</label>
CSS:
label {
position: relative;
}
label:after {
content: 'Enter your number';
position: absolute;
left: 5px;
top: 0;
color: #bbb;
}
#tb1 {
position: relative;
}
#tb1:focus {
z-index: 10;
}
JSBin Demo
It doesn't work for the simple fact that this:
<input id="tb1" type="text" class="note"></input>
is not valid. <input /> elements are not containers. As the spec notes, endtags are forbidden (and essentially ignored by the browser): http://www.w3.org/TR/html401/interact/forms.html#h-17.4
If you cant manipulate the html and use placeholder="". Use javascript to manipulate the placeholder. Every css approach is hack-isch anyway.
E.g. with jQuery:
$('#myFieldId').attr('placeholder', 'Search for Stuff');
I have found this method but not supported by all browsers:
#tb1.note:empty:before{
content: "Enter your number";
}
Note: you have forgot to place an id selector # tb1.note
see this link
EDIT:
Try this for starters: (Note: you'll need some js to detect if text has been entered in the input)
Apart from this - I don't think this there is a css solution for placeholder text on an input element without using the placeholder attribute.
FIDDLE
Markup
<div class="container">
<input />
<div class="fakePlaceholder">Some placeholder text</div>
</div>
css
.container
{
position: relative;
}
input
{
background: transparent;
}
input:focus + .fakePlaceholder
{
display: none;
}
.fakePlaceholder
{
color:gray;
position:absolute;
top: 3px;
left: 5px;
z-index: -1;
}
You can't use pseudo elements on an input tag - or any other non-container elements for that matter
From the Pseudo-Elements tag info:
you cannot use them (pseudo elements) with replaced elements (see
below) which do not have actual content. This is because the generated
content resides within the element.
...
Replaced Elements
Any element whose appearance and/or dimensions are determined by some
external resource is considered to be a replaced element. Some
pseudo-elements cannot be applied to replaced elements because they
have no "content" or get replaced with something (such as user
interface controls). Replaced elements include images (<img>), inline
frames (<iframe>), line breaks (<br>), horizontal rules (<hr>),
plugins (<object>), form elements (<button>, <textarea>, <input>, and
<select>), videos (<video>), audio sounds (<audio>), and canvases
(<canvas>). Any other element is considered to be a non-replaced
element.
Another way this can be accomplished, and have not really seen any others give it as an option, is to instead use an anchor as a container around your input and label, and handle the removal of the label via some color trickory, the #hashtag, and the css a:visited. (jsfiddle at the bottom)
Your HTML would look like this:
<a id="Trickory" href="#OnlyHappensOnce">
<input type="text" value="" id="email1" class="inputfield_ui" />
<label>Email address 1</label>
</a>
And your CSS, something like this:
html, body {margin:0px}
a#Trickory {color: #CCC;} /* Actual Label Color */
a#Trickory:visited {color: #FFF;} /* Fake "Turn Off" Label */
a#Trickory:visited input {border-color: rgb(238, 238, 238);} /* Make Sure We Dont Mess With The Border Of Our Input */
a#Trickory input:focus + label {display: none;} /* "Turn Off" Label On Focus */
a#Trickory input {
width:95%;
z-index:3;
position:relative;
background-color:transparent;
}
a#Trickory label {
position:absolute;
display:block;
top:3px;
left:4px;
z-index:1;
}
You can see this working over at jsfiddle, note that this solution only allows the user to select the field once, before it removes the label for good. Maybe not the solution you want, but definitely an available solution out there that I have not seen others mention. If you want to experiment multiple times, just change your #hashtag to a new 'non-visited' tag.
http://jsfiddle.net/childerskc/M6R7K/
I'm not sure if this is possible but it would help immensely if it is. I'm working on an e-commerce site in the Volusion framework and a lot of text is dynamically generated on Volusion sites. Most of the text is in <span>s or <div>s as normal but every once in a while there is a ":" that is displayed after a category header. You can see it in the below code that I grabbed from a page I'm working on:
<td>
<span class="PageText_L71n">Qty</span>:
<input type="text" class="v65-productdetail-cartqty" name="QTY.WA-SSPURSE" size="3" maxlength="8" onkeydown="javascript:QtyEnabledAddToCart();" value="1">
</td>
You can see the colon after the </span> that is just being displayed but not in any container. Is there any way to target that? I'm trying to put a display:none or visibility:hidden on it since I'm doing quite a bit of custom coding and it's just hanging there right now.
Thanks for the help!
If you know the container of the colon ahead of time, you can change the font color to match the background or use font-size: 0 (which I like because it also removes unnecessary space):
td {
font-size: 0;
}
td * {
font-size: 14px;
}
Obviously adjust for specifics that work for your site in particular.
If all the elements in the td are known, then target all of them with the :after and :before pseudo selectors.
td span:after {
content:"<span class="hide">"; }
td input:before {
content:"</span>"; }
.hide {
display:none; }
I have not tested this nor ever used these selectors but it should work.
If there are multiple elements of the same kind, say three inputs you can use the nth-child selector on td.
I'm experimenting with some styles on <textarea>s and I tried doing some stuff with ::before and ::after selectors and I couldn't to anything to get them to work. So the question is: is this possible? I know the CSS surrounding forms is arcane beyond mention but it seems like this should work.
The :before and :after will not work on a text-area (nor any element that cannot contain another element, such as img or input), because the generated content of the pseudo-element gets placed within the element but before or after that element's content, and acts itself as an element. The pseudo-element does not get placed before or after the parent element itself (contrary to some information one may find on the internet). To illustrate:
If you have this css:
p:before {content: 'before--'}
p:after {content: '--after'}
Then html like this:
<p>Original Content</p>
Effectively renders to the screen as if the source code were:
<p>before--Original Content--after</p>
Not as if the source code were:
before--<p>Original Content</p>--after
Which is why tags that cannot contain any html element "content" (like those mentioned above) do not recognize the pseudo-elements, as there is no "place" for that content to be generated to. The textarea can contain "content," but only pure text content.
<div class='tx-div-before'></div>
use this before textarea and
<div class='tx-div-after'></div>
use this code after textarea. and add before and after psedu element.
Actually, you can add content with :after on an input element. This will add a sort of tip when the element is in its active state:
#gallery_name {
position:relative;
}
#gallery_name:focus:after {
content: "Max Characters: 30";
color: #FFF;
position: absolute;
right: -150px;
top:0px;
}
<input id="gallery_name" type="text" name="gallery_name" placeholder="Gallery Name">