Friday, November 30, 2012

Create a Stylish Callout Box with CSS

I recently needed to create a callout box using only CSS. I was able to do this using the css :before and :after Pseudo-elements. The trick was adding the border color to the side I wanted the triangle to point towards. Here is the CSS.

#comment{
 position: relative;
 padding: 10px;
 width: 150px;
 height: 150px;
 background-color: #F0F0F0;
 border: 1px solid #D0D0D0;
 -webkit-box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
 -moz-box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
 box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
}
 #comment:after, #comment:before {
  border: solid transparent;
  content: ' ';
  height: 0;
  position: absolute;
  width: 0;
 }
 #comment:after {
  border-color: rgba(240, 240, 240, 0);
  border-bottom-color: #F0F0F0;//Change this to change direction of triangle
  border-width: 9px;
  top: -18px;
  left: 7px;
 }
 #comment:before {
  border-color: rgba(208, 208, 208, 0);
  border-bottom-color: #D0D0D0;//Change this to change direction of triangle
  border-width: 10px;
  top: -20px;
  left: 6px;
 }

Here is a fiddle that shows what this produces. I also found this great resource online that mimics what I am producing here.

I actually liked Simon's approach to this and thought it was worth writing down his code for future reference. Just in case his site is ever taken down.

.arrow_box {
 position: relative;
 background: #88b7d5;
 border: 4px solid #c2e1f5;
}
.arrow_box:after, .arrow_box:before {
 bottom: 100%;
 border: solid transparent;
 content: " ";
 height: 0;
 width: 0;
 position: absolute;
 pointer-events: none;
}

.arrow_box:after {
 border-color: rgba(136, 183, 213, 0);
 border-bottom-color: #88b7d5;
 border-width: 30px;
 left: 50%;
 margin-left: -30px;
}
.arrow_box:before {
 border-color: rgba(194, 225, 245, 0);
 border-bottom-color: #c2e1f5;
 border-width: 36px;
 left: 50%;
 margin-left: -36px;
}

Wednesday, October 24, 2012

Naming Conventions

This is a topic that will bring a wide range of opinions, but in order to keep myself consistent through my various projects, I have decided to follow the below naming conventions based on the language I am programming in.

PHP

Variable: underscore
Function: underscore
Class: camelCase

Javascript

Variable: camelCase
Function: camelCase
Constructor: camelCase

HTML/CSS

Class: hyphen
ID: hyphen
Other Attributes: hyphen/underscore (depending on project needs)

File Names

hyphen

MySQL

Database: underscore
Tables: underscore
Fields: underscore

Wednesday, October 17, 2012

Preventing Margin Collapse

Margin collapse happens when top and bottom margins of block elements are combined into a single margin whose size is equal to the margin of the element with the largest margin.

There are three basic cases of when margin collapse occurs.

  1. Adjacent siblings
  2. Parent and first/last child
  3. Empty blocks

The most frustrating case for me is the second one. An example would be adding margin-top: 10px to a header element and instead of the expected behavior of having the header be 10px down from the top of the div the entire div moves down 10px. Setting the div's overflow property to anything but the default visible value fixes this problem.

Some great resources to check out:

Retain Height of Floated Elements

A very common thing that a developer moving away from tables will want to do is float divs next to each other. This is a great way to display elements side by side but one fall back is they lose there block height causing other content to come up from beneath them. There is a simple fix to this problem that I would like to show today.

The HTML

<div id="container">
   <div id="floatLeft">
       <p>I want to keep this elements height.</p>
   </div>
   <div id="floatRight">
       <p>I want to keep this elements height as well.</p>
   </div>
</div>

The fix is setting the parent div of both floated elements overflow property to hidden/auto.

The CSS

#container{
  width: 960px;
  margin: 0px auto;
  overflow: hidden;
}
#floatLeft{
  float: left;
  width: 480px;
}
#floatRight{
  float: right;
  width: 480px;
}

Saturday, October 13, 2012

PHP Access Specifiers

There are three access specifiers in PHP: public, private, and protected.

Public

The access specifier public allows properties of a class to be accessed/modified outside the class without having to go through a get or set method. This allows for the least amount of protection for the property.

class Person {
 public $name;
 
 public function setName($name) {
  $this->name = $name;
 }
 
 public function getName() {
  return $this->name;
 }
}
 
$p = new Person();
$p->setName("Bob Jones");
echo $p->name;  // echos Bob Jones no error because it is public
$p->name = "Joe Smith" ; // this sets the name to Joe Smith only because it is public

