Best css questions in July 2012

"text-align: justify;" inline-block elements properly?

16 votes

A few other questions have already addressed how best to apply text-align: justify to get inline-block elements to spread out evenly… for example, How do I *really* justify a horizontal menu in HTML+CSS?

However, the 100% width element that "clears" the line of inline-block elements is given its own line by the browser. I can't figure out how to get rid of that empty vertical space without using line-height: 0; on the parent element.

For an example of the problem, see this fiddle

For my solution that uses line-height: 0;, see this fiddle

The solution I'm using requires that a new line-height be applied to the child elements, but any previously set line-height is lost. Is anyone aware of a better solution? I want to avoid tables so that the elements can wrap when necessary, and also flexbox because the browser support isn't there yet. I also want to avoid floats because the number of elements being spaced out will be arbitrary.

Present Workaround (IE8+, FF, Chrome Tested)

See this fiddle.

Relevant CSS

.prevNext {
    text-align: justify;
}

.prevNext a {
    display: inline-block;
    position: relative;
    top: 1.2em; /* your line-height */
}

.prevNext:before{
    content: '';
    display: block;
    width: 100%;
    margin-bottom: -1.2em; /* your line-height */
}

.prevNext:after {
    content: '';
    display: inline-block;
    width: 100%;
}

Explanation

The display: block on the :before element with the negative bottom margin pulls the lines of text up one line height which eliminates the extra line, but displaces the text. Then with the position: relative on the inline-block elements the displacement is counteracted, but without adding the additional line back.

Though css cannot directly access a line-height "unit" per se, the use of em in the margin-bottom and top settings easily accommodates any line-height given as one of the multiplier values. So 1.2, 120%, or 1.2em are all equal in calculation with respect to line-height, which makes the use of em a good choice here, as even if line-height: 1.2 is set, then 1.2em for margin-bottom and top will match. Good coding to normalize the look of a site means at some point line-height should be defined explicitly, so if any of the multiplier methods are used, then the equivalent em unit will give the same value as the line-height. And if line-height is set to a non-em length, such as px, that instead could be set.

Definitely having a variable or mixin using a css preprocessor such as LESS or SCSS could help keep these values matching the appropriate line-height, or javascript could be used to dynamically read such, but really, the line-height should be known in the context of where this is being used, and the appropriate settings here made.

Possible Future Clean Solution

A solution in which webkit is behind the times (as of writing this) is:

.prevNext {
    text-align: justify;
    -moz-text-align-last: justify;
    -webkit-text-align-last: justify; /* not implemented yet */
    text-align-last: justify; /* IE */
}

Which works in FF 12.0+ and IE8+ (buggy in IE7). Because it is not supported by webkit yet, it is really only a partial solution. However, I thought I should post it as it can be useful for some.

How can I show dots ("...") in a span with hidden overflow?

13 votes

my css

     #content_right_head span
    {
    display:inline-block;
    width:180px;
    overflow:hidden !important;
    }

now its showing content content

but i want to show like content content ...

I need to show dots after contents

Contents are coming dynamically from database

For this you can use text-overflow: ellipsis; property. Write like this

#content_right_head span{
    display:inline-block;
    width:180px;
    white-space: nowrap;
    overflow:hidden !important;
    text-overflow: ellipsis;
}

Check this http://jsfiddle.net/Y5vpb/

Optimize JavaScript CSS download

13 votes

I have a number of pages for my website all use jQuery and JSON and the same CSS, except for a few pages. The first page is user login. As the user will take time to type in his username and password, I want to download all the required JavaScript and CSS files for the entire user session during login. How can this be done? The header is the same for all pages. How do I optimize it?

My idea would be load in js and css files dynamically after document.load. This would not affect the load time of the login page, whilst also caching your js and css files once the user has logged in.

You could also easily change this to document.ready if it loads faster for you.

What about something like this?

$(document).load(function() {
    function preloadFile(filename, filetype){

        //For javascript files
        if (filetype=="js"){
            var fileref=document.createElement('script');
            fileref.setAttribute("type","text/javascript");
            fileref.setAttribute("src", filename);
        }

        //For CSS files
        else if (filetype=="css") {
            var fileref=document.createElement("link");
            fileref.setAttribute("rel", "stylesheet");
            fileref.setAttribute("type", "text/css");
            fileref.setAttribute("href", filename);
        }

        document.getElementsByTagName("head")[0].appendChild(fileref)
    }

    //Examples of how to use below
    preloadFile("myscript.js", "js"); 
    preloadFile("javascript.php", "js");
    preloadFile("mystyle.css", "css");
});

References

http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml

Math assistance with my Grid: nth-child(an+b)

12 votes

I am trying to make a grid that is not dependent on a preset number of columns. I created a small sample to show the situation:

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <title>Grid in HTML5 and CSS3</title>
<style>

* {margin:0;padding:0;}
.row {display:block;position:relative;clear:both;}
.row>* {display:block;position:relative;clear:both;float:left;clear:none;width:100%;}
.row>*:empty {width:0px;}

