image
question
Is there any way I can shift the "Vancouver, BC" text down a little bit so it aligns better with "CITIES" and "CHANGE"?
I know input elements are finicky to style across browsers; it doesn't have to be perfect but if it could work in at least some browsers, that would be great.
fiddle
Customizing a browser's default rendering of some form elements--especially dropdown select lists--is generally not recommended for a few reasons:
Your customization options are naturally limited
It's extremely difficult to get the form element to look the way you want--as you noted, they're finicky
Even if you can get the input to look the way you want in one browser, its almost impossible to do it cross-browser (I realize you said that's not a concern, but still, it's worth knowing)
From a usability perspective, customizing the default rendering of a form element almost always reduces the usability of the form somewhat
NOW, all of that being said, if you want more control over the visual styles of your form elements, I'd recommend using a jQuery plugin. Typically these work by hiding the form elements and replacing them with easily-customizable CSS--usually regular ol' unordered-lists--and then sending the user interactions with the unordered lists to the hidden forms. Here's one you could check out to get started.
I would adjust the font-size or the height to fix the alignment issue:
#city_picker {
height: 26px;
font: 19px Arial,Helvetica,sans-serif;
}
That would make the text about the same size as the select box, and force it to appear aligned. Otherwise it seems rather difficult if not impossible to adjust styles of the option elements across browsers.
Related
I want to replace some third party generated content using pure CSS. There are various techniques covered by other questions but the basic idea is hide the exiting content and add new content with pseudo selectors.
I'm interested in whether this is an acceptable thing to do from an accessibility point of view. Would a screen reader see both bits of text or only the original? Should the CSS be wrapped in #media screen {} to avoid both being used?
In my situation I can only use CSS. I can't edit the HTML or use any JavaScript. Is there any way to present only the replacement text to a screen reader?
.third-party-content {
font-size:0;
}
.third-party-content:before {
content:"lovely replacement";
font-size:initial;
}
<div class="third-party-content">unwanted garbage</div>
Don't use CSS generated text to convey meaningful information at all.
Screen readers don't behave the same. Some of them always read it, some of them never, and some of them sometimes do or don't depending on other properties.
For example, NVDA reads CSS generated text most of the time; Jaws rarely does (if ever it does sometimes).
Anyway, according to the base separation principle: content/structure=HTML, behavior/action=JavaScript, appearance=CSS, it isn't semantically correct to let CSS generate meaningful text.
It should be done in HTML. In fact the CSS Content propertiy should never be used for something else than text icons and other pure visual things that don't really matter for general understanding if they are skipped / not shown / not read.
Changing the font-size to 0 just changes the visual appearance of the text but does not hide it from a screen reader. A screen reader does not care what size the font is. It's just text that will be read.
When a screen reader reads text, it's called the "accessible name". The accessible name is computed according to these rules - https://www.w3.org/TR/accname-1.1/#step2. In particular, see step 2.F.ii
"ii. Check for CSS generated textual content associated with the current node and include it in the accumulated text. The CSS :before and :after pseudo elements can provide textual content for elements that have a content model."
One way to hide text from a screen reader is to use the aria-hidden attribute but that would require changing the HTML, which you stated you can't do. Text is also hidden using standard display:none, but that would obviously hide your :before text too.
Using CSS tricks to visually hide text, such as clip, position, width, etc, again just visually hides the text but does not hide it from a screen reader.
I'm not a CSS expert but building on your attempted solution of font-size, I added visibility:hidden and it seemed to work. I know hidden just makes the text invisible but still takes up space on the screen, but when combined with your font-size:0 (and inherit) it prevents the "unwanted garbage" from taking up any space so if you had an element adjacent to your original, you wouldn't have a big gap between the two.
visibility:hidden does hide the element from the screen reader.
.third-party-content {
font-size:0;
visibility:hidden;
}
.third-party-content:before {
content:"lovely replacement";
font-size:initial;
visibility:initial;
}
You cannot use display:none in a similar solution because as soon as the parent is hidden, the :before is hidden too.
Update: This solution works with NVDA (screen reader) on firefox and VoiceOver on iOS. (Chrome with screen readers is typically not tested because Chrome has sporadic support for screen readers.) It does not work with JAWS on Internet Explorer but IE seems to have two problems. The first is that your font-size:initial does not work on the :before. I had to set it to font-size:16px. Second is that IE does not correctly compute the text to be read as noted in step 2.F.ii above. IE is not honoring the content property so "unwanted garbage" is still read (and "lovely replacement" is not read). Since step 2.F.ii is a W3 spec, I'd say IE has a bug.
If content were correctly read by IE, then there might still be a problem. Since font-size:inherit doesn't work in IE, visibility:inherit might not work either. (I tried a simple case and it didn't work. Setting visibility:visible on :before also didn't work on IE.)
I am looking to disable a few html controls and I am running into cross browser issues with the differences between IE and Firefox/Webkit browsers. The primary issue is evident with the following line:
<input type="text" name="badIE" disabled="disabled" style="color:blue;" value="IE won't show this correctly" />
In IE, the above input would have grey text, while the text is blue in every other browser I have tested. It would appear that IE allows the disabled field of a text input to take precedence over the CSS rules for the text color. Is there any established best practice or IE CSS hack to address this type of issue?
According to the upvoted (but not accepted) answer here, you're kind of stuck with using 'readonly'.
Just out of curiousity - why are you displaying text in a textarea that you don't even want your users to be able to focus on? Seems to me you'd be better off displaying that in a regular text HTML element (e.g. <p>).
It turns out that there are few different ways to attack this problem but there isn't one exact answer. In order to provide the most complete answer possible, here is a list of the possible solutions.
Accept the differences between browsers and continue using the disabled field. This is probably the right answer. As chipcullen suggested on his comment, there is rarely a necessity that all browsers look identical. It is better to simply accept the differences between and work with them.
Use the readonly attribute instead of disabled. The problem with this method is that a user can still interact with a readonly control. For example, users could focus on the control or stick a blinking cursor in the middle of the text. If interaction is a major concern, you can always shield the disabled control behind an invisible element, although that method is on the hacky side.
The option I chose was to replace the input elements with a pure text element. Although this method might not be as straightforward as it might sound. My page was interactive and certain elements would be enabled/disabled depending on client side actions. In order to handle the transition, I threw together the following Javascript (after chipcullen's suggestion and with the help of jQuery):
function disabledToSpan() {
$('input[type=text]:disabled, textarea:disabled').replaceWith(function () {
return $('<span>' + $(this).val() + '</span>').attr('class',
$(this).attr('class')).addClass('disabledTextInput');
});
}
In summary, this will find all disabled text inputs and textareas, switch them to spans while preserving both their values and classes, before finally adding a disabledTextInput class to specially stylize the disabled elements.
See the picture above. Each navigation tab needs to have 2 pixels separation on either side and line up exactly with the header image on the edges.
Now they would like to introduce a 5th navigation tab (and possibly a 6th). Is it possible to code this in a way where you could stick a 5th or 6th tab in there and everything would resize appropriately with lists or tables or some other solution? Still keeping the 2 pixels separation and lining up with the edges exactly? I wasn't sure if it was possible or you would just have to define the widths each time for each tab based on the math involved to line it all up correctly flush with the edges.
I think the best way is to emulate table behavior with CSS. So you can use a list, and still get table behavior.
ul {
display:table;
}
li {
display:table-cell;
}
Here is a demo displaying this with CSS and proper markup. Here's a demo of how it looks with an actual table. I'm not certain on IE<8 support for this CSS, so it may be something to be aware of.
UPDATE: Confirmed: This is not supported on IE6 or 7 natively. You may be stuck with tables or hard-coded widths if you want to support those browsers. There may be a javascript fix to support these display values but I'm not aware of it.
EDIT: I realized my demos were sloppy, so I made another that actually addresses your point about the margins, it uses the :first-child selector to remove the margin from the first link, giving the evenly distributed appearance. http://jsfiddle.net/wesley_murch/pe6wd/3/
It may not be easy. One of the requirements in most implementations of css horizontal menu type displays is setting a fixed width for each element. If you try and do percentages, things start to come apart. However, any thing is possible.
Have you tried looking at LESS or SASS so you can do simple math in CSS?
i'm solving a problem to make select inputs look the same in all browsers (Chrome and Safari on Mac renders them differently) how to do that ?
The ONLY way to make them look the same right now would be to hide the original inputs, and replace them with appropriately styled html equivalents (of god forbig Flash objects), which would act as proxies, passing the functionality over to the hidden inputs.
That may be automated with JavaScript. But that would be WRONG. You are not supposed to force a different look on to OS styled elements of the webpage. It conflicts with a lot of usability and accessibility practices.
So, the only way is to make your design flexible enough to support differently looking control elements on a web page, and also use different stylesets for different browsers, to ease the adjustment of the styles (at the moment there are no inputs that would look and act the same on all browsers with the same style rules applied).
Unfortunately, life just kinda sucks on this one. Just wait till you need to style a file input...now that's some fun!
if you dont mind using js you can simply design your own look (a jpg img it can even be the same img as the original select element or if you wish you can model parts of it in css)
Then place a div on top of that image that div will contain the text which select element would usually contain
<div id="selectTxt" >
then set another div on top of that with the select element inside it.
<div id="transparentSelect" class="transparent">
<select id="selectCar" name="selectCar">
<option>Volvo</option>
<option>Saab</option>
<option>Mercedes</option>
<option>Audi</option>
</select>
</div>
Now the trick is to set the select element opacity to zero
you can do this by adding by adding a class transparent
and then applying the class to the div
.transparent
{
filter:alpha(opacity=0);
-moz-opacity: 0;
opacity: 0;
}
now the element is hidden but when you click on it the list will still show up.
So the list will always look like the default list in the browser
now use js to extract the select value every time you click on the select
and set the inner html of selectTxt div to its value.
This way you get the text of the select on top of an image you want
you can make the image animated with the hover effect in css or with js
I also make a select that looks the same in all browsers but it doesnt work when you click directly on the arrow...
so its an inferior version but if you wish to look at it here it is
http://jsfiddle.net/fiddlerOnDaRoof/LM73V/
it also lacks the arrow image but you can print screen that from your browser
good luck
You should apply a CSS to reset the styles (not just for the inputs, this is a highly recommended practice for all element so that your page looks almost the same in all browsers) there are many, just google a little, for example this one, and then apply your desired styles (border color and width, background, etc...) take a look at this tutorial on how to style form elements
For an iPhone ebook application I need to break arbitrarily long HTML documents up into pages which fit exactly on one screen. If I simply use UIWebView for this, the bottom-most lines tend to get displayed only partly: the rest disappears off the edge of the view.
So I assume I would need to know how many complete lines (or characters) would be displayed by the UIWebView, given the source HTML, and then feed it exactly the right amount of data. This probably involves lots of calculation, and the user also needs to be able to change fonts and sizes.
I have no idea if this is even possible, although apps like Stanza take HTML (epub) files and paginate them nicely. It's a long time since I looked at JavaScript, would that be an option worth looking at?
Any suggestions very much appreciated!
update
So I've hit upon a possible solution, using JavaScript to annotate the DOM-tree with sizes and positions of each element. It should then be possible to restructure the tree (using built-in XSLT or JavaScript), cutting it up in pages which fit exactly on the screen.
Remaining problem here is that this always breaks the page on paragraph-boundaries, since there is no access to the text at a lower level than the P-element. Perhaps this can be remedied by parsing the text into words, encapsulating each word in a SPAN-tag, repeating the measurement procedure above, and then only displaying the SPAN elements that fit onto the screen, inserting the remaining ones at the front of the next page.
All this sounds rather complicated. Am I talking any sense? Is there a simpler way?
You should look at the PagedMedia CSS module: http://www.w3.org/TR/css3-page/
CSS3 also support multicolumn layouts (google for "css3-multicol". I don't have enough Karma to include a second link here :-)
About your update: how about doing the layout of one single page, then use a DIV with overflow:hidden for the text part. Next thing would be to overlay a transparent item on top of that, that would programmatically scroll the inner content of the DIV PAGE_HEIGHT pixels up or down according to some navigation controls (or gestures).
The other option is to have a parent <div> with multiple css3 columns: link1, link2.
This works on Android:
<style type='text/css'>
div {
width: 1024px; // calculated
-webkit-column-gap: 0px;
-webkit-column-width: 320px; // calculated
}
p {
text-align: justify;
padding:10px;
}
</style>
The CSS multicol suggestions are very interesting! However, and I hope it's ok to respond with another question: how would you go from splitting one or more long <p> elements into columns to having one particular of these columns being rendered in a WebView? The DOM hasn't changed, so you can't pick out an element and render it. What am I missing?