Private

Private is another access specifier that offers the most protection for a property. The property is only editable within the class itself.

class Person {
 private $name;
 
 public function setName($name) {
  $this->name = $name;
 }
 
 public function getName() {
  return $this->name;
 }
}
 
$p = new Person();
$p->setName("Bob Jones");
echo $p->getName(); //this will echo Bob Jones
echo $p->name; //can't access name this way, only through getName()
$p->name = "Joe Smith" ; //can't set name this way either         

Protected

The protected access specifier offers more protection then public but allows for a property to be accessed in its class and all other classes that extend its class.

class Person {
 protected $name;
 
 public function setName($name) {
  $this->name = $name;
 }
 
 public function getName() {
  return $this->name;
 }
}
 
class Employee extends Person {
 
 private $employeeNumber;
 
 public function setEmployee($name, $employeeNumber) {
  $this->name = $name; //this is storing name in the person class 
  $this->employeeNumber = $employeeNumber;
 }
        
}
 
$e = new Employee();
$e->setEmployee("Bob Jone",10000100);
echo $e->name; // this would throw an error as it is only accessable through methods in Employee or Person class

Friday, October 5, 2012

Reformat Text for Blog

I wrote this for my blog. I have my blog set up so that I need to change all of my opening and closing tags (< >) for html elements to their html entity name element (&lt; &gt;). This can be done with a few lines of javascript.

$(function(){
 $('#cleanFormat').click(function(){
     $('#text').val($('#text').val().replace(/</g,"&lt;")); 
     $('#text').val($('#text').val().replace(/>/g,"&gt;"));
 });
});

To see an example of this follow this link.

Creating a Datepicker

I had a project recently where I needed to create a custom datepicker for a HTML form. I will walk through the basics of how I was able to accomplish this.

The CSS

My specific form required the ability for the user to add multiple dates for a specific event up to a maximum of 20. So I knew I needed to hide the unneeded date fields from view. So I created the class hidden to allow for this. The datepicker needed an absolute positioning because I wanted to move it around the page as needed.

 .hidden{
  display:none; 
 }
 #datepicker{
  background: #ccc;
  position: absolute; 
  z-index: 50;
  border: 1px solid #000;
  padding: 5px;
 }
 #closeButton{
  float:right; 
 }

The Datepicker

I used select lists to allow the user to select the date and start time. The key here was using php to pull in the current year so that I could dynamically create it. I also used php to create some for loops so that I didn't have to manually go through and type all of the options I wanted in my select lists.

<div id="datepicker" class="hidden">
 <table border="0">
  <tr>
   <td colspan="3"><strong>Date:</strong></td>
  </tr>
  <tr>
   <td>
    <select class="changeDate" id="month" name="month">
     <option id="month1" value="1">January</option>
     <option id="month2" value="2">February</option>
     <!-- etc... -->
    </select>
   </td>
   <td>   
    <select class="changeDate" id="day" name="day">
     <?php
      for($i=1; $i<32; $i++){
         echo '<option id="day'.$i.'" value="'.$i.'">'.$i.'</option>'; 
      }
     ?>
    </select>
   </td>
   <td> 
    <select class="changeDate" id="year" name="year">
     <option selected="selected" value="<?php echo date(Y); ?>"><?php echo date(Y); ?></option>
     <option value="<?php echo date(Y) + 1; ?>"><?php echo date(Y) + 1; ?></option>
     <option value="<?php echo date(Y) + 2; ?>"><?php echo date(Y) + 2; ?></option>
     <option value="<?php echo date(Y) + 3; ?>"><?php echo date(Y) + 3; ?></option>
     <option value="<?php echo date(Y) + 4; ?>"><?php echo date(Y) + 4; ?></option>
    </select>
   </td>
  </tr>
 </table>  
 <table border="0">
  <tr>
   <td colspan="3"><strong>Start Time:</strong></td>
  </tr>
  <tr>
   <td>
    <select class="changeDate" id="hour" name="hour">
     <?php
      for($i=1; $i<13; $i++){
         echo '<option id="hour'.$i.'" value="'.$i.'">'.$i.'</option>'; 
      }
     ?>
     </select>
    </td>
    <td>
     <select class="changeDate" id="minute" name="minute">
      <option id="minute00" value="00">00</option>
      <option id="minute01" value="01">01</option>
      <option id="minute02" value="02">02</option>
      <!-- etc... up to ten -->
      <?php
       for($i=10; $i<60; $i++){
         echo '<option id="minute'.$i.'" value="'.$i.'">'.$i.'</option>'; 
       }
      ?>
     </select>
    </td>
    <td>
     <select class="changeDate" id="ampm" name="ampm">
      <option id="am" value="am">am</option>
      <option id="pm" value="pm">pm</option>
     </select>
    </td>
   </tr>
  </table>   
 <input id="closeButton" type="button" value="Close"/>