/* one column in the row */
.row>:nth-last-child(1):nth-child(1) {width:100%;} 

/* two columns in the row */
.row>:nth-last-child(2):nth-child(1) {width:50%;} 
.row>:nth-last-child(1):nth-child(2) {width:50%;} 

/* three columns in the row */
.row>:nth-last-child(3):nth-child(1) {width:33.33%;} 
.row>:nth-last-child(2):nth-child(2) {width:33.33%;}
.row>:nth-last-child(1):nth-child(3) {width:33.34%;} 
.row>:empty:nth-last-child(3):nth-child(1)+:not(:empty) {width:66.66%;} 
.row>:empty:nth-last-child(2):nth-child(2)+:not(:empty) {width:66.67%;}

article {margin:.5em;border:1px solid green;border-radius:.3em;padding:.5em; }
</style>

</head>
<body>

<section class="row">
<div>
<article>
<p>This row has only one child.</p>
</article>
</div>
</section>

<section class="row">
<div>
<article>
<p>This row has two children</p>
</article>
</div>
<div>
<article>
<p>This is the second child</p>
</article>
</div>
</section>

<section class="row">
<div>
<article>
<p>
This row has three children
</p>
</article>
</div>
<div>
<article>
<p>So this is col 2 of 3</p>
</article>
</div>
<div>
<article>
<p>And this is col 3 of 3.</p>
</article>
</div>
</section>

<section class="row">
<div></div>
<div>
<article>
<p>The first child of this row is empty so spanned with the second</p>
</article>
</div>
<div>
<article>
<p>This is the second column</p>
</article>
</div>
</section>

<section class="row">
<div>
<article>
<p>This is the first column</p>
</article>
</div>
<div></div>
<div>
<article>
<p>The second and third column are spanned</p>
</article>
</div>
</section>

</body>
</html>

I put a larger sample - describing the problems in more detail - on jsfiddle at

http://jsfiddle.net/jordenvanforeest/MDv32/

My problem now is that if you want this grid to accomodate for more than 3 columns, the CSS-size gets big exponentially. So I am looking for an other solution. I tried to do something like

.row>:nth-last-child(an+b):nth-child(cn+d) {} 

but my calculus skills are a bit rusty and I cannot get it to work properly. Help would be much appreciated.

update

thirtydot provided an answer that made the CSS much smaller. This fiddle is the improved version suggested by him.

Any other suggestions are still welcome. My 12 collumn Grid still needs 30K for the spanning.

You can do something similar with display: table combined with table-layout: fixed.

Browser support: http://caniuse.com/css-table (but the limiting factor here is :not() and :empty)

See: http://jsfiddle.net/thirtydot/MDv32/3/

As you can see, it looks virtually identical. With some ingenuity, you should be able to replicate most of the functionality in your demo with the technique used in mine. I commented out the HTML in my demo where I stopped.

CSS:

.row {
    display: table;
    table-layout: fixed;
    width: 100%;
}
.row > * {
    display: table-cell;
}
.row > :empty {
    display: none;
}
/* for example: */
.row > :empty + :not(:empty) + :last-child:not(:empty) {
    width: 33.33%;
}

HTML Select padded with &nbsp; having issue in search

12 votes

I have an HTML select which has items like the below.

<SELECT id="mylist" size=5 >
   <OPTION Value="100">100</OPTION>
   <OPTION Value="200">200</OPTION>
   <OPTION Value="210">210</OPTION>
   <OPTION Value="211">211</OPTION>
</SELECT>

enter image description here

Now if I click inside the SELECT and type 21 then it will select the item 210 which is the first item starts with 21. All good.

Later I wanted to add a padding to the left of the item as requested by the client. But soon I realized that padding in SELECT will not work in IE (at least on IE6 and IE7 which I tested)

So I added &nbsp;&nbsp;

<SELECT id="mylist" size=5 >
   <OPTION Value="100">&nbsp;&nbsp;100</OPTION>
   <OPTION Value="200">&nbsp;&nbsp;200</OPTION>
   <OPTION Value="210">&nbsp;&nbsp;210</OPTION>
   <OPTION Value="211">&nbsp;&nbsp;211</OPTION>
</SELECT>

enter image description here

Now I can mimic padding.

But I lost the search option. It will not select 210 when I type 21 in IE. It works well in chrome. Please share your thoughts.

Find the sample here

How about wrapping it in a div:

HTML:

<div class="listwrapper">
    <SELECT id="mylist" size=5 >
        <OPTION Value="100">100</OPTION>
        <OPTION Value="200">200</OPTION>
        <OPTION Value="210">210</OPTION>
        <OPTION Value="211">211</OPTION>
    </SELECT>
</div>​

CSS:

.listwrapper
{
    padding: 0px 0px 0px 15px;
    border: solid 1px silver;
    width: 50px;
}
.listwrapper select,
.listwrapper select:active
{
    border: none 0px white;
    width: 50px;
}
​

My Fiddle

Visual Studio 2012 Conditional Bundling

12 votes

