Posted: Monday, March 12, 2012

Device Screen Sizes for Media Queries using HTML5 and CSS3

Media QueriesI attended the Dallas "Day of Dot Net" where Responsive Design using Media Queries was discussed in several sessions. I had already been coding using media queries and have been playing with the creation of a personal portfolio page over the last few days.

One of the questions debated was the "break points" for specific media platofrms (Androids, iPads, smart phones, etc. So after a few days of trial and error here is a current broad list of devices and min- max- widths for media queries:

/* Smartphones (portrait and landscape) ----------- */
@media only screen
and (min-device-width : 320px)
and (max-device-width : 480px) {
/* Your Styles */
}

/* Smartphones (landscape) ----------- */
@media only screen
and (min-width : 321px) {
/* Your Styles */
}

/* Smartphones (portrait) ----------- */
@media only screen
and (max-width : 320px) {
/* Your Styles */
}

/* iPads (portrait and landscape) ----------- */
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px) {
/* Your Styles */
}

/* iPads (landscape) ----------- */
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : landscape) {
/* Your Styles */
}

/* iPads (portrait) ----------- */
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : portrait) {
/* Your Styles */
}

/* Desktops and laptops ----------- */
@media only screen
and (min-width : 1224px) {
/* Your Styles */
}

/* Large screens ----------- */
@media only screen
and (min-width : 1824px) {
/* Your Styles */
}

