how to avoid browser sniffing by doing "feature" detection instead...? - cross-browser

So, let's say that I have an element that is inline-block. So this won't work with ie6 or FF2...
Say I compensate for it with css hacks and using -moz-inline-stack...
Now, let's say the inline-block element is also position: relative, so it is a container and has a child element with position absolute, top:0, right: 0.
In older browsers, the child element is in the top right of the screen, instead of in the top right of the inline-block container element...
Now, I can fix this by wrapping a div around my child element and make it 'position relative'... But I would like to avoid having unnecessary markup if possible.
Initially I wanted to do:
if (browser == ie6 || browser == ff2) {
wrap child element with div for older browser..
}
else {
assume everything is fine
}
but I am thinking something like this would be better to do:
if (child element is at the top right of the screen) {
wrap child element with div for older browser..
}
else {
assume everything is fine
}
So I am just curious, how people here would recommend this sort of thing.
Thanks!

In general, Modernizr does browser feature detection best. Modernizr
adds classes to the element
which allow you to target specific
browser functionality in your
stylesheet. You don't actually need to
write any Javascript to use it.
While it may not be applicable to your particular scenario, Modernizr does CSS feature detection as well. For example,
Have you ever wanted to do
if-statements in your CSS for the
availability of cool features like
border-radius? Well, with Modernizr
you can accomplish just that!

Related

Remove HTML element completely just by using CSS?

Just like removeAttribute in JavaScript, after which the element won't be visible in the source.
You cannot remove an element from the DOM tree using CSS. You can only prevent it from being rendered in the layout with display: none; doing so does not prevent it from responding to events or cause it to be ignored by CSS selectors such as + and :nth-child(). You won't be able to interact with an element that's not there so you wouldn't be able to trigger events the usual way, but its "essence" remains, so to speak.
Its not possible with CSS.
Even if you use display:none, the element will be still in DOM tree.
CSS is for styling not for DOM manipulation. Use JavaScript for that.
display: none;
'Unlike the visibility property, which leaves an element in normal document flow,display: none removes the element completely from the document. It does not take up any space, even though the HTML for it is still in the source code. This is because it is, indeed, removed from the document flow. For all intents and purposes, the item is gone. This can be a good thing or a bad thing, depending on what your intentions are. It can also be damaging to your page if you misuse this property!'
https://www.lifewire.com/display-none-vs-visibility-hidden-3466884
You can use display: none to hide an element but it will still be on the DOM.
You can also use visibility: hidden and it will also still be on the DOM but the DOM will reflect the same vertical flow even though the element is hidden. In other words if the element is a block, a block space will still be reserved for the hidden element. And with display: none the space will also be removed along with the element as it is hidden.
Unless you use JavaScript, with CSS you are only changing the visibility of a DOM element that is existent on the DOM. Which can absolutely serve your purpose depending on what you are trying to do.
If you need more help, just comment with more detail and I'd be glad to help.
You actually can. Not directly in CSS but in combination with Javascript/jQuery you could.
In HTML give a class of "removeFromDom" to the Elements you want to have removed.
<p class="removeFromDom">your text here</p>
In CSS you add these Lines to make it invisible, if JS is not working.
.removeFromDom { display:none !important; visibility:hidden !important; }
In a jQuery file, that you load on any site, create this function::
$(document).ready(function() {
$(".removeFromDom").remove();
});
Et voila.. your jQuery file removes your Items from the DOM. I wouldn't recommend it for security reasons if there is a link nobody should be able to see anytime..

Benefits/Drawbacks of using pseudo elements (:after, :before) vs. padding/background positioning?

