Posts Tagged ‘css’

100% CSS Post-It®
Check it out!

Who doesn’t love Post-it notes? In my previous life, before I started learning CSS, I would ask myself “how can I make a convincing looking Post-it note in Photoshop?” After extensive CSS study and research I have come to realize that some things can be done with CSS alone. That’s right, the post it you see on the right is 100% CSS. Go ahead, check it out. Here is how it is done.

I broke the instructions up into key elements so the uninitiated can get a feel for how I constructed everything. The process itself might be helpful for some people – it was certainly helpful for me. If you aren’t interested in my life story, feel free to skip to the end for a quick ‘plug and play’ code snippet.

Making the Post-it

margin: 25px;
width: 250px;
min-height:175px;
max-height:175px;
padding-top:35px;

This is the basic square that will be built around your content. The height is somewhat complicated because I want the text to begin lower on the Post-it rather than at the top. To ensure the padding doesn’t add any height while still lowering the text, set a min and max parameter on the height.

The Yellow Color

background: rgb(255,255,136); /* Old browsers */
background: -moz-linear-gradient(-45deg, rgba(255,255,136,1) 77%, rgba(255,255,214,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right bottom, color-stop(77%,rgba(255,255,136,1)), color-stop(100%,rgba(255,255,214,1))); /*Chrome,Safari4+*/
background: -webkit-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* IE10+ */
background: linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffff88', endColorstr='#ffff88',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
}

