Tag: CSS

CSS Seven-Segment Display Tutorial

April 11, 2012 » Geek

I had an idea for a little project today that needed a seven-segment display. As a first pass I’m going to implement it in all software before seeking out hardware for it.

Knowing I wanted to run my prototype in the browser I looked for a way to show a seven-segment display. I considered images, but then I decided to challenge myself to implement it in CSS only.

I recently read the CSS Hexagon Tutorial by James Tauber and I felt I could apply some of those techniques to get this working.

Step One: A Segment

The obvious first step is to get a single segment displayed.

The basic shape of a segment is actually well defined in all four edges of the box from the hexagon tutorial.

height: 100px;
width: 100px;
border-top: 30px solid #FF3636;
border-bottom: 30px solid #36FF36;
border-left: 30px solid #3636FF;
border-right: 30px solid #FFFF36;

So now I just needed to extract a single edge for my first segment, which proved quite simple.

height: 0;
width: 100px;
border-top: 30px solid #FF3636;
border-left: 30px solid transparent;
border-right: 30px solid transparent;

Step Two: Fill It Out

Iterating from that first segment is easy, just change which borders you need for which segment you require. However, I needed a positioning system. I decided to go with absolute positioning, with a relative wrapper. Traditionally these displays are addressed with each segment being a letter, so I followed that pattern.

<div class="seven-segment">
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
  <div class="d"></div>
  <div class="e"></div>
  <div class="f"></div>
  <div class="g"></div>
</div>

The CSS for this is quite similar from segment to segment, it’s mostly positioning and picking which border to colorize.

.seven-segment {
  position: relative;
}
.seven-segment .a {
  position: absolute;
  left: 10px;
  height: 0;
  width: 100px;
  border-top: 30px solid #FF3636;
  border-left: 30px solid transparent;
  border-right: 30px solid transparent;
}
.seven-segment .b {
  position: absolute;
  left: 150px;
  top: 10px;
  height: 100px;
  width: 0;
  border-right: 30px solid #FF3636;
  border-top: 30px solid transparent;
  border-bottom: 30px solid transparent;
}
.seven-segment .c {
  position: absolute;
  left: 150px;
  top: 180px;
  height: 100px;
  width: 0;
  border-right: 30px solid #FF3636;
  border-top: 30px solid transparent;
  border-bottom: 30px solid transparent;
}
.seven-segment .d {
  position: absolute;
  top: 320px;
  left: 10px;
  height: 0;
  width: 100px;
  border-bottom: 30px solid #FF3636;
  border-left: 30px solid transparent;
  border-right: 30px solid transparent;
}
.seven-segment .e {
  position: absolute;
  left: 0;
  top: 180px;
  height: 100px;
  width: 0;
  border-left: 30px solid #FF3636;
  border-top: 30px solid transparent;
  border-bottom: 30px solid transparent;
}
.seven-segment .f {
  position: absolute;
  left: 0;
  top: 10px;
  height: 100px;
  width: 0;
  border-left: 30px solid #FF3636;
  border-top: 30px solid transparent;
  border-bottom: 30px solid transparent;
}

Step Three: G Segment

Here’s where it gets interesting. Our standard segment shape will not work for the center segment, the G segment, which is beveled on both sides, something we can’t do with a single div. First let’s split it up and treat it differently for top and bottom.

<div class="g">
  <div class="top"></div>
  <div class="bottom"></div>
</div>

Now we’ll style these using our regular segment markup.

.g .bottom {
height: 0;
width: 100px;
border-top: 30px solid #FF3636;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
}
.g .top {
height: 0;
width: 100px;
border-bottom: 30px solid #FF3636;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
}

It works, sort of. We now have the shape we want, but it’s way too thick. It won’t fit in the slot we have without looking strange.

Halving the borders and extending the width makes it look better.

This would be a good stopping point, but the angled edges don’t seem as long in G, so I tried to fix that.

.seven-segment .g {
  position: absolute;
  top: 160px;
  left: 10px;
}
.seven-segment .g .bottom {
  height: 0;
  width: 130px;
  border-top: 15px solid #FF3636;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
}
.seven-segment .g .top {
  height: 0;
  width: 130px;
  border-bottom: 15px solid #FF3636;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
}

The best solution I came up with was dealing with it at a smaller size, then using a transform to scale it up to where I wanted it. It’s not exact, and it’s not the same width as the other segments, but the slopes are right, it fits and it feels as close to balanced as I’ve been able to get.

.seven-segment .g {
  position: absolute;
  top: 162px;
  left: 35px;
  -webkit-transform: scale(1.4);
  -moz-transform: scale(1.4);
  -ms-transform: scale(1.4);
  -o-transform: scale(1.4);
  transform: scale(1.4);
}
.seven-segment .g .bottom {
  height: 0;
  width: 80px;
  border-top: 15px solid #FF3636;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
}
.seven-segment .g .top {
  height: 0;
  width: 80px;
  border-bottom: 15px solid #FF3636;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
}

Conclusion

That was pretty painless! I wish I had a better solution for G, but this one is passable.

You can check out a nifty demo with some JavaScript and on/off states here.

Got some ideas for how to make G better? Please share in the comments!

Tags: ,

New Design!

February 5, 2012 » Geek, Life

After six years of sameness, I finally redesigned the blog.

While I was at it, I made it responsive, so it should look good on mobile too.

Responsive Layout

Some content is bound to still look funny as I haven’t reviewed all of it, but for the most part I think it looks good!

Special thanks to @johnhenrymuller for design help and my cool new logo.

CSS Heart

December 7, 2009 » Geek

(Update 2009-12-07)
I fixed it to work in webkit too.

I was playing with clip and border-radius and put this little guy together.

<3 CSS

I haven’t tested it in anything but Iceweasel 3.5.5, so your mileage may vary. You can check it out here: CSS Heart.

This is only two divs to make the heart. Much less impressive than the Homer Simpson in CSS.

I suppose I could have just used &hearts; huh?

Javascript Rating Meter 2

September 1, 2006 » Geek

In between classes today I updated the meter. It’s essentially the same script, just it changes background images now, instead of having transparent images. I only did it for the pretty-factor since I had made the nice stars already. Once I’ve written it into an un-intrusive script, which is turning out to be a bit harder than I thought, I’ll likely swap it back and make it some better graphics.

Still cool, and with a few more lines could actually be used.

Version 2 Example

Tags: ,

Javascript Rating Meter

August 31, 2006 » Geek

Update: A newer version is outlined in this post.

Due to a discussion I had earlier today, I was thinking about how to make one of those little star meters where you can click to set the rating and they change colors. I took some time to code up this quick version.

I didn’t want to use image swapping, because that wouldn’t be as flexible. So instead, you change the background color and have a transparent cutout of the image you want over that. It’ll make more sense once I get an example made.

For now, here’s my prototype. It needs a lot of work to make it into a good script, but it’s a start. Example Here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var sets = Array();
 
function hover(level) {
for(j = 1; j <= level; j++)
{
document.getElementById('S'+j).style.backgroundColor = "#0FF";
}
for(k = (level+1); k <= 5; k++)
{
document.getElementById('S'+k).style.backgroundColor = "transparent";
}
}
 
function unhover(group) {
for(j = 1; j < 6; j++)
{
if(sets[group] == null)
{
document.getElementById('S'+j).style.backgroundColor = "transparent";
}
else
{
if(sets[group] >= j)
{
document.getElementById('S'+j).style.backgroundColor = "#F00";
}
else
{
document.getElementById('S'+j).style.backgroundColor = "transparent";
}
}
}
}
 
function set(group,level) {
sets[group] = level;
}
Tags: ,