Tag Archives: CSS

Customising Cross-Browser Range Inputs with CSS and JavaScript

Customising Cross-Browser Range Inputs with CSS and JavaScript
// CSS-Tricks

The following is a guest post by Steven Estrella. Steven shared with me a technique for creating customized range inputs by writing a little JavaScript atop some of the techniques explored here by Daniel Stern and others. I invited Steven to explain his approach.

Last year, Daniel Stern wrote a very useful article to demonstrate cross-browser styling of the HTML5 range input using nothing more than CSS and HTML. He even created a handy tool called range.css for generating the CSS. Sometimes, however, our designs may need to go beyond what is possible with CSS alone.

In the example below I wanted to experiment with what’s currently possible when manipulating a range input with JavaScript:

See the Pen 17140bb5973a773b82e2d5fd1d5bcd00 by CSS-Tricks (@css-tricks) on CodePen.

Notice how the track fills with a gradient as you drag the thumb? Also, the thumb uses an image as its background, rotates whilst you drag, and displays the value as text. And of course there is the not-so-small-matter of allowing for both horizontal or vertical slider orientations and preserving inputs from the keyboard too. We’ll go into further detail on that soon. Ultimately, this tutorial will walk you through the code and concepts to add this type of control over the appearance and functionality of HTML5 range inputs.

Marking things up

To get started, we’ll make the standard range input invisible to the user, place it on top of our own styled divs, and then wire them all together with a few lines of JavaScript. The user will then drag the invisible range input thumb, which will fire event listeners that call a function and transmit the range input value. Consequently, this will trigger changes to the appearance of the styled divs.

OK, so let’s start with the markup first:

<table class="slider2column"> <tr> <td>

<input class=”slider” id=”slider1″ type=”range” min=”0″ max=”100″ value=”0″ /> </div> </td> </tr> </table>

  • The outer .slidershell div exists to provide a positioning context for the divs it contains.
  • .sliderfill should create a gradient that changes the appearance as the user drags the thumb.
  • .slidertrack will display a styled border on top of the .sliderfill.
  • .sliderthumb makes the 90’s-style beveled square image that looks like marble.
  • .slidervalue styles the current value of the slider input.

Finally, the <input type="range"> is added last so that it rests on top of those other elements.

In our example we’ll need to have three of these td elements, with each input having an id attribute with a different number at the end. This will allow us to present multiple sliders in both orientations on the same page. At the moment our input will look like this:

See the Pen a823e1cf9e505f812f01fe9d6016e441 by CSS-Tricks (@css-tricks) on CodePen.

Next, we can add an inline event listener to call a JavaScript function when the slider has an input or registers a change in the value. The function should take three parameters: the value of the slider, the number of the slider, and a boolean value of true if the slider should be vertical. We’ll call this function showValue():

<input class="slider" id="slider1" type="range" min="0" max="100" value="0" oninput="showValue(value, 1, false);" onchange="showValue(value, 1, false);" />

Now we have to strip away the default appearance of the range input with some CSS that effectively acts as a reset. We can do this by first adapting the ideas presented by Daniel Stern, but then focus our efforts on making all the default elements of the range input appear transparent.