I just began working with VS 2012 RC. I've created a test site with a master page and a single web form. Currently, I'm using this code to bundle the entire Styles folder on the site:

Global.asax

BundleTable.Bundles.EnableDefaultBundles();

Site.master

<link rel="stylesheet" type="text/css" href="Styles/css" />

Question: The test site has a site-level CSS file that controls the overall look and feel of the site. In addition to the site-level CSS, each page could have their own CSS definitions. Is it possible to include only the site.css file in the master page, and then conditionally add .css files to the bundle as each page requires?

I tried this in the code behind of Default.aspx but it didn't work:

BundleTable.Bundles.Add(new Bundle("~/Styles/Default.css"));

My suggestion:

Goto Global.asax. Ensure the method Application_Start contains following line:

protected void Application_Start()
{
    ...
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

Find or create class BundleConfig as follows, preferrably in folder App_Start:

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        ...

        bundles.Add(new StyleBundle("~page1").Include(
             "~/Styles/site.css",
             "~/Styles/page1.css"));

        bundles.Add(new StyleBundle("~page2").Include(
             "~/Styles/site.css",
             "~/Styles/page2.css"));

        ...

        bundles.Add(new StyleBundle("~pageN").Include(
             "~/Styles/site.css",
             "~/Styles/pageN.css"));

    }
}

Now use corresponding bundle in every appropriate page:

<link rel="stylesheet" type="text/css" href="Styles/page1" />

Or better from code:

@Styles.Render("~/Styles/page1")

(this is cshtml, but aspx syntax is for sure very similar).

Note that you must have a separate bundle per page. You should not modify one and the same bundle on the fly. Bundles have virtual Urls. In your example it is just css. These are cached by browsers, so regardless weather you have changed the content of bundle on the fly a browser might think this is the same and do not re-fetch it.


If you do not want to take care about adding each and every page manually to the method above. You could automate it. Following code could give you an idea how:

public class MyStyleHelper
{
    public static string RenderPageSpecificStyle(string pagePath)
    {
        var pageName = GetPageName(pagePath);
        string bundleName = EnsureBundle(pageName);
        return bundleName;
    }

    public static string GetPageName(string pagePath)
    {
        string pageFileName = pagePath.Substring(pagePath.LastIndexOf('/'));
        string pageNameWithoutExtension = Path.GetFileNameWithoutExtension(pageFileName);
        return pageNameWithoutExtension;
    }

    public static string EnsureBundle(string pageName)
    {
        var bundleName = "~/styles/" + pageName;
        var bundle = BundleTable.Bundles.GetBundleFor(bundleName);
        if (bundle == null)
        {
            bundle = new StyleBundle(bundleName).Include(
                "~/styles/site.css",
                "~/styles/" + pageName + ".css");
            BundleTable.Bundles.Add(bundle);
        }
        return bundleName;
    }
}

Usage:

<link rel="stylesheet" type="text/css" href="<%: MyStyleHelper.RenderPageSpecificStyle(Page.AppRelativeVirtualPath) %>" />

What does this operator (::) in CSS mean?

11 votes

I have seen CSS like Custom Scrollbars in WebKit

body::-webkit-scrollbar {
    width: 10px;
    height: 13px;
    background-color: white;
    color: #EBEBEB;
    border:none;
}

This specifies CSS for WebKit browsers. But what does this operator (::) mean in CSS?

Where can I find other such operators in CSS?

It indicates that what follows is a "pseudo-element". From the CSS Selectors level 3 spec:

A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.

And a pseudo-element creates an "abstraction about the document tree":

Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element's content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).

For example, the ::webkit-scrollbar pseudo-element provides a mechanism to refer to the webkit scrollbar, which would be otherwise inaccessible. Another example: the ::first-letter pseudo-element provides a way to refer to the first letter of an element (if it is not preceded by any other content).

How to use "two-toned" font variants in CSS?

11 votes

Certain fonts have a variant for outline and filled, and if you use these on overlapping text it draws an outlined or shaded stroke over the filled text. This is different than just an outline that strokes the text like -webkit-text-stroke-color would give you, since sometimes the filled font contains shading or other details.

Here's some examples of fonts designed to be used this way.

http://www.myfonts.com/fonts/matchandkerosene/duotone/

http://www.myfonts.com/fonts/scrowleyfonts/stomp/

I was sort of able to get this to work using CSS like this:

http://jsfiddle.net/6SakC/2/

This creates two H1 spans and uses the top-margin to move the outline one atop the filled one.

However, this doesn't seem ideal to me. Two problems:

  • I don't want to duplicate the text in the html.
  • I have to guesstimate the top-margin by trial and error.
  • If the text wraps, this doesn't work anymore.

Is there a better way to do this? I can live with having to duplicate the text, but I'd really like a more automatic way to do the positioning.

Thanks!

You can place the outline text inside the h1 and use absolute positioning instead of estimating the margin, as in this jsFiddle: http://jsfiddle.net/6SakC/4/

That also solves the problem with the text wrapping.