</div>

The Javascript

I have condensed my code to just the basics. Please see comments for more specifics.


 $(function(){
   var globalFocus = 'required-date'; //I used this to see which date field was currently in focus
                
   $('#month<?php echo date(n);?>').attr('selected', 'selected');
   $('#day<?php echo date(j);?>').attr('selected', 'selected');
   $('#hour<?php echo date(g);?>').attr('selected', 'selected');
   $('#minute<?php echo date(i);?>').attr('selected', 'selected');
   $('#<?php echo date(a);?>').attr('selected', 'selected');
   //I used the above code to set up the defaults for the datepicker
   updateDate(globalFocus);//This sets the focused date field value
    
   $('.date').focus(function() { //corresponds to all of the date fields 
         globalFocus = $(this).attr('id');
         $('#datepicker').show();
         var position = $(this).position(); //Return position of date field to position the date picker right below it
         var height = $(this).height(); 
         $('#datepicker').css('top', position.top+height); 
         $('#datepicker').css('left', position.left);
  });

  $('.changeDate').change(function(){
        updateDate(globalFocus);
  });
  
  $('#closeButton').click(function(){
        $('#datepicker').hide();
  });
 });

 function updateDate(currentFocus){
     $('#'+currentFocus).val($('#month').val()+'/'+$('#day').val()+'/'+$('#year').val()+" "+$('#hour').val()+':'+$('#minute').val()+$('#ampm').val()+" - "+$('#hourend').val()+':'+$('#minuteend').val()+$('#ampmend').val());
 }

Wednesday, August 8, 2012

CSS Hover Menu

Today I want to show a stylish way using CSS to create a hover drop down menu.

The HTML

<div id="navbarMain" class="navbar">
    <ul> 
       <li><a href="#">first level link</a>
          <ul>
            <li><a href="#">second level link</a>
               <ul>
                  <li><a href="#">third level link</a></li>
                  <li><a href="#">third level link</a></li>
                  <li><a href="#">third level link</a></li>
                  <li><a href="#">third level link</a></li>
               </ul>
            </li>
            <li><a href="#">second level link</a></li>
            <li><a href="#">second level link</a></li>
            <li><a href="#">second level link</a></li>
            <li><a href="#">second level link</a></li>
            <li><a href="#">second level link</a> 
                <ul>
                  <li><a href="#">third level link</a></li>
                  <li><a href="#">third level link</a></li>
                </ul>    
            </li>
            <li><a href="#">second level link</a></li>
            <li><a href="#">second level link</a></li>
           </ul>
        </li>
        <li><a href="#">first level link</a>
            <ul>
               <li><a href="#">second level link</a></li>
               <li><a href="#">second level link</a></li>
             </ul>
        </li>
        <li><a href="#">first level link</a>
           <ul>
             <li><a href="#">second level link</a></li>
           </ul>
        </li>
        <li><a href="#">first level link</a></li>   
    </ul>
</div><!-- /navbarMain -->

The CSS

.navbar{
 position: relative;
 width: 100%;
 opacity: 0.75;
}

.navbar ul{
 position: relative;
 padding: 0px; 
 margin: 0px;
}

.navbar ul li{
 position: relative;
 float: left;
 list-style-type: none;
 width: 25%;
}