/* iPhone 4 ----------- */
@media
only screen and (-webkit-min-device-pixel-ratio : 1.5),
only screen and (min-device-pixel-ratio : 1.5) {
/* Your Styles */
 

Posted: Saturday, March 10, 2012

Using jQuery Multiselect Post with PHP Implode to grab array variables

ImplosionI cut my teeth on DHTML ("Dynamic"  HTML using javascript or Microsoft's jscript) when I started coding in 1995 when everything happened on the client browser.  With the blazing speed of 56K modems you couldn't really do too much server-side without causing your users endless frustration while waiting for a page refresh with new data.  It has been interesting to see the movement from the client to the server with ASP and then .NET (and PHP, of course) as connectivity improved.  Today we've come full circle as javascript is once again the language of choice clent-side on mobile platforms like ipads and mobile phones.  3G is much faster than 56K modems but we still want to limit unnecessary calls to the server. I now live in jQuery and backbone.js libraries and develop sites and apps using HTML5 responsive design with media queries where the size of the screen determines layout so that one site will render across almost all platforms (test my new, unfinished, portfolio page by dragging the corner of the browser to ever smaller widths to see the effect).

I do somewhat less PHP programming than most developers but occasionally I run into a puzzler (at least to me) as happened this week.  A political client wanted a simple PHP form to post to a database and send two emails. That was fairly straightforward.  But one of the form fields allowed multiple selections.  

I dove into my favorite jQuery library and tossed in some live validation and tested the post grabbing the multiselect field named xschool:

<?php $xschool = $_POST['xschool']; ?>

But when I went to "echo" the variables I received the text string "array". Ooops.

Allright, all I had to do is this, right? 

if ($xschool) {
foreach ($xschool as $d){echo $d;}
}

And, sure enough, when I tested the form and did a simple "print" or "echo" using the code I indeed all of the schools selected by the user in the original form were displayed. 

So, I grabbed the variable "d" and stuck it into the email and database code where it immediately failed and returned the text string "array" again.

$ToEmail = "".$_POST["xemail"].""; 
$EmailSubject = 'Constituent Survey Responses'; 
$mailheader = "From: survey@client.com\r\n"; 
$mailheader .= "BCC: client@client.com\r\n";
$mailheader .= "Reply-To: client@client.com\r\n"; 
$mailheader .= "MIME-Version: 1.0\r\n";
$mailheader .= "Content-type: text/html; charset=iso-8859-1\r\n"; 
$MESSAGE_BODY = '<html><body>';
$MESSAGE_BODY .= '<p>Thank you for completing the survey.<br />Here are your responses:</p>';
$MESSAGE_BODY .= "<p>e-mail: ".$xemail."<br>"; 
$MESSAGE_BODY .= "Zipcode: ".$xzipcode."<br>";
$MESSAGE_BODY .= "Schools Selected: ".$d."<br>"; 
$MESSAGE_BODY .= "Comment: ".nl2br($xcomments)."</p>";
$MESSAGE_BODY2 .= "</body></html>";
mail($ToEmail, $EmailSubject, $MESSAGE_BODY, $mailheader) or die ("Failure"); 

Well, after fiddling around for 20 minutes I was stumped. How does one grab and array and use it as a variable? It seemed simple enough. Then I remembered "explode and implode". First I needed to grab the posted data from the multiselect field as an array:

if ($xschool)
 {
    foreach ($xschool as $schools)
     {
      $d[] = $schools ;
    }
 }

Then I needed to "implode" the array:

$MESSAGE_BODY .= "Schools selected: ".implode(', ',$d)."<br>";

In PHP the implode() function returns a string from the elements of an array using the syntax implode(separator,array). Although the implode() function accept its parameters in either order, for consistency with explode(), you should use the documented order of arguments. The separator parameter of implode() is optional. However, it is recommended to always use two parameters for backwards compatibility. Example:

 <?php
$arr = array('Hello','World!','Beautiful','Day!');
echo implode(" ",$arr);
?>

The output of the code above will be: Hello World! Beautiful Day!

Here is a working example of the form for you to test:

Posted: Saturday, December 10, 2011

Framebusting Javascript, Clickjacking and SEO

FramebusterHijacking a user's web session using an iframe is known as clickjacking.  A technique called called "frame busting" is the most common defense to break out of the surrounding "enemy" frame.  We developed a variant of the code that the Stanford Web Security Group suggested in their paper Busting Frame Busting: A Study of Clickjacking Vulnerabilities at Popular Sites which examined common frame busting code and the ways it can be circumvented.

 

Most of the current javascript solutions use a conditional statement like

if (top != self

Followed by a counter-action like:

top.location = self.location

The solutions may work if the victim page is enclosed by a single frame but fails when the attacker encloses the victim page in two frames. Double framing is only one attack, other methods examined in the paper include onBeforeUnload events, 204 Flushing, Cross Site Scripting (XSS), Referrer Checking and Clobbering top.location.

So what to do? The paper suggests using the X-Frame-Options HTTP header and creating a Firefox Content Security Policy.

We have coded a javascript variant that we use on pages that require text input like log-in forms, registration forms, password request forms and contact forms and other pages not usually indexed by the search engines. A minor drawback of any javascript solution is that it must be present on all pages that you want to protect from framing attacks. Although we cannot guarantee security - the code may already be vulnerable to unknown attacks - we believe it is currently the correct approach to the problem.

<style type="text/css">
    html { visibility:hidden; }
</style>

<script language="javascript" type="text/javascript">
    if ( self == top ) {
document.documentElement.style.visibility='visible';
    } else {
top.location = self.location;
    }
</script>

The code is simple. On page load the CSS style hides the html. The page will attempt to bust out of the frame but will remain blank if JavaScript is disabled; if the code is blocked by double framing or by unload events; or if the the code is blocked by 204 Flushing, XSS, Referring Checking or Clobbering.

The use of the code on non-indexed pages to prevent framing is highly recommended however there is a caveat for indexed pages.  Because the solution hides content with CSS there may be an unintended impact on Moz Ranking when considering Search Engine Optimization (SEO) for pages indexed by the search engines. We have asked for clarification and will update this post as soon as we hear back from our friends at Google.

Posted: Wednesday, June 29, 2011

2011 Marketing Charts and Assessment Offer

If you enjoy learning new marketing data, you will love our free personal website evaluation. Sign up today to receive a website assessment with a marketing expert!