To avoid duplicating the text in the markup, you can use JavaScript to create the duplicate text, as in this jsFiddle: http://jsfiddle.net/6SakC/5/ (This might not be the best idea, though, since the text might get a moment to display without the outline, and JS is occasionally disabled in the browser settings.)

Why does HTML5 recommend putting the code element inside pre?

11 votes

The HTML5 documentation recommends putting the code element inside the pre element, but I don't understand how this is better or more semantic than just using the code element and CSS. In their own example:

<pre><code class="language-pascal">var i: Integer;
begin
   i := 1;
end.</code></pre>

Could also be written (Making some assumptions about the browser's defaults for pre):

<style>
code {
    display: block;
    white-space: pre;
}
</style>
…
<code class="language-pascal">var i: Integer;
begin
   i := 1;
end.</code>

Even if the pre is there to distinguish a code block from an inline string of code, I don't see it being a more semantic choice than specifying the block-ness of the code in a class.

Is there a specific reason the pre is recommended over a CSS solution?

<code> represents only a "fragment of computer code". It was originally thought for simple code snippets like i++ or <code>.

<pre> "represents a block of preformatted text, in which structure is represented by typographic conventions rather than by elements". It's original purpose was nothing more than exactly this: provide a text in the same way it was given by the author.

You don't need to use each with each other. <pre> has its own roles, like <code> has its own. However, <pre> is a way to signalize that the white-space in the given fragment is important, a role that <code> is missing.

However, back to your question: note the exact wording:

The following example shows how a block of code could be marked up using the pre and code elements.

<pre><code class="language-pascal">var i: Integer;
begin
   i := 1;
end.</code></pre>

A class is used in that example to indicate the language used.

It says could, not should. You're free to do this how you want. It's not recommended by the W3C in any way, however, I recommend you to use <pre><code>....

Further explanation

Whenever white-space is part of your code and the structure of your code, you should state that this structure should be kept. As the structure in code is given by typographic conventions (tabs, linefeeds, spaces) I personally recommend you to use <pre><code>, even if it's arguably more code and another node in the DOM. But whenever missing white-space will render your code imperfect it's necessary.

Apart from that you can easily differ between inline code and code-blocks without checking element.className, and some JS syntax highlighter work pretty well with <pre><code>... and strip the <code> automatically.

jQuery's .css() implementation

9 votes

I was looking through the jQuery code and found this line:

elem.runtimeStyle.left = elem.currentStyle.left;

at

https://github.com/jquery/jquery/blob/449e099b97d823ed0252d8821880bc0e471701ea/src/css.js#L169

I am not sure why this is done. Isn't this useless?

Setting the runtimeStyle to the currentStyle would override nothing. Except make the runtimeStyle readable the next time you read it - which doesn't seem needed now.

I understand the overall concept here and why that code block exists (to convert numeric non-pixel values to the appropriate pixel value, by setting the left to the non-pixel value and reading its pixel value and then reverting the left back to the original value).

Edit See my answer below for why I think this is done (with jsFiddle illustration!).

I have been thinking about this. Here is why I believe it is done:

Setting the runtimeStyle to the currentStyle ensures that this is style that is applied on the element (the runtime style wins over the inline style). So when you set elem.style.left in the next line, there would be no change in the UI. However, the new pixel value can still be calculated using elem.style.pixelLeft - because this just converts the non-pixel value on the CSS to a pixel value. pixelLeft is not a measurement of the actual position, it is just a conversion to the pixel value.

See this: http://jsfiddle.net/RaSzc/

So this is done to figure out the pixel value without having anything change in the UI

Can CSS be used to mask background images?

9 votes

This is what I have presently:

Image of current code

Here's my code so far:

<style type="text/css">
    .main
    {
        background:url(bg.jpg);
        height:250px;
        }
    .ban
    {
        background-color:#333;
        height:150px;
    }
    .mask
    {
        width:75px;
        height:75px;
        float:left; 
        border:#fff solid 1px;

        margin:20px;
    }
</style>

<div class="main">
    <div class="ban">
         <div class="mask"></div> 
         <div class="mask"></div>
         <div class="mask"></div>
         <div class="mask"></div>
         <div class="mask"></div>    
    </div>
</div>

Here's what I am aiming for:

enter image description here

I am looking to create a mask using CSS - what do I need for this?

If you don't find the solution in the comments above, then I've got one for you.

Instead of trying to create the svg or png image to position against, you could use borders (if you're using a solid color that's easy to work with) to replicate this.

You can see a working jsFiddle here

Firefox ignores outline and focus styles on select elements when using Tab

8 votes

Context

Firefox 14 (and 13); specific CSS styles being ignored under certain conditions

The Problem

Using the following CSS:

*
{
    outline:none;
    -moz-outline:none;
    -moz-user-focus:ignore;    
}

JSFiddle

Firefox 14 (and 13) ignore these styles when using Tab to switch between select elements. Clicking these elements after using Tab still displays the outline.

Notes

  • Specifically styling select instead of * has no effect.
  • This only occurs with select elements.

The Question

Is this a bug or intended behavior?

Are there any other CSS styles that need to be used to prevent the outline from appearing indefinitely?

This is a known bug which has sparked several Stackoverflow discussions. From what I have read, Mozilla have deemed that CSS is the wrong place to handle this element behaviour, and have opted instead to handle it by other means. At this time the only solution is to either use tabindex="-1" or to set the element to display as something else, and restyle the look and feel of a droplist — but be warned, this opens a can of worms in itself.

If you do opt to do this, I have had success in the past with the following kludge:

select {
    appearance: normal;
        -webkit-appearance: none;
        -moz-appearance: radio-container; /* renders text within select, without arrow chorme */
}

Appearance tells the browser to display the element as something else, but this is inconsistent from vendor to vendor. appearance: normal; is the spec, whilst webkit replaces normal with none. -moz-appearance: radio-container; has been the only way I have found to display the text within the chosen select option, whilst removing the arrow chrome for a fully customised droplist. However, try experimenting with the available options until you find something that works and doesn't add the focus ring you wish to customise. Internet Explorer will require further kludge to bend the select to your needs. Entirely possible, but out of scope for this question and answer.

What happens to the remaining 1px when an odd-width div is split 50%/50%?

8 votes

Let's say I wanted to make a background for div#wrapper so that half is blue and half is red using two divs with width:50%, like so:

HTML

<div id="wrapper">
    <div id="leftSide"></div>
    <div id="rightSide"></div>
</div>

CSS

body, html, #wrapper {
    width: 100%;
    height: 100%;
}