/* First we have to make transparent all the default elements of the range input. We use color:transparent to eliminate the default tick marks in IE. */ input[type=range]::-ms-track { width: 100%; height: 100%; -webkit-appearance: none; margin: 0px; padding: 0px; border: 0 none; background: transparent; color: transparent; overflow: visible; } input[type=range]::-moz-range-track { width: 100%; height: 100%; -moz-appearance: none; margin: 0px; padding: 0px; border: 0 none; background: transparent; color: transparent; overflow: visible; } input[type=range] { width: 100%; height: 100%; -webkit-appearance: none; margin: 0px; padding: 0px; border: 0 none; background: transparent; color: transparent; overflow: visible; } input[type=range]:focus::-webkit-slider-runnable-track { background: transparent; border: transparent; } input[type=range]:focus { outline: none; } /* Make the thumbs the same size as your custom sliderthumb. They will not be visible but they will be draggable. */ input[type=range]::-ms-thumb { width: 40px; height: 40px; border-radius: 0px; border: 0 none; background: transparent; } input[type=range]::-moz-range-thumb { width: 40px; height: 40px; border-radius: 0px; border: 0 none; background: transparent; } input[type=range]::-webkit-slider-thumb { width: 40px; height: 40px; border-radius: 0px; border: 0 none; background: transparent; -webkit-appearance: none; } /* Eliminate the default appearance and tooltip behaviour that is peculiar to IE and Edge. */ input[type=range]::-ms-fill-lower { background: transparent; border: 0 none; } input[type=range]::-ms-fill-upper { background: transparent; border: 0 none; } input[type=range]::-ms-tooltip { display: none; }

At this point, if you reload your example, you’ll find that the default range elements will now be hidden. Notice also that the width and height are set to 100% of its containing element (the .slidershell class in our example). However, the CSS for the thumb pseudo-elements requires us to enter a specific width and height in pixels. These dimensions should match the size of whatever image you plan to use for the thumb because we must ensure that the draggable area of the invisible range input matches the size of the visible thumb image.

Next, we can choose an image to use for the draggable thumb. I selected an old 90s-style library image of a green marble beveled square:

Following this, we can style our customized range input to look however we’d like:

/* The .slider and .slidervertical classes are for the range inputs. Set the z-index high so its on top. */ .slider, .slidervertical { position: absolute; left: 0; top: 0; overflow: visible; z-index: 100; } /* slidershell exists only to provide a positioning context for the range input and other elements.*/ .slidershell { border: 0 none; position: relative; left: 0; top: 0; overflow: visible; } /* .slidertrack is the visible track on which the user drags the thumb button. */ .slidertrack { border: 2px outset #666; border-radius: 4px; position: absolute; } /* .sliderfill adds color (or a gradient as seen here) to the track as the user drags the thumb. */ .sliderfill { border: 2px solid #00767f; border-radius: 4px; position: absolute; opacity: 0.2; pointer-events: none; background: #00767f; background: linear-gradient(90deg, #005555, #006699); } /* .sliderthumb can be any css you like including an image. The dimensions must match those found in the rule for input[type=range]::-webkit-slider-thumb. */ .sliderthumb { width: 40px; height: 40px; background-image: url('thumb.png'); background-size: 40px 40px; background-position: 0px 0px; background-repeat: no-repeat; background-color: transparent; position: absolute; left: 0; top: 0; border: 0 none; padding: 0; margin: 0; text-align: center; pointer-events: none; } /* .slidervalue can be styled as you see fit */ .slidervalue { width: 40px; height: 40px; line-height: 40px; color: #fff; font-family: sans-serif; font-size: 18px; position: absolute; left: 0; top: 0; border: 0 none; padding: 0; margin: 0; text-align: center; pointer-events: none; }

Finally, we can tie everything together with JavaScript. The showValue function receives a parameter representing the value chosen in the range element and a second parameter representing the slider number. The third parameter is a boolean to indicate vertical orientation if true. We can have as many sliders as we want on one page, all we need to do is give them each a serialized id (#sliderthumb1, #sliderthumb2, etc.). Then, with some simple math, we can use the value to locate and rotate the thumb, display the value as text, and fill the track with color as the user drags the thumb. A series of inline if structures allows us to support vertical orientation when requested. I also included a setValue() function you can use to set the values of your sliders when the page loads.

/* We need to change slider appearance oninput and onchange */ function showValue(val,slidernum,vertical) { /* setup variables for the elements of our slider */ var thumb = document.getElementById("sliderthumb" + slidernum); var shell = document.getElementById("slidershell" + slidernum); var track = document.getElementById("slidertrack" + slidernum); var fill = document.getElementById("sliderfill" + slidernum); var rangevalue = document.getElementById("slidervalue" + slidernum); var slider = document.getElementById("slider" + slidernum); var pc = val/(slider.max - slider.min); /* the percentage slider value */ var thumbsize = 40; /* must match the thumb size in your css */ var bigval = 250; /* widest or tallest value depending on orientation */ var smallval = 40; /* narrowest or shortest value depending on orientation */ var tracksize = bigval - thumbsize; var fillsize = 16; var filloffset = 10; var bordersize = 2; var loc = vertical ? (1 - pc) * tracksize : pc * tracksize; var degrees = 360 * pc; var rotation = "rotate(" + degrees + "deg)"; rangevalue.innerHTML = val; thumb.style.webkitTransform = rotation; thumb.style.MozTransform = rotation; thumb.style.msTransform = rotation; fill.style.opacity = pc + 0.2 > 1 ? 1 : pc + 0.2; rangevalue.style.top = (vertical ? loc : 0) + "px"; rangevalue.style.left = (vertical ? 0 : loc) + "px"; thumb.style.top = (vertical ? loc : 0) + "px"; thumb.style.left = (vertical ? 0 : loc) + "px"; fill.style.top = (vertical ? loc + (thumbsize/2) : filloffset + bordersize) + "px"; fill.style.left = (vertical ? filloffset + bordersize : 0) + "px"; fill.style.width = (vertical ? fillsize : loc + (thumbsize/2)) + "px"; fill.style.height = (vertical ? bigval - filloffset - fillsize - loc : fillsize) + "px"; shell.style.height = (vertical ? bigval : smallval) + "px"; shell.style.width = (vertical ? smallval : bigval) + "px"; track.style.height = (vertical ? bigval - 4 : fillsize) + "px"; /* adjust for border */ track.style.width = (vertical ? fillsize : bigval - 4) + "px"; /* adjust for border */ track.style.left = (vertical ? filloffset + bordersize : 0) + "px"; track.style.top = (vertical ? 0 : filloffset + bordersize) + "px"; } /* we often need a function to set the slider values on page load */ function setValue(val,num,vertical) { document.getElementById("slider"+num).value = val; showValue(val,num,vertical); }

Making vertical inputs

To make those vertical inputs we mentioned earlier we can set the third parameter of the showValue() function to true and add orient="vertical" to the input itself, like so:


<input class=”slidervertical” id=”slider3″ type=”range” min=”0″ max=”100″ value=”0″ oninput=”showValue(value,3,true);” onchange=”showValue(value,3,true);” orient=”vertical” /> </div> </td>

The orient="vertical" attribute is only supported by Firefox, so to fix this we’ll need to update our CSS:

/* we need a separate rule for when the range input is to be vertical */ input[type=range].slidervertical { -webkit-appearance: slider-vertical; writing-mode: bt-lr; /* IE */ opacity:0.01; /* needed to hide the default slider-vertical appearance */ }

Because we have to use -webkit-appearance: slider-vertical, we have to set the opacity to 0.01 here to keep the vertical slider invisible. And here’s what that additional markup and CSS will look like:

See the Pen 840d5006ed127be58f30e1891b4698af by CSS-Tricks (@css-tricks) on CodePen.

Wrapping up

For the longest time styling inputs was beyond challenging. But now, with a little CSS and JavaScript, we can fix these problems in all modern browsers without the heroic efforts required in the past.

More information

AngularJS – The Next Big Thing

via AngularJS – The Next Big Thing – CodeProject.

AngularJS is the next big thing for web applications.

AngularJS is a framework for client side web application development that brings with it the virtues of organization, structuring and the architectural pattern that helps make enterprise and data centric business web application development a breeze.

AngularJS is open source web application framework wrapped around native HTML/JS/CSS technologies. It augments the web development techniques with patters and practices that helps web application development become more mature and be able to handle more and more responsiblity that can (and should be) be shifted from the backend to the frontend.

AngularJS is “Super-powered by Google” and has a active community around it so anyone starting out with Angular can except to have a super charged ecosystem already present and one can quickly get started to building cool things and have their own “WOW” moments while using Angular.

Angular comes as a natural extension to the thinking and mindset of the modern web application developer. Angular brings the power where it belongs. Angularjs is built around design principles that supports scalability, maintainability, modularization at it core. It is best suited for thick client business web applications. It encourages the usage of best practices and patterns of development and thus drives the development of a high quality decoupled modular maintainable application. It serves as a solid base for large business web applications.

What Angular provides:

  • Architecture/organization patterns out of the box (MVC/SPA/DI)
  • View templating using plain-old HTML (no new templating language to learn) for creating dynamic views
  • Allows to extend HTML vocabulary to create new UI widgets/components
  • Avoids scattered DOM manipulation spagetti code
  • Inherent support for testing of the application
  • Provides modularity, loose coupling and reusability
  • Parallel development and comprehensible code due to virtue of MVC

Design goals (as on AngularJS guide):

  • Decouple DOM manipulation from application logic. This improves the testability of the code.
  • Regard application testing as equal in importance to application writing. Testing difficulty is dramatically affected by the way the code is structured.
  • Decouple the client side of an application from the server side. This allows development work to progress in parallel, and allows for reuse of both sides.
  • Guide developers through the entire journey of building an application: from designing the UI, through writing the business logic, to testing.

Building a Bootstrap Contact Form Using PHP and AJAX

via Building a Bootstrap Contact Form Using PHP and AJAX – Tuts+ Web Design Tutorial.

In this tutorial I’ll go over the steps to create a working contact form, utilising the ever popular front-end framework Bootstrap, in combination with AJAX and PHP. From there we can explore some additional features such as some fancy CSS animation with animate.css, further validation in JavaScript and refining the user experience with asynchronous content.

At the time of writing Bootstrap 3.3.5 is the most current version, and it’s worth mentioning that we are using a default build of Bootstrap (with a 12 column layout) for this tutorial. When following along make sure you use the latest snippets and code structures as outlined by the Bootstrap documentation.

Responsive Sidebar Navigation

via Responsive Sidebar Navigation in CSS and jQuery | CodyHouse.

Building responsive navigations for mega sites is never an easy task. If you’re working on an admin panel, chances are you’ll need to design and develop a vertical menu, with plenty of sub-categories. That’s why we decided to share today’s snippet! Our Sidebar navigation can make your life easier by providing a starting, simple template for your next project 😉

Video: Building our own browser with CSS⁄HTML and NodeJS

Ever wanted your very own browser with proper support for 200 tabs and a built-in Hello Kitty UI? Watch David code the monstrosity live! Using only CSS, HTML and Javascript we’ll create a brand new browser with a custom UI and amazing/horrible features.

With Node.js and bindings to modern browser engines(Electron, nw.js) we can build desktop applications with web technologies, we can even build browsers where anyone who can program the web can program their browser. This talk will start by looking at just how amazing web-based desktop apps can be and end with building a monster of a browser.

Features I’ll build in the browser:
Amazing sound effects
Multiple rows for tabs enabling hundreds of tabs ruining usability
Bookmark manager that rejects sites that aren’t on Alexa top 100, only the best will do!

Video: Visual Studio Tools for Apache Cordova

In this episode, Robert is joined by Ryan Salva, who shows us what’s new in the Visual Studio Tools for Apache Cordova. These enable developers to use their HTML, CSS and JavaScript (or TypeScript) skills to write and debug Windows, iOS and Android apps. Ryan focuses on the most recent additions to the tools, including changes to the project system and support for the latest in modern Web technologies.

How to Build VR on the Web Today

via How to Build VR on the Web Today.

To begin your development adventure into the Virtual Web, there are three potential ways to do this:

  • JavaScript, Three.js and Watching Device Orientation
  • JavaScript, Three.js and WebVR (My new preferred method!)
  • CSS and WebVR (still very early days)

I’ll go over each one and show a short summary of how each works.