Theres a mistake in my rather large demo where i assume all the divs under the class special will be used to align something. Now i realize i need to add an extra div outside of the part i want to align but inside of .special.
How do i write .special div[NOT someclass] ? or is there no way to do this and i need to rewrite a lot of html?
CSS3 includes the not() selector. The only problem is (you guessed it) no IE compatibility. If you're willing to require Javascript from IE <9 users, you can get IE compatibility with IE9.js.
+1 to both answers above.
I'll add i was able to get away with some things but writing this in the css block to undo the effect
some-type: inherit;
I would go with jQuery or some other Javascript Framework, the selectors just rock and NOT class XY is rather easy to achieve.
As Pekka pointed out I am not sure what brothers you want to target. getElementsByClassName() is implemented by almost all browsers (you know which one doesn't work, don't you?).
I found a rather nifty solution on devshed to also make it work in IE:
onload=function(){
if (document.getElementsByClassName == undefined) {
document.getElementsByClassName = function(className)
{
var hasClassName = new RegExp("(?:^|\\s)" + className + "(?:$|\\s)");
var allElements = document.getElementsByTagName("*");
var results = [];
var element;
for (var i = 0; (element = allElements[i]) != null; i++) {
var elementClass = element.className;
if (elementClass && elementClass.indexOf(className) != -1 && hasClassName.test(elementClass))
results.push(element);
}
return results;
}
}
}
All you need to do now is to iterate through all your div classes and negate the one you DON'T want.
Related
If I have an HTML element <input type="submit" value="Search" /> a css selector needs to be case-sensitive:
input[value='Search'] matches
input[value='search'] does not match
I need a solution where the case-insensitive approach works too. I am using Selenium 2 and Jquery, so answers for both are welcome.
CSS4 (CSS Selector Level 4) adds support for it:
input[value='search' i]
It's the "i" at the end which does the trick.
Broader adoption started mid-2016: Chrome (since v49), Firefox (from v47?), Opera and some others have it. IE not and Edge since it uses Blink. See “Can I use”...
It now exists in CSS4, see this answer.
Otherwise, for jQuery, you can use...
$(':input[name]').filter(function() {
return this.value.toLowerCase() == 'search';
});
jsFiddle.
You could also make a custom selector...
$.expr[':'].valueCaseInsensitive = function(node, stackIndex, properties){
return node.value.toLowerCase() == properties[3];
};
var searchInputs = $(':input:valueCaseInsensitive("Search")');
jsFiddle.
The custom selector is a bit of overkill if doing this once, but if you need to use it many times in your application, it may be a good idea.
Update
Is it possible to have that kind of custom selector for any attribute?
Sure, check out the following example. It's a little convoluted (syntax such as :input[value:toLowerCase="search"] may have been more intuitive), but it works :)
$.expr[':'].attrCaseInsensitive = function(node, stackIndex, properties){
var args = properties[3].split(',').map(function(arg) {
return arg.replace(/^\s*["']|["']\s*$/g, '');
});
return $(node).attr(args[0]).toLowerCase() == args[1];
};
var searchInputs = $('input:attrCaseInsensitive(value, "search")');
jsFiddle.
You could probably use eval() to make that string an array, but I find doing it this way more comfortable (and you won't accidentally execute any code you place in your selector).
Instead, I am splitting the string on , delimiter, and then stripping whitespace, ' and " either side of each array member. Note that a , inside a quote won't be treated literally. There is no reason one should be required literally, but you could always code against this possibility. I'll leave that up to you. :)
I don't think map() has the best browser support, so you can explictly iterate over the args array or augment the Array object.
input[value='Search'] matches
input[value='search' i] Also matches in latest browsers
Support:
version : Chrome >= 49.0, Firefox (Gecko) >= 47.0, Safari >= 9
You can't do it with selectors alone, try:
$('input').filter(function() {
return $(this).attr('value').toLowerCase() == 'search';
});
I wonder what the the part ::-webkit-search-decoration do in the CSS selector for input[type="search"]::-webkit-search-decoration?
And why is this causing en DOM Exception error?
function is(selector, element) {
var div = document.createElement("div"),
matchesSelector = div.webkitMatchesSelector;
return typeof selector == "string" ? matchesSelector.call(element, selector) : selector === element;
}
is('input[type="search"]::-webkit-search-decoration', document.body);
It allows you to make search boxes look uniform across multiple browsers. Chrome for instance has default styling for search boxes that does not fit into some designs.
here is a good link on the topic.
http://geek.michaelgrace.org/2011/06/webkit-search-input-styling/
It just makes your search box little bit styled.As it is one of the property for css3 then it will not work on every browser.
Have a look in this link
http://css-tricks.com/webkit-html5-search-inputs/
I need an if/else statement for my CSS which can count list items. Would this be possible?
Basically I want to say, if there are less than 10 list items, the UL container should be 200px wide, and it there are more than 10 list items, it should be 400px wide. Something like that.
Can it be done?
I would appreciate a working demo on jsFiddle, both so I can see working code, and for anyone who looks here in the future so they can see a working example and how to do it :)
CSS only does styles, but not dynamically (unless with assistance of JS). you can use the following JS snippet for the task. just to make sure, load this at the very last, just before the </body>
<script type="text/javascript">
(function resize() {
//get all lists with selected name
var lists = document.getElementsByClassName('myList');
//loop through all gathered lists
for (i = 0; i < lists.length; i++) {
//shorthand elements for easy use
var list = lists[i];
var items = list.getElementsByTagName('li');
//append class names
list.className = (items.length < 10) ? 'myList less' : 'myList more';
}
}())
</script>
.less{
width:200px;
}
.more{
width:400px;
}
CSS has no if else statements. You can do this easily with jQuery. Another option would be to use LESS or SCSS.
Short answer: no. CSS offers no conditional support.
Long answer: you need to use javascript or a server side language to either add a class when there are more than 10 items (or elements) in the list, or in the case of javascript, directly manipulate the style after it's loaded.
That doesn't sound possible for CSS. There are no logical if/else statements in the CSS spec. Your next best bet would probably be javascript. You could achieve this with jQuery with the following code:
if($('ul#target-list li').length < 10) {
$('ul#target-list').css('width', 200);
}
else {
$('ul#target-list').css('width', 400);
}
Pure CSS3 Solution
If you only want to support CSS3, then this does what you need:
li {
width: 200px;
}
li:nth-last-child(n+11),
li:nth-last-child(n+11) ~ li {
width: 400px;
}
But you will need to make the ul either display: inline-block or float it so that the width is controlled by the li elements themselves. This may require you to wrap the ul (display: inline-block) in a div so that it still is a block element in the flow of the page if you need it so.
I'm trying to use modernizr to test for :nth-child browser support but I'm not sure how to do it, I found this one http://jsfiddle.net/laustdeleuran/3rEVe/ which tests for :last-child but I don't know how to change it to detect :nth-child (I was also thinking about using it like that since I believe that browsers that don't support :last-child don't support :nth-child either but I'm not sure)
Can you guys help me? Thanks in advance!
I just wrote a function to detect the :nth-child support for you
function isNthChildSupported(){
var result = false,
test = document.createElement('ul'),
style = document.createElement('style');
test.setAttribute('id', 'nth-child-test');
style.setAttribute('type', 'text/css');
style.setAttribute('rel', 'stylesheet');
style.setAttribute('id', 'nth-child-test-style');
style.innerHTML = "#nth-child-test li:nth-child(even){height:10px;}";
for(var i=0; i<3; i++){
test.appendChild(document.createElement('li'));
}
document.body.appendChild(test);
document.head.appendChild(style);
if(document.getElementById('nth-child-test').getElementsByTagName('li')[1].offsetHeight == 10) {result = true;}
document.body.removeChild(document.getElementById('nth-child-test'));
document.head.removeChild(document.getElementById('nth-child-test-style'));
return result;
}
Usage:
isNthChildSupported() ? console.log('yes nth child is supported') : console.log('no nth child is NOT supported');
You can see this works in action here
http://jsbin.com/epuxus/15
Also There is a difference between jQuery :nth-child and CSS :nth-child.
jQuery :nth-child is supported in any browser jQuery supports but CSS :nth-child is supported in IE9, Chrome, Safari and Firefox
I remember there was a Modernizr selectors plugin that tested for selectors support, but I can't find it right now. You can take a look at this: http://javascript.nwbox.com/CSSSupport/ which is similar.
You can also use Selectivizr to add CSS3 selector support to unsupported browsers
Mohsen, thank you for your decision.
If someone needs to jQuery:
function test(){
var result = false,
test = $('<ul id="nth-child-test"><li/><li/><li/></ul>').appendTo($('body')),
style = $('<style type="text/css">#nth-child-test li:nth-child(even){height:10px;}</style>').appendTo($('head'));
if(test.children('li').eq(1).height() == 10)
result = true;
test.remove();
style.remove();
return result;
};
I'm looking to set the background-image (or even render an image via the pseudo elements :after or :before) to the value, which will be a URL, of a rel attribute, but only in certain cases (this is a cloud file listing). For example:
HTML:
<div class="icon ${fileExtension}" rel="${fileURL}"></div>
It would be great if I could do something like this:
CSS:
.icon.png,
.icon.jpg,
.icon.jpeg,
.icon.bmp,
.icon.gif { background-image: attr(rel,url); }
... but obviously that doesn't work as, if I'm not mistaken, the attr() CSS function only works inside pseudo element blocks.
I know there are ways of doing this using conditional JSP or even jQuery logic, but I'd like to figure out a neat way of doing it via CSS3, since I'm only concerned with modern browsers at the moment anyway.
Also, I don't want to explicitly set the background image to the URL or create an <img> element, because by default if the file is not a supported image, I'd rather display a predetermined set of icons.
Using
.icon:after{ content: ""attr(rel)""; }
displays the rel value as text.
A jQuery solution is to add the background-image (taken from the rel value) as inline CSS:
jQuery(function($) {
$('.icon').each(function() {
var $this = $(this);
$this.css('background-image', 'url(' + $this.attr('rel') + ')');
});
});
I've tried to do something using jQuery but i don't exactly understand what you want so i can't go on with my code. So far i've done only this.
EDITED I hope it's exactly what you need
$(function(){
var terms = new Array('png','jpg','jpeg','bmp','gif');
$('.icon').each(function(){
var t = $(this),
rel = t.attr('rel'),
cls = t.attr('class');
cls = cls.split(' ');
for (var i=0; i < terms.length; i++) {
if (terms[i] == cls[1]) {
t.css('background-image','url('+rel+')');
}
}
});
});
if you can give me a better example, to undestand exactly what you want, i hope somebody from here will be able to solve your problem.
Regards,
Stefan
I've decided to go the jQuery route, and used a combination of #ryanve and #stefanz answers. Thanks guys
$(document).ready(function() {
$(".png,.jpg,.jpeg,.bmp,.gif,.tiff").each(function(n) {
var bg = 'url(' + $(this).attr("rel") + ')';
$(this).css('background-image', bg);
});
});
I think this is relatively neat/concise and works well for my needs. Feel free to comment on efficiency, methodology, etc.