This is where much of the magic happens. When you think of a Post-it note you probably think of yellow, right? It’s true, but we need to think in 3D terms. It needs a yellow gradient that fades at a 45-degree angle into a slightly lighter color at the bottom right. This will help with creating a “peeled up” illusion later on. I just used this amazing tool (http://www.colorzilla.com/gradient-editor) to make mine. This code looks like a huge mess, but it’s mostly due to cross-browser support. Speaking of cross-browser support, Internet Explorer 6-9 does not like diagonal gradients so this website provides a nice fallback and converts our diagonal gradient into a horizontal gradient. This is not optimal so I recommend changing the last line of code here:

filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffff88', endColorstr='#ffff88',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */

Either make startColorstr and endColorstr the same number (which will turn off the gradient and make the Post-it a solid color) or change GradientType from 1 to 0 (this will make the gradient vertical instead of horizontal). I chose to remove the gradient.

border:1px solid #E8E8E8;
border-top:60px solid #fdfd86;

I am doing something special with the border. You could easily give this a 1px light grey border and it would look fine, however, Post-its have that sticky glue-like substance on top that, when in use, has a slightly different look than the rest of the Post-it. I created a thick top border that is nearly the same color as the yellow I used. The effect is so slight you almost can’t tell it’s there, but anyone who does will surely appreciate it.

Font Styling

font-family:'Reenie Beanie';
font-size:22px;
text-align:center;

This is my font styling. Consider putting a script font on your post it, something like Marker Felt or Comic Sans, or preferably something interesting from the Google Font API like Reenie Beanie seen here.

A Peeled Corner

Although Post-its are square, the bottom corners tend to peel off the surface a bit when stuck to something. This 3D effect is subtle, but adds a ton to the feel of the note. This is the code to make only the bottom right corner look peeled for most browsers. As usual, sorry IE users :P

-webkit-border-bottom-right-radius: 60px 5px;
-moz-border-bottom-right-radius: 60px 5px;
-o-border-bottom-right-radius: 60px 5px;

And there we have it. The final code for the Post-it class looks like this:

.postit {
  text-align:center;
  width: 275px;
  margin: 25px;
  min-height:175px;
  max-height:175px;
  padding-top:35px;
  position:relative;
  border:1px solid #E8E8E8;
  border-top:60px solid #fdfd86;
  font-family:'Reenie Beanie';
  font-size:22px;
  -webkit-border-bottom-right-radius: 60px 5px;
  -moz-border-bottom-right-radius: 60px 5px;
  -o-border-bottom-right-radius: 60px 5px;display:inline-block;
  background: rgb(255,255,136); /* Old browsers */
  background: -moz-linear-gradient(-45deg, rgba(255,255,136,1) 77%, rgba(255,255,214,1) 100%); /* FF3.6+ */
  background: -webkit-gradient(linear, left top, right bottom, color-stop(77%,rgba(255,255,136,1)), color-stop(100%,rgba(255,255,214,1))); /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* Opera 11.10+ */
  background: -ms-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* IE10+ */
  background: linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffff88', endColorstr='#ffff88',GradientType=0 ); /* IE6-9 fallback on horizontal gradient */
}

I know what you are thinking. Where is the shadow? Well, the shadow is actually a different piece of CSS. We’re doing more than simply adding a box shadow around the note. We could do that, but then it would look like the Post-it is floating rather than stuck on the wall.

Creating a non-box shadow is a bit of a workaround. We are actually going to be making a shape, giving that shape a shadow, and carefully adjusting that shape/shadow so only about 5% of it is visible. Sounds easy, right? I used this website to fine tune my effect (http://www.wordpressthemeshock.com/css-drop-shadow). It took me some playing to get it right, but I am happy with the result.

The Bottom Corner Shadow

content: "";
width:125px; height: 25px;
-moz-transform:skew(10deg,10deg) translate(-45px,-15px);
-webkit-transform:skew(5deg,5deg) translate(-45px,-15px);
-o-transform:skew(5deg,5deg) translate(-45px,-15px);
transform:skew(10deg,10deg) translate(-45px,-15px)

Here is our shape. It’s a long rectangle that has been skewed to have more acute angles.

position:absolute;
right: 0px; bottom:9px;
z-index: -1;

This positioning hides the box behind our Post-it and makes sure it stays underneath. I ran into an interesting problem when using this on a template sites like the one you are on now. The negative z-index actually put the shadow behind the background, making it invisible. I am not sure if this will be the case on other CMS sites, or other templates, but to get around this problem you simply need to give your background a z-index of 0.

background: rgba(0, 0, 0, 0.2);
 -moz-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  -webkit-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  -o-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  /* box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40); */

Finally, the shadow. It takes a bit of tweaking to make it show up just right. Also you might have noticed that box-shadow is commented out. This is the IE workaround. IE doesn’t support rotation or skew so the shape that is actually making our shadow doesn’t cast the correct shadow. Without a box-shadow, it is just hidden under the yellow not not bothering anyone. The shadow website I provided above wants you to put together your inline code in a funny way. After you wrap your content in the .postit class, you need to make another empty div just to hold the box shadow. Like this:

<div class="postit">
Here is my postit content
<div class="cornershadow">
</div>
</div>

That is a bit clunky and I always want to do less inline work, so I put my own spin on things. Instead of making a separate class for the cornershadow, which would look like this:

.cornershadow {
  content: "";
  position:absolute;
  z-index:-1;
  right: 0px; bottom:9px;
  width:125px;
  height: 25px;
  background: rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  -webkit-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  -o-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  /* box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40); */
  -moz-transform:skew(10deg,10deg) translate(-45px,-15px);
  -webkit-transform:skew(5deg,5deg) translate(-45px,-15px);
  -o-transform:skew(5deg,5deg) translate(-45px,-15px);
  transform:skew(10deg,10deg) translate(-45px,-15px)
}​

…I used the psuedo class :after to simply put the cornershadow code after all postit class divs! So now all you need to do is make a div class=”postit” and put whatever you want in it!

The complete code:

.postit {
  text-align:center;
  width: 275px;
  margin: 25px;
  min-height:175px;
  max-height:175px;
  padding-top:35px;
  position:relative;
  border:1px solid #E8E8E8;
  border-top:60px solid #fdfd86;
  font-family:'Reenie Beanie';
  font-size:22px;
  -webkit-border-bottom-right-radius: 60px 5px;
  -moz-border-bottom-right-radius: 60px 5px;
  -o-border-bottom-right-radius: 60px 5px;display:inline-block;
  background: rgb(255,255,136); /* Old browsers */
  background: -moz-linear-gradient(-45deg, rgba(255,255,136,1) 77%, rgba(255,255,214,1) 100%); /* FF3.6+ */
  background: -webkit-gradient(linear, left top, right bottom, color-stop(77%,rgba(255,255,136,1)), color-stop(100%,rgba(255,255,214,1))); /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* Opera 11.10+ */
  background: -ms-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* IE10+ */
  background: linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffff88', endColorstr='#ffff88',GradientType=0 ); /* IE6-9 fallback on horizontal gradient */
}

.postit:after {
   content: "";
  position:absolute;
  z-index:-1;
  right: 0px; bottom:9px;
  width:125px;
  height: 25px;
  background: rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  -webkit-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  -o-box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40);
  /* box-shadow: 40px 27px 5px rgba(0, 0, 0, 0.40); */
  -moz-transform:skew(10deg,10deg) translate(-45px,-15px);
  -webkit-transform:skew(5deg,5deg) translate(-45px,-15px);
  -o-transform:skew(5deg,5deg) translate(-45px,-15px);
  transform:skew(10deg,10deg) translate(-45px,-15px)
}

And the inline code:

<div class="postit">Check out this Post-it <br /> It's 100% CSS!</div>

If you want to further increase your Post-it fun consider separating the colored gradient and borders into its own class, naming that class .yellow. Then create a class for other Post-it colors like .blue, .pink, .orange, and so on. That way you get to name your div class=”positit pink” and get different colors. You can also give your Post-its a rotation (like the one I have at the beginning of this post) by wrapping it in a div and giving that div rotate transformation.

Google recently announced that they began factoring in web site load time into their search engine ranking algorithm. This has brought the importance of a fast load time front and center even though “fewer than 1% of search queries will change as a result” of this update. MentorMate.com likely was not impacted very significantly from this change to Google’s ranking algorithm; however, we still decided to optimize our site’s load time. We did this because Google showed that “delays of under a half-second impact business metrics.” It’s better to be safe than sorry, and besides, it’s not that difficult to optimize your site. We recommend you do the same with your web site, here are nine easy ways to do just that:

1. Place scripts near closing body tag

Scripts block parallel downloads. While a script is downloading, the browser will wait until it finishes before downloading anything else. This is why it is recommended that you get everything else out of the way before having your users download scripts.

2. Remove any broken links/references

Simply enter your web page URL in Pingdom’s Full Page Test Tool. This tool will color-code any broken links/references in red so you can easily identify them.

3. Specify image dimensions

When image dimensions are not specified in the HTML and/or CSS of a web page, the web server must spend resources calculating these dimensions. It’s particularly important to specify the dimensions of images being used in conjunction with heavy Javascript image-manipulation libraries.

4. Localize external file references to minimize DNS requests

This is another spot in which Pingdom’s Full Page Test Tool comes in handy. Enter your URL and look for any file references to external domains. If possible, copy these files onto your own domain and link to them locally to minimize DNS requests.

5. Minimize slow-loading libraries and external widgets

Libraries and external widgets need to be chosen carefully. Sometimes it’s worth sacrificing load time for particularly engaging/useful libraries and/or widgets; however, sometimes you can live without the library and/or widget. For example, on MentorMate.com we felt it was worth sacrificing Sexybuttons for better load time, but sacrificing load time for Shadowbox. External widgets can be particularly bad for a site’s load time because of their reliance on external servers.

6. Compress your files using gzip

These days, gzip comes pre-installed on most web servers. You can check to see if gzip is running your server quite easily using Google’s Firebug “Speed Test” extension. Open Firefox, visit the web site you’d like to optimize, and open Firebug. From there, click “Analyze Performance” and select the “Resources” tab. Then you can expand any file to view details. If gzip is installed and compressing the element you are viewing, you will see what is highlighted in red in the following screenshot:

Google's Firebug "Page Speed" extension gzip enabled

7. Merge Javascript and CSS files or use Minify

Depending on the complexity of your site, it can be quite time consuming to merge all CSS into one file. The same goes for Javascript. This is why Minify was developed.  Minify “combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers.” Then you simply need to install it on your site, select the files you want it to serve together, change some references in your header, and you’re good to go. This will minimize your site’s load time by further helping to reduce HTTP requests.

8. Load cross-browser compatibility hacks only for necessary browsers

For instance, we use the IE PNG FIX for IE6 PNG transparency compatibility. This script adds an extra second to web site load time. For this reason, we only load the script if the visitor is running IE6 by applying an IE6-specific stylesheet which references the IE PNG FIX. This way the extra load time will only impact IE6 visitors.

We simply added the following line of code to our header:

&lt;!--[if IE 6]&gt;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/ie6.css&quot; /&gt;&lt;![endif]--&gt;

9. Use CSS sprites to minimize HTTP Requests

A CSS sprite is the combination of multiple images into one. Then CSS is used to reference different aspects of the image where needed. This reduces load time by minimizing all of these images into only one  HTTP request. CSS Tricks has a good example of CSS sprites.

This post will cover the basic setup and creation of an application with web content for iPhone that will load local CSS and some useful JavaScript functions. Most of these hints I found partially in different blogs and forums listed in the reference section. The idea is to collect all them together. You can use the following technique to create a more attractive application design.
Creating an application using UIWebView control is not the focus of this post. Here is a helpful beginner’s tutorial for creating an application using UIWebView. We assume that you are already familiar with this topic.

UIWebView load

Our work will start with a little change in calling load method of the UIWebView instance. Instead of loadRequest

[[webView graphWebView] loadRequest:requestObj];

we use the loadHTMLString method, providing an NSString object that contains HTML code of our page as a parameter:

[[webView graphWebView] loadHTMLString:htmlPageStr baseURL:baseURL];

To get this page to load resources and styles correctly, you have to set up the right URL:

Set baseURL property of UIWebView to refer your bundle’s resources directory

MentorMate

Initial loading screen with progress indicator

On the following reference[2] you can find a short and clear revision of the problem of displaying local images in a UIWebView. To use relative paths or files in UIWebView, you have to load the HTML into the view with the correct baseURL parameter. The following example shows how to do this:

NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];