.navbar ul li a{
 text-decoration: none;
 display: block;
 height: 35px; 
 line-height: 35px; /*centers the text vertically*/
 text-align: center;
 border: 1px solid #111;
 background: #333;
 font-weight: bold;
 color:  #fff !important;
 text-shadow: 0 /*shadow-x*/ 1px /*shadow-y*/ 1px /*shadow-radius*/ #111 /*shadow-color*/;
 background-image: -webkit-gradient(linear, left top, left bottom, from( #444444 /*background-start*/), to( #2d2d2d /*background-end*/)); /* Saf4+, Chrome */
 background-image: -webkit-linear-gradient( #444444 /*background-start*/, #2d2d2d /*background-end*/); /* Chrome 10+, Saf5.1+ */
 background-image: -moz-linear-gradient( #444444 /*background-start*/, #2d2d2d /*background-end*/); /* FF3.6 */
 background-image: -ms-linear-gradient( #444444 /*background-start*/, #2d2d2d /*background-end*/); /* IE10 */
 background-image: -o-linear-gradient( #444444 /*background-start*/, #2d2d2d /*background-end*/); /* Opera 11.10+ */
 background-image: linear-gradient( #444444 /*background-start*/, #2d2d2d /*background-end*/);
 text-overflow: ellipsis;
 overflow: hidden;
}

.navbar ul li a:hover{
 border: 1px solid #000;
 background: #444444;
 font-weight: bold;
 color:  #fff !important;
 text-shadow: 0 /*shadow-x*/ 1px /*shadow-y*/ 1px /*shadow-radius*/ #111 /*shadow-color*/;
 background-image: -webkit-gradient(linear, left top, left bottom, from( #555555 /*background-start*/), to( #383838 /*background-end*/)); /* Saf4+, Chrome */
 background-image: -webkit-linear-gradient( #555555 /*background-start*/, #383838 /*background-end*/); /* Chrome 10+, Saf5.1+ */
 background-image: -moz-linear-gradient( #555555 /*background-start*/, #383838 /*background-end*/); /* FF3.6 */
 background-image: -ms-linear-gradient( #555555 /*background-start*/, #383838 /*background-end*/); /* IE10 */
 background-image: -o-linear-gradient( #555555 /*background-start*/, #383838 /*background-end*/); /* Opera 11.10+ */
 background-image: linear-gradient( #555555 /*background-start*/, #383838 /*background-end*/);
}

.navbar ul li a:active{
 border: 1px solid #000;
 background: #222;
 font-weight: bold;
 color:  #fff !important;
 text-shadow: 0 /*shadow-x*/ 1px /*shadow-y*/ 1px /*shadow-radius*/ #111 /*shadow-color*/;
 background-image: -webkit-gradient(linear, left top, left bottom, from( #202020 /*background-start*/), to( #2c2c2c /*background-end*/)); /* Saf4+, Chrome */
 background-image: -webkit-linear-gradient( #202020 /*background-start*/, #2c2c2c /*background-end*/); /* Chrome 10+, Saf5.1+ */
 background-image: -moz-linear-gradient( #202020 /*background-start*/, #2c2c2c /*background-end*/); /* FF3.6 */
 background-image: -ms-linear-gradient( #202020 /*background-start*/, #2c2c2c /*background-end*/); /* IE10 */
 background-image: -o-linear-gradient( #202020 /*background-start*/, #2c2c2c /*background-end*/); /* Opera 11.10+ */
 background-image: linear-gradient( #202020 /*background-start*/, #2c2c2c /*background-end*/);
}

.navbar ul li ul{
 position: absolute;
 width: 100%;
 left: -99999em;
}

.navbar ul li:hover ul{
 left: 0px;
}

.navbar ul li ul li, .navbar ul li ul li:hover ul li{
 width: 100%;
}

.navbar ul li ul li ul, .navbar ul li:hover ul li ul{
 position: absolute;
 width: 100%;
 left: -99999em;
 top: 0px;
}

.navbar ul li ul li:hover ul{
 left: 100%;
}

To see a working demo of the code follow this link.

Monday, August 6, 2012

Adding Time

Today I thought I would add a quick note about how to utilize the strtotime() function in PHP to add time and still keep it in the desired format. The trick is to pass the strtotime() function to the date() function in order to keep the formatting.

$end_time = date('H:i:s', strtotime($start_time)+5);
// 5 represents time to be added in seconds. 

Saturday, August 4, 2012

HTML5 Video

A very beautiful yet frustrating improvement in HTML5 is the browser support of native video without any third party plugin with the use of the video tag.

<video controls="controls" width="352" height="288" poster="poster.jpg">
     <source src="video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
     <source src="video.ogv" type='video/ogg; codecs="theora, vorbis"'>
     <track kind="captions" src="captions.vtt" srclang=en label=English />
</video>

The controls tells the browser to use its default controls with the video. The poster is the image that should be shown while the video is being downloaded or until the user pushes the play button. I include two different source files with the video because not all browser play nicely together. Browsers like Firefox require the open video file type ogv while browser like IE 9 and Safari want the mp4 file type. The track is used to display text for captions/subtitles on the video.

There are a few problems that can keep your video from playing and the biggest ones I have run into are incorrect encoding and incorrect MIME type. Internet Explorer is the most unforgiving in both of these regards. The video needs to be encoded with H.264. I like to use ffmpeg to do this with the following command:

ffmpeg -i input.mpeg -s 352x288 -vcodec -libx264 -preset slow output.mp4
Here are two samples for webm and ogv file types.
ffmpeg -i input.mpeg -vcodec libvpx -acodec libvorbis -f webm output.webm

ffmpeg -i input.mpeg -vcodec libtheora -acodec libvorbis output.ogv

Another great utility is Miro.

Your server needs to be set up to send the correct MIME type to the browser. In apache you need to add the following to the httpd.conf file. Remember to reboot the server after doing so.

AddType video/mp4 .mp4 .m4v
AddType video/ogg .ogv
AddType video/webm .webm

I hope this is enough to get you started in the right direction. If you still have questions here are some good links to check out ffmpeg commands, trouble shooting IE9. Good luck!

Tuesday, June 19, 2012

Writing Classes with PHP

Classes allow for the creation of objects that can contain multiple properties. The properties can then be pulled from the class using methods for a specific object. I recently wanted to create an array of objects, so I created an index.php page that looked similar to this.

<?php
include("class_lib.php");

for ($i=0; $i < 10; $i++){
// Use data pulled from a database or post data
   $array[$i] = new person ($name,$age,$address);
}
var_dump($array);
?>

I first include the class I am going to use to create the objects and then I create a new person for each instance of the array. I suggested that you get the data from post data or from a database.

The class will then look something like this.

<?php
class person{
  private $name;
  private $age;
  private $address;
  public function __construct($persons_name, $persons_age, $persons_address){
     $this->name = $persons_name;
     $this->age = $persons_age;
     $this->address = $persons_address;
  }

  // You can create set methods like

  public function set_name($new_name) {
     $this->name = $new_name;
  }

  //Or you can create get mehthods like

  public function get_name(){
     return $this->name;
  }

}
?>

If you still have questions, then a good resource is to go to killerphp.com

Thursday, June 14, 2012

jQuery Mobile Select Menu

Had a bit of a headache today trying to figure out how to dynamically load a select menu using ajax with jQuery Mobile. The select menu would load fine, but I was losing all of the styling. Thanks to a post from kadaj's musing I realized that I needed to initialize the select menu before I tried to refresh it.

$('#selectMenu').selectmenu();
$('#selectMenu').selectmenu('refresh', true);

This method helped me avoid the "Uncaught cannot call methods on selectmenu prior to initialization; attempted to call method 'refresh'" error I was getting.

Wednesday, June 13, 2012

Responsive Web Design

I have recently been working with jQuery Mobile and learned something pretty awesome about CSS. I was trying to think how I could make my web page look different on a phone and a tablet. That is when I looked into what jQuery Mobile was doing on their docs page. You can target a device by running a query through CSS to check for the devices width. Here is the example.

@media all and (min-width: 650px){
      /*Do css styling here for devices with a width of 650px or greater */
}
@media all and (min-width: 750px){
      /*Do css styling here for devices with a width of 750px or greater */
}
@media all and (min-width: 1200px){
      /*Do css styling here for devices with a width of 1200px or greater */
}

This also works great in a desktop environment. As you re-size the browser window the different styles will come into play overwriting the previous styles. The above example is using the min-width property, but the max-width property can also be used to effect devices that are the same or smaller than the max-width.

All about Colors

As a web developer/designer one is often trying to find the right color combination. I am more of a developer than a designer so I often struggle in this area. I have found some useful tools to help me in this area.

For windows I like to use ColorPic. It allows me to find a site that I really like the color scheme on and find the hex codes, if I can't figure it out in firebug first of course. Linux also has a nice tool for this called Gpick.

I also recently found the site colorcombos.com. It shows a lot of promise in being a valuable resource. Colorlayout.com also shows some potential.

Tuesday, June 12, 2012

Error Reporting with PHP

I often find myself needing to display the errors and warnings for my php scripts. A quick and easy way of doing this is adding the following lines of code to the top of your php page.

error_reporting(E_ALL);
ini_set('display_errors', '1');

Thursday, June 7, 2012

All About HTML Forms

The two things you must have when it comes to using the form tag is one the action attribute and second the method attribute. I also often use the enctype attribute when doing file uploads.

<form action="get-data.html" method="post" enctype="multipart/form-data"> </form>

The method attribute takes 'get' or 'post'. Get will send the data in plain text in the URL (not secure for more sensitive information) while post sends data as a http post transaction (more secure).

The enctype attribute specifies how the form data is encoded when submitting it to the server. I generally use enctype="multipart/form-data" when uploading a file. No characters are encoded, but it is necessary for file transactions.