I'm digging through some older code on a site that I'm working with, which uses iconize. The way that it seems to work is by adding a class like this...
a[href=$='.pdf']{
padding: 5px 20px 5px 0;
background: transparent url('icon.gif') no-repeat center right;
}
Is there any benefit to doing it that way than the way that I'd have done it? Something like this...
a[href=$='.pdf']:after{
content: url('icon.gif');
vertical-align: sub;
}
Here's a fiddle to demonstrate both of them...
JSFiddle
My question is... What are the benefits, if any, of using pseudo-elements vs. standard padding and background positioning for appending/prepending images to elements?
Just a few initial and later thoughts. I may still think of some more to add.
Padding/Background
Advantage(s):
Works for IE6-7 (i.e. older browsers).
If one wanted to overlap the icon with the text, especially if centered, this would be easier to implement.
Disadvantage(s):
More thought needed to implement (must calculate some factors).
For older browsers, only one background was supported, so if another background was needed, then there was a conflict to be resolved.
If browser is set to not print background images, then a "gap" for the padding will still exist in the printed text, but no image will be there. This could be resolved through print media css.
Pseudo-Elements
Advantage(s):
Easier to implement (no calculations needed).
It can have its own padding, border, opacity, etc. applied if desired, just as if it were a real element.
Related to #2, it can actually be moved outside the element if needed or desired.
Semantically, it is being implemented in a more appropriate manner. The icon is not really a "background," but neither is it an essential part of the html that a content img might be, so the pseudo-element fits the bill for enhancing the presentation, but not causing issues if it is missing (in older browsers).
In CSS3 browsers (and possibly CSS2), usually less code can be used to switch between right or left aligned icons (see "Discussion about code length" below).
Disadvantage(s):
Only one (of each type) allowed per element, so if it is needed for something else on an element, then you can have conflict.
Not supported in older browsers.
Some elements (replaced elements) cannot take pseudo-elements, so this would not even be an option.
Discussion about code length
EHLOVader noted in a comment to the question that part of his concern was extra coding that might be needed for pseudo-elements as opposed to background/padding if one wanted to switch to a left side icon. He gave this codepen example. However, it can be made to be less code to do a pseudo-element. Assuming .iconleft is a class used to put the icon left rather than right, and .iconit the class that sets an icon at all, then the following code concisely makes it happen for CSS3 browsers using the :not() selector (here is the fiddle, using the original .pseudo class of the OP for iconing):
.iconit:not(.iconleft):after,
.iconit.iconleft:before {
content: url('http://www.jasonapollovoss.com/web/wp-content/uploads/2010/09/pdf_icon_small.png');
vertical-align: sub;
}
The same could be done with CSS2 browsers if an iconright class is used to explicitly set an icon to the right, or iconleft to the left (no iconit class needed then):
.iconright:after,
.iconleft:before {
content: url('http://www.jasonapollovoss.com/web/wp-content/uploads/2010/09/pdf_icon_small.png');
vertical-align: sub;
}
What makes pseudo-classes so useful is that they allow you to style content dynamically. In the example above, we are able to describe how links are styled when the user interacts with them. As we’ll see, the new pseudo-classes allow us to dynamically style content based on its position in the document or its state
Read more http://coding.smashingmagazine.com/2011/03/30/how-to-use-css3-pseudo-classes/

Show outlines around divs in a web-based HTML editor, a la Dreamweaver and other editors