And then call load method of UIWebView provide above NSURL parameter:

[[webView graphWebView] loadHTMLString:pageStr baseURL:baseURL];

A short explanation: An NSBundle object represents a location in the file system that groups code and resources that can be used in a program. mainBundle method returns the NSBundleobject that corresponds to the directory where the current application executable is located. bundlePath instance method of NSBundle returns the full pathname of the receiver’s bundle directory. NSURL class is used to create an object which will hold the URL information. It provides a way to manipulate URLs and the resources they reference. loadHTMLString method of UIWebView has parameter baseURL that accept an NSURL object instead of a pathname as the file reference. Giving the above baseURL to UIWebView, you can refer to your bundle’s resources directory like this:

&lt;img src=&quot;myimage.png&quot;&gt;

Or from within CSS like this:

background-image: url(loading.gif)

It’s important to note that resources (images, CSS and JavaScript Files) inside your application bundle are at the root of the bundle, even if you place them in an separate group (folder) in your project.

Giving the correct URL to UIWebView will allow you to refer to local resources in your page, but it does not work in all cases. If you want to use JavaScipt, some additional settings have to be done.

Link a CSS and JavaScript files

MentorMate

Second loading screen with progress indicator

Now you can use generic HTML technique to add CSS and JavaScript to the web page and displaying in a UIWebView.

