I've created a nice set of form elements in Photoshop and am looking to convert them into HTML and CSS. The simple input-text form will have a background image, as the field does not change in size. However, the text-area form will dynamically change size as the user types.
Normally, to build out this sort of style, I'd wrap the form field in divs, as such:
<div class = "textarea-top">
<div class = "textarea-bottom">
<textarea></textarea>
</div>
</div>
Or by using multiple background-images in one wrapping div:
<div class = "textarea">
<textarea></textarea>
</div>
Is there a better way to approach this? To restate, the field styles are advanced images that can be repeated (for the body of the field), and have styling for the top and bottom. The question is, what is the best practice in dealing with these advanced form styling?
I'm not entirely sure what you mean by "best practice", but one thing I'd improve are the semantics.
You could (should?) use <fieldset>'s instead of a, rather meaningless, <div>.
And you don't need to use two <div>'s around the textarea, or even multiple background images on a single <div> (which is a CSS3 property, and not widely-supported).
Instead, you should wrap the <textarea> in a <label> element, and nest your background-images as I've described below:
Try this:
<fieldset class="expandableInput">
<label>
Semantic text:
<textarea></textarea>
</label>
</fieldset>
Bonus: wrapping form elements in <label>'s like this, affords a larger click area, for the user to gain focus on the form element at hand. Just be wary of <select>'s, which doesn't play nice (even though it's valid HTML)
The CSS would be something like:
.expandableInput {background: url(/path/to/first/img);}
.expandableInput label {display: block; background: url(/path/to/second/img);}
.expandableInput textarea {display: block; margin-top: 3px; background: url(/path/to/third/img);}
Also;
For consistent looks on form elements, in every browser & platform, I can highly recommend Nathan Smith's Formalize CSS (it requires JS for HTML5 support in older browsers).
Related
I think I cannot do that one in CSS, but wanted to see whether someone would have such a solution...
I have a div with the page content, a div which can be in several different location in the HTML, and a set of paragraphs. The CSS would have to place the second div between two paragraphs.
There is a sample HTML:
<div id="to-be-placed">Move Me</div>
<div id="content">
<p>P1</p>
<p>P2</p>
<p>P3</p>
<p>P4</p>
<p>P5</p>
</div>
Say we want to place the "#to-be-placed" div after the 3rd paragraph, is there a way to do that in CSS? I can reference the 3rd paragraph as so:
content.p:nth-child(3)
But I really don't see a way to tell CSS to move my DIV to that location...
Note: the #to-be-placed div could be inside the #content div, at the beginning or at the end.
P.S. Please, don't come up with hard coded sizes and positions. That won't work.
P.S. Just in case you get all excited about jQuery. I know how to do it with jQuery. So no, I don't need you to give me such an answer. (see How to add div tag in-between two paragraphs when wrapped inside main div using jquery for those who wonder.)
This cannot be done using CSS, as CSS does not provide any mechanism for moving elements in HTML, only for styling existing elements and adding new content through the use of pseudoelements. The best you're going to get is a solution that uses JavaScript or jQuery.
If you only want to add styled text content, you can add that using the ::after pseudo-element in CSS, but it does not support HTML, only plain text:
p:nth-child(2)::after {
content: "- Added content";
}
<div id="content">
<p>P1</p>
<p>P2</p>
<p>P3</p>
<p>P4</p>
<p>P5</p>
</div>
You can't do that exactly, but a possible workaround would be to define the div as the ::after element on the 3rd p element. This technically puts the div inside the p, but it might do what you're looking for.
p:nth-child(3)::after {
content: "Move Me";
display: block;
}
Here's a fiddle: https://jsfiddle.net/me5su05f/1/
Short answer: No you cannot do that. CSS (Cascading Style Sheet) is designed for styling. It is not designed to be used to manipulate DOM elements. JavaScript on the other hand is built for doing that. So if you happen to be wanting to use CSS for manipulating your DOM then you might want to re-think your approach to the solution.
I'm trying to get a site I'm working on to be WCAG 2 compliant. The site uses image sprites and it would be a challenge to replace the usage of image sprites throughout. As such I'm trying to determine whether the following technique:
<div style="background: url(flower.png); height: 20px; width:20px;">
<div style="text-indent: 100%; white-space: wrap; overflow: hidden">
A red rose
</div>
</div>
Is sufficiently compliant. From reading the documentation... it's unclear.
For a non-decorative img tag use of alt is definitely a requirement: H37: Using alt attributes on img elements
And for a media objects, wrapping content is sufficient: H53: Body of Object
But whether using the body of a a div that has a non-decorative image background passes muster isn't very clear.
Can anyone speak to this or point me to the relevant page in the standard?
There are a couple of scenarios this could be, the advice will change depending on whether it is:
Content images (e.g. a gallery)
Functional elements like a navigation or toolbar options.
If they are content images (which 'red rose' implies), then I think this technique applies:
http://www.w3.org/WAI/GL/WCAG20/WD-WCAG20-TECHS/C30.html
In which case your approach would meet WCAG if people could display it without the image in order to read the alt-text. That might sound odd, but assistive technologies have long known how to read alt attributes, but image-replacement can be done in many ways and they may not be able to tell when it is used.
Screen reader users would probably find it ok, but other groups who need alt-text probably wouldn't be able to read the text in a 20x20px box. For example, if you turn on high-contrast mode in Windows, background CSS images are dropped and the text would not be visible.
If they are functional elements and the image is an icon, e.g. a "save" button, then you want a visible (e.g. tooltip) and programatic label, in which case I would suggest:
<div style="background: url(flower.png); height: 20px; width:20px;"
role="button" aria-label="Save" title="Save" tabindex="0"></div>
However, you would be better off using foreground images or font-icons, as these are far more robust in different situations. For example, if you included a font-icon you could use:
<button>
<span class=”icon-save” aria-hidden="true"></span>
<span class=”alt”>Save</span>
</button>
With something like this as the CSS, assuming you have already imported the correct font to use:
.icon-save:before {
font-family: icons;
content: ⇝ /* whatever your icon reference is */
}
.alt {
position: absolute;
left: -9999px;}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<style>
form:focus{
background:red;
}
</style>
<title>Home, sweet home</title>
</head>
<body>
<form>
<input type="text"/>
<input type="submit"/>
</form>
<form>
<input type="text"/>
<input type="submit"/>
</form>
<form>
<input type="text"/>
<input type="submit"/>
</form>
</body>
</html>
This obviously doesn't work, as is why I'm asking the question. How can I get the form which has one if it's inputs as the focus to highlight? That is, I want to be able to apply styles to the active FORM, not the active INPUT - is that doable without JS or something?
This is an older question, but as of now, some of the more popular browsers are supporting a css pseudo selector called :focus-within, which can style a form (without javascript) that has a focused input.
Here is the current support for the selector: http://caniuse.com/#search=focus-within
If you're using a supported browser, here is an example: https://codepen.io/jumprope-design/pen/LjxORX
This code works as an exercise but probably not a solution you should use. The version relying on legend actually seems acceptable.
There is no form:focus selector so I thought instead the individual input:focus could create the desired effect using pseudo-elements. However, pseudo-elements can only be used on elements with content, like if I were to replace input[type=submit] with button
form {
position:relative;
}
/*style the pseudo-element before a button that is a general sibling
of any element that currently has focus within a form*/
form *:focus~button:before{
content:"";display:block;background:red;
/*take up the entire space of the form*/
position:absolute;top:0;right:0;bottom:0;left:0;
/*but render behind its children*/
z-index:-1;
}
Fiddled, but it instantly looked pretty crazy, so I've refactored the solution to rely onto a legend element. Enjoy :)
There is no parent selector in CSS so javascript is required. CSS 4 is planned to get this feature, however.
I've been looking for the same styling technique for a while. From a UI/UX standpoint - simplifying search forms to a single element makes a lot of sense in certain situations.
Consider the example below:
When you approach it from a development standpoint the knee-jerk is to decide to style the form itself instead of the input elements. A transparent input[type=text] to the left, and a transparent .PNG submit button to the right and you've got a sharp looking search field.
As you've discovered though, you give up the CSS style capabilities associated with :focus because the input field isn't the one controlling the background / color etc - the form element is instead.
The form:focus selector would be a perfect way to handle that. Unfortunately, we've got to wait to CSS4 for that (thanks to matt3141 for the tid-bit).
In the meantime, you have a few options available
Option 1 - Forgo the Clickable Submit Button
I usually try and avoid this if possible, but you have the option to forgo the submit button altogether. Style the text field as you intended, and use a background image with the position limited to the left or of the field right. When the user types in their query, and presses enter, you can still fire a GET action. The example image above uses this technique.
Example: http://designdisease.com/
Pros: Easiest to set up.
Drawbacks: Users who still click search buttons might be confused.
Option 2 - Use an Alternate Element to Style the Background
Your next option is to take advantage of the sibling selector and content tags as o.v. has so generously explained in his/her previous answer. This in effects adds a new element and styles it to act as a new background for a specified area when the :focus effect is applied to an input field.
Example: http://jsfiddle.net/ovfiddle/PEK7h/2/
Pros: Extendable to larger forms with multiple fields more easily.
Drawbacks: The intensive selectors may not degrade as gracefully as we'd like.
Option 3 - Use Absolute Positioning to Stack the Elements
In situations where the text field will encompass the full width of the form, you can use a the position:absolute; attribute to simply load the submit button over top of the input element, and then a few css tweaks on the button to remove the background / border - giving the same effect as our example image above, but with added benefit of making it clickable.
Step One: Give the form a position - relative/absolute/fixed.
Step Two: Give the text field a width of 100%.
Step Three: Give the button an absolute position, and right position of 0.
I've updated o.v.'s fiddle to incorporate the new technique:
Example: http://jsfiddle.net/PEK7h/17/
Pro's: Degrades gracefully, gives us what we want in most single input field cases.
Drawbacks: Not as easily extendable to large forms like o.v.'s fix is.
--
As you can see, each option has its own drawbacks - but if you know about them ahead of you can usually lessen their impact. Hope this helps!
If you have multiple forms in the page, without JS, the renderer will not be able to link the stylesheet and the form. The best way to do it is to have the form name/ID and have JavaScript to apply the stylesheet when form get focus.
You cannot "focus" on a form. You can only "focus" on the form elements inside the form (that are editable and enabled) using CSS. Hope this helps.
I'm working with an <input> field and I'd like to style part of the field as the user's typing in a different color. For example, let's say the <input> has a style declaration of color: red; and I want to change part of it to color: blue;. Is there any way this is possible?
If there isn't (as I suspect), any creative ideas on how I can simulate this effect while still preserving semantic mark-up?
Your suspicions are correct: styles will apply to the whole input only.
As styles can apply to the entirety of an element only, a solution will require at least one element per required colour.
Consider the division of the input field with respect to the point at which the user is making changes. There are three sections of the input:
that before the point at which changes are being applied
that after the point at which changes are being applied
that at the point the changes are being applied
You cannot achieve this with a single input element. And as the point at which the changes are being applied can change, the portions of the 'input' wrapped by the three elements will also change. JavaScript is required for a solution.
You should initially include a regular input element and forgo any of the required colouring. Use JavaScript to replace the input with a suitable container element. This can be styled to mimic an input element.
As changes occur, use JavaScript to identify the above-mentioned three divisions. Wrap them in suitable elements (spans would be ideal) and colour as needed.
Consider the following starting point for the generated replacement markup:
<div class="input">
<span class="nonEdited before">foo</span>
<span class="edited">fizz</span>
<span class="nonEdited after">bar</span>
</div>
Use click, keydown and keyup events to figure out the three divisions for the input and to apply wrap the three portions of the faked input as required.
As others have said, you can't do this with styles and static markup.
You could probably do it with a Flash-based form.
But, if I had to this, I'd use jQuery to overlay divs, with the colorized text, atop the <input>.
Algorithm:
Use a normal <input> with whatever default styles are desired. The contents of this input will never change except by user action.
jQuery monitors that <input>. When it detects trigger word(s), it adds a <div> after the input and fills it with the trigger word(s) -- styled as desired. Probably one <div> per word or phrase is best.
jQuery then positions the new <div>, absolutely, directly over the trigger word(s).
Getting the trigger word(s) offset within the <input> might not even be necessary, because the previous words could also be in the overlay <div> -- either styled defaultly or with visibility: hidden.
But, if only the trigger word(s) are desired in the overlay, then using a fixed-width font, like Courier, will help with the sub-positioning.
Take care that the overlay does not interfere with the user trying to mouse or key to certain parts of the <input>. IE, probably don't want to cover any more of the <input> than necessary, and set a click() handler to relay focus.
Alternate, user friendly and simpler approach:
Rather than try to do funky, non-user-expected things to the input, take a page from Jakob Nielsen and from sites like StackOverflow.
Just have a plain ol' <input>, but underneath it, show the formatted text as it comes in.
You can achieve this with (a lot of effort and) a div with the contentEditable attribute present. This is how most web-based WYSIWYG editors achieve rich formatting of inputs. See here for more info: http://ajaxian.com/archives/on-browser-wysiwyg
You can keep differently styled divs side by side in a container overlapped by a transparent input. Modify the widths of the styled divs on the basis of your input entry.
For example, to color input background for leading and trailing spaces:
<div class="bckg-container">
<div id="bckg-leading" class="bckg spaces">
</div>
<div id="bckg-middle" class="bckg">
</div>
<div id="bckg-trailing" class="bckg spaces">
</div>
<br style="clear: left;" />
</div>
<input id="inpt" type="text" placeholder="Add leading/trailing spaces" maxlength="20" />
The three divs inside the container will change their width with input change.
Check the working example in jsfiddle http://jsfiddle.net/TalhaAwan/ywyw4qq5/
You might be able to do it with some edit in place javascript (if it's not possible in pure html/css):
http://www.appelsiini.net/projects/jeditable/default.html
That jQuery plugin doesn't use html input fields so it could be possible to style different parts of the input. It has a couple of hooks for callbacks which you could use to style the input. Hope that helps as an idea.
You can have a label mocking that input and the real input to be hidden, then you can do a lot of things beteen label tags (e.g. colored spans).
If you absolutely have to style your html buttons, what is the correct way to emphasize some of them? e.g. "Add to cart" is usually emphasized visually to make it stand out.
Option 1 - wrap submit in em or strong + css
Option 2 - class + css
Option 3 - ?
CSS is the way to go. For example, on the Facebook "Notes" application, the "Publish" button is in strong blue, and the others are in grey. That's all done with CSS classes and IDs.
Ultimately, you should just look for a site you trust, if you want a second opinion on CSS. Tools like Firebug make it easy to see exactly how they do their styling.
A class would probably be you're most flexible solution. If you want to do anything more than just bold or italic then you are going have to use some sort of class/id anyway.
If you have this item in a container however, then you could just use that container to select your button.
html
<div class="foo">
<input type="submit" />
</div>
css
.foo input
{
...some styles
}
Putting the class on the input is perfectly acceptable though. The previous method is only if you already have the button in a container and you don't want to add any extra markup.
Well, if you're looking to emphasize a button, I'd say the most semantic representation is to wrap your <button> tag (or <input type="submit"> or whatever you're using) in <em> tags and style it in CSS, e.g.:
em button {
color: blue;
font-style: normal;
font-weight: bold;
}
(Remember that, while italics and bold may be the default visual styles for <em> and <strong> in most browsers, that's just convention. If you aren't "strongly" emphasizing something, just use <em> even if you want it displayed bold.)
The correct and semantic way would be
<button><em>label</em></button>
but since IE does not support multiple elements you have to use <input type="button"> -- and wrapping that in an em or something is bad.
I'd strongly prefer
<input type="button" class="emphasized"/>
or something..
With CSS2+ you could use option 3: Only CSS
input[type="submit"] {
border: 3px solid blue;
}
More info: http://www.w3.org/TR/CSS2/selector.html
I would use an Image Button... no emphasis can match the beauty of a well designed icon...
"A picture is worth a thousand words!"
Ask an open question, get a bunch of correct-but-different answers...
Most people just go for an image as the button as that bypasses a lot of browser issues. You know it will look the same on every browser.
You can use CSS to style the element you use to submit. Going that route, you can use the <input type="submit"> and style appropriately, or you can use <button type="submit">[lable goes here]</button>. I prefer the latter as its easier to style, but that's largely a personal preference.
Best advice is to look around and when you see something like what you want, look at how they did it.
A good way to think about these kinds of issues is to consider what you'd want from an aural browser. In this case, if your page is being read out, would you also want the button to emphasized by a different tone or volume of voice from the other buttons. If so, you should use semantic markup to indicate that this is emphasis and not just presentation.
<em> should really be used to emphasize individual words to indicate the where the stress should be placed in a sentence, so unless your button appears in the middle of sentence, I would prefer wrapping the input element in <strong> rather than <em>.
In addition, you can add CSS to get the visual effect you want.
A lot of sites use images. One problem with that can be inconsistency - you have to make all of your buttons images, or none of them or some will look out of place.
I generally go for:
larger font size (font-size: 120%)
bold text (font-weight: bold)
padding (more horizontal than vertical, e.g. padding: 4px 8px)
I don't change colours, because of the massive platform variations. Grey text might look fine for most people, but if the user is using a darker theme then the button background colour could make the text unreadable.
If you start changing any colours you'll need to set at least a color, background-color and border.