I'm writing a simple contenteditable-based HTML editor, one which lets the user edit a page that is styled by their own CSS (which they can live-edit) and also do basic things like insert new tags, apply classes, etc.
One feature I'd like to have is an option to toggle the display of dotted borders around divs, much like you typically find in WYSIWYG HTML editors such as Dreamweaver, Expression Web, and many others. (This helps the user see her divs even when they have no visible border.)
Is there any possible way to do this? Some ideas:
I can't simply modify the CSS on the actual/existing divs, since they may already have their own borders defined, which I should not obliterate with dots. Ideally, I can show a border around the existing borders, which is how things appear in the aforementioned commercial editors. Even if I fall back to actually setting borders on elements that have no existing borders, figuring out which ones have no borders may be difficult, esp. in the face of things like :hover which dynamically change the computed style.
I may wrap these divs inside new divs, which in turn have the dotted border. The tricky part is handling their CSS, e.g.:
Wrappers must be similarly styled as their children, e.g. a div that has width:50px must have a wrapper that's also width:50px (roughly), so I'd either need to continually poll (as there's no way to be notified of indirect style changes, e.g. on the class) for changes to the computed style (which is completely non-scalable), or implement my own CSS engine that runs and determines what has changed each time the user live-edits their CSS.
Polluting the DOM with my own divs is invasive and interferes with rules such as:
/* these may or may not be divs */
.a > .b > .c { ... }
or:
/* if this is wrapped, then they'll all be :first-child */
.foo:first-child { ... }
or perhaps:
/* immediate children of my wrappers would inherit the dotted borders */
.foo { border: inherit; }
Perhaps there's a way to automatically rewrite these rules robustly - to take the last example:
:not(.my-dotted-border) > .foo { border: inherit; }
But even if theoretically possible, there are a ton of cases to worry about and it would be quite hairy.
Lastly, perhaps there's a way to collapse margins even with the dotted border, but I don't know of it.
Another idea is to overlay the borders on top (absolutely positioned with JS based on the dimensions/offsets of the underlying elements), but this is ugly with overlapping elements that have particular z-indexes, and again I'd need to monitor all elements for style changes. Except now it's not enough just to monitor the changes in the explicitly specified styles, as I need to react to changes even to offset and dimensions (e.g. if the user types some text, it may push down all the elements below it, so I must react to that by updating the overlays).
A related question is See the page outlines but this is from the perspective of a user who wants to see outlines - I'm asking from the perspective of a web-based editor implementation, how to provide these outlines.
Thanks in advance for any tips.
You can use the outline and outline-offset CSS properties to style the outline of your editable divs as they will not overwrite any existing borders (they will however overwrite any existing outlines if there are any).
Check out this example to get an idea of how you can implement it: http://jsfiddle.net/EFJ6B/

HTML forcing img dimensions requires block?

I have a situation where I would like an HTML img which has not yet loaded to have a pre-set height. The reason is that this height will be used in a calculation that may fire before the image is fully loaded and needs to remain accurate. I tried the following:
<div>hello<img src='http://example.com/invalid.gif' class="testimage"> there</div>
and put in some css
.testimage {
height: 200px;
width: 200px;
}
​
and at least in Firefox 5, the extra space is not rendered (and oddly, the broken image doesn't show either, just a blank space). That is, until I add display: inline-block. In at least some other browsers the default display of inline produces the desired result. Is this expected? If so, why?
Here's a jsFiddle as well: http://jsfiddle.net/uYXD4/
it says here that images are inline elements - http://htmlhelp.com/reference/html40/special/img.html
On the other hand take a look here - Is <img> element block level or inline level?
It looks like the <img> element is kind of both inline and block. No strict rules defining it, so probably the browser vendors make their own decisions about the defaults. So your best bet is to reset their assumptions to display: inline-block
Images are replaced elements:
An element whose content is outside the scope of the CSS formatting model, such as an image, embedded document, or applet. For example, the content of the HTML IMG element is often replaced by the image that its "src" attribute designates.
For replaced elements, display: inline-block is supposed to have the same exact same efffect as display: inline, which is the default.
So this may be a possible explanation for that strange behaviour in some browsers*:
They treat only completely loaded images as replaced elements, and otherwise treat them as non-replaced elements. That makes sense after all, and the standard does not explicitly disallow that. As a consequence, there's 3 possible scenarios:
replaced element, inline or inline-block doesn't matter, height property works
inline non-replaced element, height attribute has no effect
inline-block non-replaced element, height property works
Loaded images always qualify as 1., and broken/loading images may qualify as 1. or 2. (or 3. if you set display: inline-block explicitly)
*Not sure if that's how things actually work though.
Why not use something like
<img src="..." width=400 height=200>
I'm doing the exact same thing and it works quite well. Another option is...
$('.myimg').load( function() { /* ops */ } );
though I don't know if that waits to load the image in ALL browsers or not

Placing HTML Pseudo elements

My css looks like this;
p:not(.dummy):after
{
content: url(../../irhiddenchars/img/afterimage_9x9.gif);
}
I wish to take a taller (height) gif, but my lineheigth is increased when the css gets applied (even though there seems to be enough space for a bigger picture, line-height for a p-tag is 18px). Is it possible to place the pseudo element containing the gif somehow a little bit higher on the page?
Is there any other solution?
Try setting the margin and padding to 0. The p elements (among others) have a implicit standard mark-up determined by the browser.
I'm still wondering however why you use the :after pseudo-class instead of nesting an img. Any specific reason for that?
Edit: Wow, this question is 2 months old, why did it appear on the recent questions page?
I solved it dropping the image after approach (i had an image showing a Pilcrow symbol). Instead i use the Pilcrow character (which gets rendered according to the fontsize choosen):
body.hiddenchars p:after
{
content: '\00b6';
}
use jQuery, not only to insert the content but you can then give it a class and style it to position exactly where you want it.