&lt;link href=&quot;default.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
 &lt;script type=&quot;text/javascript&quot; src=&quot;showhide.js&quot;&gt;&lt;/script&gt;

Do not forget to add your CSS and Javascript files to the xCode project (if you are using external files).

Some additional actions have to be taken before starting your application and using JavaScript functions.[3]

XCode setup (*.js) javascript as some type of source code needs to be compiled in the application. We would like to include it as a resource so I’ve solved it by doing two things:

  1. Select .js file and in the “Detail” view unselect the bullseye column indicating it is compiled code
  2. In the “Groups & files” view expand the “Targets” tree and expand the application then go to “Copy Bundle Resources” and drag the *.js files into it.

The Apple dev forums has a posted solution. [4] You need to do two things – select the .js file in your project, and turn off the checkbox that indicates that it is compiled (the “bullseye” column). If you don’t do this, you’ll get a warning in your build log about being unable to compile the file (which should be your first warning – always try to figure out and and correct any and all warnings that appear in your build).

Set transparent background color for UIWebView

MentorMate

Final screen with graph representation.

In our example we need to figure out a transparent background for UIWebView. On the parent View Container we have additional controls (buttons, labels) and already defined background. The following code will set this:

[[webView graphWebView] setBackgroundColor:[UIColor clearColor]];&lt;/code&gt;

[[webView graphWebView] setOpaque:NO];

Example

MentorMateDemoJS is a simple application example which uses the settings described above. It is a view-based application that shows a graphical representation of some data. Application behavior consists of a predefined call with formatted data to Vvidget Service[5] for graph generation. The service returns an image that is loaded in UIWebView Design Resource. The update button is added to resend the graph request and update view.

The Problem: Graph image requires some time for loading.

Our Decision: Notify user of graph loading process by showing a progress bar during load time.

To achieve this, we use UIWebView with local resource of two JavaScript functions. One to show/hide notification messages and the other to visualize a progress bar during loading time. In the provided sources you can find all these steps implemented.

Sources of the example iPhone application

References

  1. iPhone SDK Articles, UIWebView Tutorial, August 19, 2008
  2. iPhone Development Blog, UIWebView – Loading External Images and CSS, February, 2009
  3. StackOverflow, iPhone UIWebView local resources using Javascript and handling onorientationChange
  4. Developer Forum, UIWebView and JavaScript, 2009
  5. Vvidget, Vvidget Server™ Reference Manual , 2010