Surf the Dream A discourse of links and articles from Justin Avery

Tag Archive: tutorial

  1. Chaining pseudo selectors

    Leave a Comment

    I’ve been working on a sales dashboard for work that highlights the number of sales, number of meeting, contribution to the overall targets and a few other things that make a member of the sales team proud they’re hitting their targets.

    The layout requirements I had for this part of the dashboard was

    • Zebra background to differentiate rows.
    • Gold Border around the top performer
    • Golden Crown sat upon the top performer

    Here’s what we’re after….

    pseudo-selectors-example

    The layout we are aiming for….

    Zebra background with pseudo selectors

    The zebra background is done through the use of the nth-child approach.

    
    .sales-team:nth-child(2n) { background: #eee;}
    
    

    What we’re doing here is saying we want to select the element with the style .sales-team and then for every second element, (2n), we should add a background: #eee;. That’s that problem sorted.

    The next part is getting the golden border and the crown to appear.

    Psu, psu, psuedo

    This is where we apply a border and the crown on the first element.

    The border can be added by selecting the :first-of-type pseudo element.

    
    .sales-team:first-of-type { border: solid 5px gold;}
    
    

    The next requirement is to add the crown as a background image. Now I wanted this to sit on the top corner of the first row so that it spills out of the container on the angle.

    To accomplish this I wanted to add a :before pseudo element and use that as the background image for positioning, but I needed it to run on the same :first-of-type element.

    Fortunately you can daisy chain pseudo elements together so I ended up with

    
    .sales-team:first-of-type:before {
        content: '';
        background-image: url(../images/crown.svg);
        background-repeat: no-repeat;
        background-size: 75%;
        position: absolute;
        width: 150px;
        height: 150px;
        top: -45px;
        left: -40px;
        -webkit-transform: rotate(-18deg);
        -moz-transform: rotate(-18deg);
        -ms-transform: rotate(-18deg);
        -o-transform: rotate(-18deg);
        transform: rotate(-18deg);
    }
    
    

    The above code we are selecting the first element with :first-of-type, and then creating a :before pseudo element to contain the Crown.SVG file. This hook is then used to position the background image on the top left side of the element a rotate the crown.

    The result is something that works quite nicely and cheers up the sales team, or at least the one at the top of the table.

  2. Learn CSS Layout

    Leave a Comment

    This site teaches the CSS fundamentals that are used in any website’s layout.

    They assume you already know what selectors, properties, and values are. And you probably know a thing or two about layout, though it may still be a rage-provoking activity for you.

    Visit Link

  3. Building Am I Responsive

    30 Comments

    Eighteen months ago I put together a very crude webpage that used iFrames to preview a few of the popular viewports as a quick and dirty test for a responsive project we were working on.

    There were plans to improve the tools to something with quite a bit of sophistication, but with time constraints in addition to a plethora of similar tools becoming available I put it back on the shelf labeled “The projects that never were”.

    I never really needed this tool again. All my final testing was done on devices, and in the early stages using Media Queries (by Spark Box), dragging the chrome window. That was, at least, until a Thursday night in early February.

    After spending a couple of hours putting together the responsive design newsletter it was all ready to go once I added the feature site image to the top of the newsletter. To do this I would open up safari and resize the browser from 1600px to 1280px, 768px, 320px and take screen shots at each point. I would then import those shots to Photoshop and position it within some pre canned browser chrome images (iMac, macbook, iPad and iPhone). Once that was done I’d export it to the web, run image optim and upload it to the newsletter. The whole process would take 15-30 minutes depending on distractions.

    It’s not just the weekly newsletter I need them for either, it’s also website reviews for new responsive designs, visual aids for presentations, feedback for clients on their designs…

    So after the newsletter went out on Friday morning I opened up the laptop and started building a responsive design testing tool.

    Am I Responsive?

    A screen shot of Am I Responsive

    Am I Responsive doing it’s best inception impersonation.

    Am I Responsive is super simple, you enter a URL within the input and press go and it takes that URL and rewrites the src attribute of 4 iframes. Each iframe has a height a width attribute set to mimic a particular viewport, in this case 1600px, 1280px, 768px & 320px.

    	
    $(document).ready(function() {
    // Change iFrame on a Button Click Event
        $(".button").click(function(event){
            $("iframe").attr('src', $( '#url' ).val());
        });
    });
    	
    

    The div around the iframe uses a transparent png background-image of the particular device chrome (iMac, Macbook, iPad and iPhone), which then makes it appear as though the iframe site is appearing directly within the device. Of course at their full size the iframe‘s would never all fit not the screen let alone within the image screen space, so the CSS3 transform property is used to scale the size of the iframes to fit nicely within the ‘device’.

    
    .laptop {
      background-image: url("../images/laptop-screen-optimised.png");
      width: 477px;
      height: 307px;
      top: 264px;
      left: 560px;
      position: absolute;
      z-index: 2;
      iframe {
        width: 1280px;
        height: 802px;
        top:26px;
        left:60px;
        transform: scale(0.277);
    -webkit-transform: scale(0.277);
    -o-transform: scale(0.277);
    -ms-transform: scale(0.277);
    -moz-transform: scale(0.277);
    transform-origin: top left;
    -webkit-transform-origin: top left;
    -o-transform-origin: top left;
    -ms-transform-origin: top left;
    -moz-transform-origin: top left;
      }
    
    }
    
    

    By Friday afternoon I had it working at the most basic level and pushed it out to a few twitter friends. The first thing they came back with was that it wasn’t responsive, ironic isn’t it, and although it was primarily required for screenshots on the desktop it was kind of annoying me too. I made a few adjustments to the overall scale of the preview area as you move through the various viewports and made some simple changes to the form as well.

    
    @media (max-width: 850px){
      .display{
        height: 500px;
      transform: scale(0.65);
      -webkit-transform: scale(0.65);
      -o-transform: scale(0.65);
      -ms-transform: scale(0.65);
      -moz-transform: scale(0.65);
    }
    .desktop{left: 100px;}
    .laptop{left: 440px;}
    .tablet{left: 0px;}
    .mobile{left: 180px;}
    
    }
    
    @media (max-width: 768px){
      .display{
        height: 450px;
      transform: scale(0.55);
      -webkit-transform: scale(0.55);
      -o-transform: scale(0.55);
      -ms-transform: scale(0.55);
      -moz-transform: scale(0.55);
    }
    a.button {font-size: 1.6em; line-height: 1.75em; margin-top:0.5em; width:100%;}
    input {height:1.2em; width:100%;}
    
    }
    
    

    Extending

    Move me

    Rather than have the same screenshots EVERY single time I wanted the ability to move them around the screen and change their z-index order. jQuery was already getting loaded to help with setting the iframe src (my javascript is terrible, so jQuery to the rescue) so I also included jQueryUI to allow the devices to the draggable. Again, there’s probably lighter/faster ways to achieve this with JS but I tested the load and it had a reasonable response.

    
    <script src="//code.jquery.com/ui/1.10.0/jquery-ui.js">
    
    <script>
    $(document).ready(function() {
        var a = 3;
        $('.desktop,.laptop,.tablet,.mobile').draggable({
       start: function(event, ui) { $(this).css("z-index", a++); }
    });
        $('.display div').click(function() {
            $(this).addClass('top').removeClass('bottom');
            $(this).siblings().removeClass('top').addClass('bottom');
            $(this).css("z-index", a++);
    
        });
    });
    </script>
    
    
    
    This came about thanks to Setting z-index on draggable element from StackOverflow.

    Input + Enter

    I noticed during my testing that I was occasionally hitting the enter key after typing in the URL instead of hitting the GO button. To fix that I started trying to find ways to hijack the return key to activate the button instead. Fortunately I had a bit of trouble trying to achieve that because it took me in another direction of trying to deal with ?url=http://yoursite.com as part of the url string.

    I added a check to see if there was a URL variable and if so to load that into the <iframe src="". This provided the awesome benefit of being able to send someone a link that would load a specified site directly into the iframes. I think because of this the tool picked up a bit more traction in blogs and on twitter.

    
    function getUrlVars() {
        var vars = {};
        var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
            vars[key] = value;
        });
        return vars;
    }
    var first = getUrlVars()["url"]; 
    var first = decodeURIComponent(first);
    var first = first.replace(/\#$/, '');
    
    if(first === "undefined") {
      // don't do anything.
    }
    else {
    //  take the url variable and update the iframes and input field
      $("iframe").attr('src',(first));
      $('#url').attr('value',(first));
    }
    
    
    This came about thanks to getting parameters from page url from StackOverflow.

    Go, then enter – the hash #

    With the added function of the URL variable I noticed that if you used the Go button first, and then used to the enter key (or visa versa) you would get a hash at the end of the url string which would shoot the preview to the top and interfere with the device previews. To fix this I added an extra check to remove # tag if it is found at the end of the url string. If it’s a legitimate anchor tag it will still work because it only removes the # from the very end of the string.

    
    // this line achieves that and is part of the code already listed above
    var first = first.replace(/\#$/, '');
    
    

    Transparent Previews

    I noticed a couple of sites people were posting didn’t have a background colour set. These were fairly basic information sites, but still it was bugging me. If you fail to declare a background-color: on your site it defaults to browser white, however because the iframes were sitting over a background image they were showing through in the site preview. This was quickly fixed by applying a background-color:#fff; to the iframes to hide what appears behind in the background images.

    Feedback

    I’m super excited/happy/humbled from how well received this tools has become. I’ve had help from people sending in bugs they’ve found and also sending through suggestions to improve the tool.

    The feedback so far has been

    • Add rotate to mobile and tablet
    • Allow the ability to zoom into a device
    • Enable the ability to change the background-color of the preview area

    These are good suggestions, and I’ve even implemented the zoom capability locally allowing for a double click to zoom however it just doesn’t work that well in practice so I was reluctant to push it live. I need to think about how the UI would work for the other ideas as well, plus spend a bit of time trying to write the actual functionality.

    I’m always keen to hear more about the things that could improve it, because after all it was built to help speed up my own workflow so the more it can help out others the better.

    Some things to do/note

    iPhone & iPad

    Although I mentioned that I made this responsive I noticed that you don’t have any control over the height of the iFrame on these devices. The fix seems to be to add another div containing the iframe to set the viewable area of the iframe and hide the overflow.

    @media max-device-width()

    These media queries will not fire if your CSS is set up in this way. Unless you’re really really sure that you only want to trigger the query on a specific device my general advice would be to use min-width max-width and target the viewport rather than the device itself.

    Non Responsive previews

    If you’re previewing a non-responsive site you’ll probably notice that rather than zooming out so that the whole site fits in the viewport (which would happen on iPhone) it actually expands past the viewable area. I think this has to do with Mobile Safari including a faux viewport value if no value is found to improve how non responsive sites appear. Unfortunately it’s not possible (corrections?) to target the viewport meta of a site being shown through an iFrame.

    Offline

    With the local idea I thought about preparing presentations on trains, planes and automobiles. With that in mind there is now a cache manifest file added as well for those that want to take shots of local developments with not internet connection. Oh, and it made the page load even faster. Not sure if there’s any negatives to that though.

Surf the Dream is a blog that has been running since the mid 2000's when it started on BlogSpot. Over the years it's been rebranded as justinavery.me (now my resume) and JaveryDesign.com (which now redirects back to this site).

I offer consultation services through Simple Things, produce a range of educational pocket notebooks, write about the Universe and run a responsive design and a RWD Weekly Newsletter