#wrapper {
    background: white;
}

#leftSide, #rightSide {
    width: 50%;
    height: 100%;
}

#leftSide {
    float: left;
    background: blue;
}

#rightSide {
    float: right;
    background: red;
}

Here is a fiddle for the above example.

This would, theoretically solve the task. However, if the wrapper had a width containing an odd number of pixels, what would happen to the remaining 1px?

For example, if the wrapper's width were changed to 101px, then #leftSide would be 50px wide, and #rightSide would be 50px wide, presumably leaving a 1px vertical white line running down the middle.

How do browsers normally render this? Will one of the sides absorb the remaining 1px? And, if so, what would be the best pure CSS approach to working around this? My first inclination would be to set the background of the wrapper to either red or blue, but are there other approaches?

See http://jsfiddle.net/dq323/.

In IE and Firefox, the right side takes up the extra pixel. In Chrome, there's actually a gap between the two.

Setting the background of the container seems like the best way to address this.

Vertically align text in an inline element

8 votes

Problem

So I'm creating a simple navigation menu which contains a div of a tags. Currently it looks like this:

enter image description here

The follow are my HTML and CSS:

HTML

<div id="tabcontent-container">
    <div class="tabcontent-menu">
        <a href="#">WLAN Jumpstart</a>
        <a href="#">Mobility</a>
        <a href="#">Guest Access Jumpstart</a>
    </div>
</div>

The CSS

