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 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;
}

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.

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.