#tabcontent-container { padding: 15px 0px; position: relative; text-align: center; border-radius: 25px; -webkit-border-radius: 25px; }
.tabcontent-menu {}
.tabcontent-menu a { text-decoration: none; color: white; font-size: 30px; border-right: 1px solid white; line-height: 33px; padding: 0 22px; display: inline-block; width: 200px; height: 70px; vertical-align: top; }
.tabcontent-menu a:last-child { border:none; }
.tabcontent-menu a:hover { color:#000; }

Working example on Jsfiddle.net

The Question

I'm wondering if there is an easier way to align the middle "Mobility" a tag to the middle. The other two links look fine because they are double line. I purposely made them double line for a reason, and now just need the middle one to middle align some how.

Any suggestions?

You can use vertical-align: middle to adjust the position vertically. Since that only works on table cells, set display: table-cell for the .tabcontent-menu a

http://jsfiddle.net/H9VHs/8/

Convert RGBA color to HTML color code

7 votes

I have a color picker in my application that users can use to pick colors of certain objects that the application outputs. The color picker is outputting the color chosen in RGBA format. However, I need the HTML color code. I need to be able to convert RGBA, without knowing the color ahead of time, to HTML and use it as a string later. How would I go about doing this?

RGBA is natively supported by CSS3:

div {
   background: rgba(200, 54, 54, 0.5); 
}

Firefox, Safari, Chrome, IE9 and Opera browsers all support RGBA. Older IE's do not support it.

Fortunatly, you can specify RGBA colours for browsers that support it and an alternative for browsers that do not. Check this link for a great howto.

This are the two options: - from the link -

1. FALLING BACK TO SOLID COLOUR: Allow the browser to fall back to using a solid colour when opacity isn’t available. The

h1 {
     color: rgb(127, 127, 127); 
     color: rgba(0, 0, 0, 0.5); //for modern browsers only
}

2. FALLING BACK TO A PNG: In cases where you’re using transparency on a background-color (although not on borders or text) it’s possible to fall back to using a PNG with alpha channel to get the same effect. This is less flexible than using CSS as you’ll need to create a new PNG for each level of transparency required, but it can be a useful solution.

h1 {
     background: transparent url(imageName.png);
     background: rgba(0, 0, 0, 0.5) none; //for modern browsers only
}

What I am trying to say is that you do not need the HTML color code, you just need to add the css property rgba - with javascript or jquery - after you pick up the color and I think you are done.

Overflow : hidden in FF

7 votes

I'm having a problem with overflow : hidden content, but only in FF. enter image description here

I have two divs (each side of the vertical arrow, see above) each have overflow:hidden applied masking their respective child div. The child elements are being rotated onscroll event via jQuery. For whatever reason the background image in each of the children elements are not being masked as they should by their parent div.

To see this inconsistency; http://www.pearman.com.au/

Whats strange is the child content appears when inspecting any of the parents CSS properties in Firebug.

edit : find the CSS / HTML / JQuery

This code is run each time the onscroll is updated (alot);

    scrollAnimations.push({ 'start': 0, 'end': 450,
                'callback': function(scrollTop,scrollDirection){ 
                    ran_one.css({
                        '-ms-transform': 'rotate('+ -(scrollTop)*0.4 +'deg)',
                        '-webkit-transform': 'rotate('+ -(scrollTop)*0.4 +'deg)',
                        '-moz-transform': 'rotate('+ -(scrollTop)*0.4 +'deg)',
                        '-o-transform': 'rotate('+ -(scrollTop)*0.4 +'deg)',
                        'transform': 'rotate('+ -(scrollTop)*0.4 +'deg)' })
                    }
                });
            scrollAnimations.push({ 'start': 0, 'end': 900,
                'callback': function(scrollTop,scrollDirection){
                    ran_two.css({
                        '-ms-transform': 'rotate('+ -(scrollTop)*0.4 +'deg)',
                        '-webkit-transform': 'rotate('+ -(scrollTop)*0.4 +'deg)',
                        '-moz-transform': 'rotate('+ -(scrollTop)*0.4 +'deg)',
                        '-o-transform': 'rotate('+ -(scrollTop)*0.4 +'deg)',
                        'transform': 'rotate('+ -(scrollTop)*0.4 +'deg)' })
                    }
                });

CSS ;

#rainbow-mask-right{
        width:421px;
        height:421px;
        display:block;
        position:absolute;
        bottom:0;
        left: 50%;
        overflow:hidden;
        }
    #rainbow-mask-left{
        width:421px;
        height:421px;
        display:block;
        position:absolute;
        bottom:0;
        left: 50%;
        overflow:hidden;
        margin-left: -420px;
        visibility:visible;
        }
    #ran-one{
        background:url(images/home/rainbow/ran-dash.gif) no-repeat;
        width:421px;
        height:421px;
        display:block;
        top: 421px;
        position: absolute;

        transform: rotate(50deg);
        -ms-transform: rotate(50deg); /* IE 9 */
        -webkit-transform: rotate(50deg); /* Safari and Chrome */
        -moz-transform: rotate(50deg); /* Firefox */
        -o-transform: rotate(50deg); /* Opera */
        }
    #ran-two{
        background:url(images/home/rainbow/ran-colour.gif) no-repeat transparent;
        width:421px;
        height:421px;
        display:block;
        top: 421px;
        position: absolute;
        left: 421px;
        }
   .set-origin {
    transform-origin:0 0;
    -ms-transform-origin:0 0; /* IE 9 */
    -webkit-transform-origin:0 0; /* Safari and Chrome */
    -moz-transform-origin:0 0; /* Firefox */
    -o-transform-origin:0 0; /* Opera */
    }   

and HTML

<div id='rainbow-mask-right'><div id='ran-one' class="set-origin"></div></div>
<div id='rainbow-mask-left'> <div id='ran-two' class="set-origin"></div></div>

Well, after a little while of debugging, I am pretty sure I found the issue.

Looks like FireFox does not like to display empty containers. I am on 13.1, but after editing your HTML via FireBug, here is the end result:

space enter

Just add a simple

&nbsp;

to the rainbows and it should be a win.

Great looking site! Enjoy,

<div id="rainbow-mask-right"><div id="ran-one" class="set-origin">&nbsp;</div></div>
<div id="rainbow-mask-left"><div id="ran-two" class="set-origin">&nbsp;</div></div>

What CSS3 selectors does jQuery really support, e.g. :nth-last-child?

7 votes

According to http://api.jquery.com/category/selectors/ we can use a large amount of CSS selectors in jQuery, but e.g. :nth-last-child is not mentioned there. However, when I test the following (with jQuery 1.7.1 as from Google), it actually works on Firefox, Chrome, and IE 9, but not on IE 9 in IE 8 emulation mode:

$('li:nth-last-child(2)').css('color', 'red');

So what’s happening? It looks as if jQuery generated CSS code, like li:nth-last-child(2) { color: red } and somehow injected it, which then works OK on browsers that support the selector used. But that would be odd.

Most importantly, is there some trick to make jQuery support such selectors on all browsers?

jQuery supports nearly all CSS3 selectors1, with the following exceptions:

  • :root

  • :lang()

  • :target

  • :nth-last-child()

  • :nth-of-type(), :nth-last-of-type(), :first-of-type, :last-of-type and :only-of-type

  • Namespace prefixes and pseudo-elements

A few other selectors (like the ~ combinator, :empty, and some CSS2 attribute selectors) were going to be dropped as well during jQuery's early development, all because John Resig didn't think anybody would use them. Luckily, they made it into the final release after some more tests were made available.

The reason why your selector appears to work in Firefox, Chrome and IE9 is because jQuery first passes the selector string to the native document.querySelectorAll() implementation before falling back to Sizzle. Since it is a valid CSS selector, document.querySelectorAll() will successfully return a node list for jQuery to use.

In the event that document.querySelectorAll() fails, jQuery automatically falls back to Sizzle. There are a number of scenarios that can cause it to fail:

  • The selector is invalid, not supported, or otherwise cannot be used (see the Selectors API spec for details).

  • document.querySelectorAll() is not supported.

In your case, although IE9 (and IE8) implement document.querySelectorAll(), IE8 doesn't support :nth-last-child(). Since jQuery doesn't implement :nth-last-child() either, there's no fallback behavior to use, so your selector fails completely on IE8.

That said, you can always use jQuery's custom selector extensions to implement the missing pseudo-classes yourself.2 See this question for an :nth-of-type() implementation.

Here's my take at :nth-last-child(), based on the existing :nth-child() implementation:

$.expr[':']['nth-last-child'] = function(elem, index, match) {
    var parent = elem.parentNode, 
        children = parent.childNodes;

    // Filter out non-element nodes
    children = $.grep(children, function(e, i) {
        return e.nodeType === 1;
    });

    // Pretend to be :nth-child() in order to parse the formula
    fMatch = $.expr.preFilter.CHILD($.expr.match.CHILD.exec(':nth-child(' + match[3] + ')'));

    // Use the existing :nth-child() implementation... backwards
    var lastIndex = children.length - 1;
    return $.expr.filter.CHILD(children[lastIndex - index], fMatch);
};

jsFiddle preview


1 It does support :contains(), last defined in this old CR revision of the spec before being dropped later, as well as extending :not() from the standard. The differences between jQuery's implementation and the current standard are covered in this question.

2 But, considering that the CSS3 selectors spec has now been widely implemented by modern browsers as well as the fact that Sizzle has been rewritten for jQuery 1.8 (and jQuery 2.0 will finally be dropping IE6/7/8 support), I don't think the developers will be willing to patch any implementations of the above CSS3 selectors into future versions of Sizzle.

Ajax/Js Image uploader: Creating duplicate preview images

5 votes

I am working with an Ajax imageuploader from this SITE. I currently achieve in creating duplicate preview images: one appears under the input field and the other will appear somewhere else in the page under something like "this what you chose". The problem is that if the user selects a file, the function will display the Image but if the user changes its mind and chooses a new image then the yourCustomPreview will show the new image chosen and the old.

Is there a way of just having the most recent preview picture shown without the old preview picture appearing? If unclear please check the source files HERE

uploaderPreviewer.js- Original function

<script>
function displayImage($previewDiv, imageUrl) {

    var imageFilename = imageUrl.substr(imageUrl.lastIndexOf('/') + 1);

    $previewDiv
        .removeClass('loading')
        .addClass('imageLoaded')
        .find('img')
        .attr('src', imageUrl)
        .show();
    $previewDiv
        .parents('table:first')
        .find('input:hidden.currentUploadedFilename')
        .val(imageFilename)
        .addClass('imageLoaded');
    $previewDiv
        .parents('table:first')
        .find('button.removeImage')
        .show();
}
</script>

uploaderPreviewer.js- Modified function

<script>
    function displayImage($previewDiv, imageUrl) {
    //New
    var yourCustomPreview = $('#custompreview');

    var imageFilename = imageUrl.substr(imageUrl.lastIndexOf('/') + 1);

    $previewDiv
        .removeClass('loading')
        .addClass('imageLoaded')
        .find('img')
        .attr('src', imageUrl)
        .show();
    $previewDiv
        .parents('table:first')
        .find('input:hidden.currentUploadedFilename')
        .val(imageFilename)
        .addClass('imageLoaded');
    $previewDiv
        .parents('table:first')
        .find('button.removeImage')
        .show();

        //New
        yourCustomPreview.append('<img src="' + imageUrl + '"/>');

    }
</script>

ok, try this:

TO EDIT:

replace the displayImage function with this:

function displayImage($previewDiv, imageUrl) {
//New
var yourCustomPreview = $('#custompreview');
var imageId = $($previewDiv.context).attr('id');
var imageFilename = imageUrl.substr(imageUrl.lastIndexOf('/') + 1);

$previewDiv
    .removeClass('loading')
    .addClass('imageLoaded')
    .find('img')
    .attr('src', imageUrl)
    .show();
$previewDiv
    .parents('table:first')
    .find('input:hidden.currentUploadedFilename')
    .val(imageFilename)
    .addClass('imageLoaded');
$previewDiv
    .parents('table:first')
    .find('button.removeImage')
    .show();

    //New
    if(!yourCustomPreview.find('#' + imageId +'_prev').length > 0)
    {
      yourCustomPreview.append('<img id="' + imageId + '_prev" src="' + imageUrl + '"/>');
    }
    else
    {
      $('#' + imageId +'_prev').attr('src', imageUrl);
    }
}

TO DELETE

replace removeImage function with this:

function removeImage($removeImageButton, errorDisplayed) {

    var thumbIdToDelete = $removeImageButton.parents('table').find('[name=imageToUpload]').attr('id');
    var $parent = $removeImageButton.parents('table:first').parent();

    $.post($.uploaderPreviewer.removeImageAjaxUrl, {
        currentUploadedFilename: $parent.find('input:hidden.currentUploadedFilename').val()
    });

    $parent.find('input:hidden.currentUploadedFilename').removeClass('imageLoaded');
    $parent.find('div.previewImage')
        .removeClass('loading imageLoaded')
        .find('img')
        .hide();

    $parent.removeErrorMessage();

    if ( ! errorDisplayed) {
        $parent.find('input:file').val('');
        $removeImageButton.hide();
    }

    $('#' + thumbIdToDelete +'_prev').remove();
};

Ajax Loader and chained select boxes

4 votes

I am working with dynamic select boxes and I am using JS/Jquery to update the values of each select box. Since I am pulling the values from MySQL table, sometimes it takes a little longer to load the select boxes with its values. One Solution i search is the use of an ajax loader.

How can I place an ajax loader (just before the jQuery.getJSON in the updateSelectBox.js) so that nothing can be clicked while loading on the first tab and remove it after the success handling (in the same file)? or any better solutions? Here is an EXAMPLE

updateSelectBox.js

var formObject = {
    run : function(obj) {

            obj.nextAll('.update').attr({'disabled': true, 'hidden':true}).html('<option value="">----</option>');
            var id = obj.attr('id');
            var v = obj.val();
            jQuery.getJSON('mod/postfile.php', { id : id, value : v }, function(data) {
            $('.update').removeClass('last');
                if (!data.error) {
                    obj.next('.update').html(data.list).removeAttr('disabled hidden');
                } else {
                 obj.addClass('last').nextAll('.update').attr({'disabled': true, 'hidden':true}).html('<option value="">----</option>');
                }
            });
        }   
}; 

$(function(){

    $('.update').live('change', function() {
        var str = "";
          $("select option:selected").each(function () {
                str += $(this).text() + " ";
              });
          $("#postSelected").text(str);

        formObject.run($(this));
    });

});

HTML

<select name="gender" id="gender" class="update" size="7"> 
  <option value="">Select one</option> 
    <?php if (!empty($list)) { ?> 
    <?php foreach($list as $row) { ?> 
       <option value="<?php echo $row['id']; ?>"> 
        <?php echo $row['category_name']; ?> 
       </option> 
    <?php } ?> 
    <?php } ?> 
</select> 

<select name="category" id="category" class="update" disabled="disabled" hidden="hidden" size="7"> 
  <option value="">----</option> 
</select> 

<select name="colour" id="colour" class="update" disabled="disabled" hidden="hidden" size="7"> 
  <option value="">----</option> 
</select> 

First you should create an ajax loader image (e.g. here) and save it on your server. Just before the getJSON the ajaxloader overlay should be shown (customize the image source!):

$('#tabs').append('<div class="overlay"><div class="overlay_image"><img src="ajaxloader.gif" alt="ajaxloader"></div></div>');
$('#tabs .overlay').css("line-height", $('#tabs').height()+'px');

And remove it at the end of the success handler:

$('#tabs .overlay').remove();

Your formObject should be now:

var formObject = {
    run : function(obj) {
        obj.nextAll('.update').attr({'disabled': true, 'hidden':true}).html('<option value="">----</option>');
        var id = obj.attr('id');
        var v = obj.val();
        $('#tabs').append('<div class="overlay"><div class="overlay_image"><img src="ajaxloader.gif" alt="ajaxloader"></div></div>');
        $('#tabs .overlay').css("line-height", $('#tabs').height()+'px');
        jQuery.getJSON('mod/postfile.php', { id : id, value : v }, function(data) {
        $('.update').removeClass('last');
            if (!data.error) {
                obj.next('.update').html(data.list).removeAttr('disabled hidden');
            } else {
             obj.addClass('last').nextAll('.update').attr({'disabled': true, 'hidden':true}).html('<option value="">----</option>');
            }
            $('#tabs .overlay').remove();
        });
    }   
}; 

Following additional stylesheets are necessary to see the overlay:

#tabs {
    position: relative;
}

.overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2000;
    background-color: #EEEEEE;
    opacity: 0.5;
}

.overlay > div {
    position: relative;
    text-align: center;
}

.overlay > img {
    vertical-align: middle;
}

Also see this example.