I don’t like the idea of making a student feel confused and uneasy. I want the learning process to be pleasant, and preferably without tears and frustration.

I once had a boss that said I was in danger of coddling the trainees I was in charge of then. And I’ve thought a lot about that since then. Was I, really? And would he really have said that to a man? (He called me a “mother hen”).

Is it better for the student to make sure they take steps on their own, give them a small piece of information and then let them find their own way? Or is it better to make a safe space, and raise the starting point, so to speak.

My instinct is usually the latter. To create great material and try to fix what I hated when I learned. I don’t want anyone to feel crappy about themselves just because they don’t understand. I really hate that feeling myself.

Is that being coddling, and if so, is that a bad thing?

In the course I’m creating now, Pinkwebdev (an evening course for women), I decided to try out the principle of flipped classroom. We’re going to have 2 hours each week, 17 students and 12 weeks. That’s not a lot of time. So instead of them coming to the occasions and then just using all the time to listen to me droning on, I decided that they should listen to me droning on at home instead!

In hindsight this might not be such a novel thing, after all Khan Academy is huge in promoting the flipped classroom idea. For me it opens up for using all the time we see the students to just talking and together solving problems. It also makes it possible for students to learn at their own speed, rewatch videos, or skip things they already know.

What it doesn’t do is give opportunity for questions, your just supposed to watch all the videos and then do excercises later on. And that sort of separates the theory from the practice, wich also could be a bad thing. But for me that’s the lesser of two evils. Better to be able to actually program when you see the reast of the group and the assistants.

But the main question I have now is how fast can you really learn? What is reasonable to learn in a week? I mean, you can go to university for 5 years to learn qomputer science, how far can you really get in 12 weeks?

I’m actually quite nervous now that I have set up to high a speed. Betweek week 1 and 2 I’m discussing

  • Running a function, with and without parameters
  • Creating and using variables
  • Primitive data types
  • Simple math (addition, multiplication and so on)
  • If-statements

And between week 2 and 3 I have crammed

  • Adding scripts to an HTML page
  • Create a function
  • Create function with parameters
  • Return data from function
  • Arrays
  • Loops
  • Objects

It sure looks like a lot to learn in two-three weeks, but I want to quickly get to where you can create stuff! I don’t really care that they understand the exact difference between function or methods, or that they have even heard of prototypal inheritance, or OOB vs functional programming. I want us to start creating web pages and solving problems.

I’m scared and excited at the same time to see if it works, or if it all crasches down and everyone quits because they’re so confused they all gave up. Time will tell, I guess.

This August I got an idea that seems to have been waiting for me for a few years, at least. It’s a combination of circumstances coming together, starting with me talking about becoming a web developer at Pink Programming’s event at International Womens day this spring, to having a lot of extra free time this autumn, via speaking at a CodeHer event in Copenhagen and there sitting next to a woman taking her first step into JavaScript (we made a count down to her trip next year). Another contributing factor was the fact that I’ve been looking for a new job and truly discovered the drought of women in my field of work: frontend development.

So what I came up with is a course in web development for women. I want to teach programming, and this is my way! I also want colleagues. I feel like I’ve done being the only woman in an entire team now, it’s enough.

And so far it’s progressed better than I ever hoped. We are a team of five women putting this together, and first day of this evening course is on February the 1st next year.

And I remember my introduction to programming at the University. I literally sat at my kitchen table crying trying to learn arrays and loops in Java. We had a teacher that droned on and on about boxes and Object Oriented Programming (queue sacral music here), and I didn’t understand anything at all. I wouldn’t have made it if it wasn’t for the teaching assistants.

I don’t want anyone’s introduction to tech and IT to be like that, I want it to be filled with the possibilities of what you can do. Simply put, I want to find the best way to learn programming there is. And that’s not at all a megalomaniac thought…

I love writing CSS. One of the best things I know is getting a new design and spend time implementing it. But I rarely get to do that anymore.

It’s a blessing as well as a curse that CSS has such a low threshhold for getting started. The relative simpleness of CSS and HTML means that the world of web development opens up in a way that JavaScript can not offer, other languages even more so. But it also means that it’s easy to miss that CSS can be hard, and that you need to study and pratice to understand how and why things work.

As soon as you try more complex things you run into obstacles. Floating and negative margins are often used to fix things. Developers get angry, saying that CSS is a crappy way to do things, and it might well not be the optimal way. But still, I think that some of the problems lies in the fact that since it seems so easy at first glance, many don’t bother learning it for real.

Writing good, reusable CSS is not easy, and writing a 3000 lines long CSS file can happen without anyone noticing. JavaScript often gets blamed for making it easy to write bad code, but with CSS this is even more true. It so easily happens that you pile new rules on top of old, the cascading part of CSS that is so great gets overused.

But I have noticed in the last few month or year that the amount of CSS that I’m writing has decreased enormously. Great, and sad, I say. Great beacuse you have some sort of base to build upon and use complete components from. Before you hade to write it all yourself, but with the advent of frameworks, internal as well as external, comes using already written stuff. Many times this is great, you have some sort of baseline and don’t have to reinvent the wheel over and over again.

But still, I miss it.

TLDR: Can’t be done with ng-click, use jQuery or jQLite, or don’t do it at all

Say that you have a web page that have a search bar at the top, but the search input is hidden from view when viewed from a small device. You have a button with a looking glass that when tapped it shows the input field. When the user want to search they don’t want to first tap the button and then tap again to focus on the input field to have the keyboard appear, they expect this to happen at once. So one element is tapped, but another should get focused.

This is quite easily done in most browsers, but not those running on iOS. The iOS developers, preferring a stable and simple UI with little visual jank, where the keyboard does not show up unnecessarily, have ensured that input elements can’t be focused without the user initiating the process.

When does the keyboard appear in iOS?

First thing first, what are the ways the keyboard appears in iOS?

  1. The natural way, the user taps an input element and the browser focuses that element and shows the keyboard
  2. The programatic way, the user taps an element and a click handler sets the focus to a different element, but within what the iOS browser considers to be the same action.

Focus using a click handler

You can attach a jQuery click handler (probably also a native click handler, but I didn’t try that) to an element and inside that set focus on an input field, and that will show the keyboard, like this:

1
2
3
$('.wrapper').on('click', '#some-button', function () {
    $('#some-input').focus();
});

This will work in iOS and all other browsers that I’ve tried, since even iOS considers it user initiated. But if you remove the focus part from the timeline, for example putting it inside a timeout, it will no longer work in iOS, but other will happily set focus.

So this will not work:

1
2
3
4
5
$('.wrapper').on('click', '#some-button', function () {
    setTimeout(function () {
        $('#some-input').focus();
    });
});

The call to focus has to be directly inside the click handler

But what about Angular?

This is where I had trouble. The application I’m writing on at work is all Angular, and you don’t want to mix if you can help it. Mixing regular click handlers with ng-click makes for a hard to maintain application. I tried putting the exact same call to focus (using jQLite or jQuery, which ever) inside an ng-click, like this:

Template:

1
<button id="some-button" ng-click="focusOnInput()">Click me</button>

In controller

1
2
3
$scope.focusOnInput = function () {
    $('#some-input').focus();
};

But iOs couldn’t have cared less. It would not work. I have no idea why, but for some reason iOS consideres this less user initiated, perhaps Angular itself does a timeout or something like it. In the end I had to abandon ng-click in this case, even though it hurt somewhat, and use the same approach as above.

Looking around online I found others struggling with this. Some had ways around, some not, but this is all I could get to work.

This is how I implemented the user story that a user wants to change his or her profile picture by uploading a new one and choosing which part of it to show by cropping it.

I needed IE9 support, which made it all a lot harder. The end result is not very complex, code wise, but it took a long time, for me at least, to come up with the best way to go about this, and fit all the pieces together. I’m using two jQuery plugins, Jcrop for cropping and jQuery File Upload for uploading.

Note that there are some requirements on the server side. The actual cropping is done at the backend, not on the client, and of course you need a server that can store your images. You also need to have CORS set up on your server (?).

Here’s the workflow that I came up with:

  1. The user loads the page and all the elements are loaded.
  2. The user clicks ‘browse computer’ (what is this? clarify it is input field) to find a suitable image to upload.
  3. When user has selected an image, it is sent with a POST request to the server, which stores it in a temporary location.
  4. The new temporary image is loaded back onto the page and the cropping plugin is activated (image source is set to the temporary location).
  5. The user chooses which part of the image he or she wants by dragging the cropping rectangle.
  6. Once satisfied, the user saves the image, and the coordinates are sent to the server with a POST request. The image is not sent again, only the coordinates are needed.
  7. The server takes the temporary image and crops it with the coordinates and moves the cropped version to the final location.
  8. The finished image can be loaded back onto the page from the final location (for example user/image).

Why do we need to make such a fuss?

This workflow may seem longer and more complex than should be required. The main problem here is IE and especially IE9 (no surprise there). The server I was using was located on a different domain from the site, so I also had some CORS issues to contend with. The largest problem I had was when I was trying to crop the image before sending it, using Canvas (what is this?). This will not work. You need to set the image source for a canvas and IE9 or IE10 does not support, at all, the source of the canvas image to be different than the site (this includes files chosen using a file input, as their origin is null). So if you try to load the image from the computer, it will not work. And it will also not work with my separate domains setup. This can’t be fixed with CORS in IE9-10 (citation required). So let go of the canvas idea.

This means uploading the image first and then cropping it. This is where you might want to try and make your own FormData object and set image, with base64. This, also, is not supported by IE9. There is no way to create your own xhr request and POST an image with it. What is needed is a form tag that does the actual posting.

I was working here with a SharePoint site, and those are wrapped in one gigant form tag, and you can’t have nestled form tags. So I needed an iFrame with the form tag in it. Here’s where jQuery File Upload is your savior. Though the documentation is somewhat lacking, once you get it to work it actually works, and you don’t have to implement the actual file upload youself, which is a really good thing.

On to the actual implementation.

Implementing the file upload

First step is to include all the necessary files for the plugins to your page, of course. From Jcrop I just included the jquery.jcrop.min.js. In jQuery File Uplpoad, which is a bit more complex, I ended up needing the files jquery.fileupload.js, jquery.fileupload-image.js, jquery.fileupload-process.js, jquery.fileupload-validate.js and jquery.iframe-transport.js, but this could differ for your needs. Read the documentation carefully and try not to rip out your hair in the process (it is quite a challenging read, the information is all over the place). I also needed to deploy a file called result.html found in the project. This is to make it work in IE9, more on that below.

I added this markup:

<input id="fileupload" type="file" name="files[]">

And to my JavaScript file I added this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$('#fileupload').fileupload({
    forceIframeTransport: true,
    url: == url to your server ==,
    // The regular expression for allowed file types, matches
    // against either file type or file name:
    acceptFileTypes: /(\.|\/)(jpe?g|png)$/i,
    success: function (e, data) {
        $uploadPanel.hide();
        showCroppingPanel();
    },
    fail: function (e, data) {
        console.log(e);
        console.log(data);
    },
    done: function (e, data) {
        console.log(data);
    }
    }).on('fileuploadprocessalways', function (e, data) {
        var currentFile = data.files[data.index];
        if (data.files.error && currentFile.error) {
          // there was an error, do something about it
            console.log(currentFile.error);
            $wrongFileMessage.show();
        }
    });

    // This reditect the POST to a html file
    // needed for the iframe, and perhaps for the CORS support
    $('#fileupload').fileupload('option',
        'redirect',
        '/result.html?%s'
    );

Let’s go through it step by step.

.fileupload initializes and after that you give it options. The forceIframeTransport forces it to always create an iframe to make the POST request to. This is needed for IE9, which does not support the sending of images via xhr.

url should be self explanatory, it’s the location of your server, to where the POST request will be made.

acceptFileTypes takes a regular expression to match the file ending. And this is where I found a bit of a gotcha. You can only catch this “error” (when a user uploads the wrong file type) if you also implement the fileuploadprocessalways bit of the code above. This “pauses” the upload if there is an error, and you can for example show an error message to the user, which is what I did.

The last part is also for the iFrame. It redirects the POST to an iFrame and the HTML file is needed there. Don’t forget the %s at the end there, it won’t work without it.

Once you get all this to work, the image should magically be sent to the server. One big problem for me at first was the success handler not running, even though the image was successfully uploaded and the server returned 200. This was because I, according to the startup guide, had specified that the result should be in JSON, but the server was not sending JSON.

My main problem now is that the error handler is not run even though the server returns an error. Don’t yet know why this is.

Implementing the cropping

At this point you hopefully have a temporary image on the server. Create an <image> tag on your page, and in the success handler of the previous part, add the newly uploaded image url as source. I did it like this:

1
$croppingImage.attr('src', "http://myserver/user/picture-temp");

And then wait for it to load, and activate the Jcrop plugin on it:

1
2
3
4
5
6
7
8
9
10
11
$croppingImage.load(function () {
    $croppingImage.Jcrop({
       setSelect: [96, 96, 0, 0],
       minSize: [minSize, minSize],
       aspectRatio: 1,
       onSelect: setCoordinates
    }, function(){
       jcrop_api = this;
    });

});

As usual there are a lot of options that you can implement, I just wanted the selection to be a square.

Here I give the callback setCoordinates for each time a user updates the selection.

Those coordinates are then used when the user clicks a button.

1
2
3
4
5
6
7
8
9
10
$cropAndSaveButton.on('click', function (x1, x2, y1, y2) {
        // This happens when a user clicks to crop and save

        var requestUrl = "user/picture/crop-and-enable/" + x1 + "/" + y1 + "/" + x2 + "/" + y2;

        $.ajax({
            url: requestUrl,
            method: POST
        }).done(reloadPage);
    });

Depending on your serverside implementation here, you could send the coordinates in different ways, this is the way this backend had implemented it.

This was just an overview of how the flow and process of uploading and cropping an image could work, to help give an idea of how to think. I hope it will help someone out there.

I grew up with it and it’s hard to shake. It follows me around, looking over my shoulder everytime I try to position anything. That deeply ingrained hatred of tables. Nothing was as ugly and disgraceful as using tables to position content (that and maybe using capital letters for your tags).

  • What, are you not using THE BOX MODEL? I can’t work like this.

I sometimes sit and glare longingly at those at the office that don’t have to support the older versions of IE. Imagine the glory and wonder of using Flexbox! To be able to roll around in align-items: center, revel in justify-content and delight in flex width. But, alas. It is not so, using flexbox for corporate oriented (especially SharePoint) styling is still some years off.

But I still have to vertically align things all the time. And that’s the reason for this post. Yes, it is true. I have started to use tables to get things to where I want them. Not actual tables, but virtual ones with div and span elements with display table. And I have come to, maybe not love it, but at least rather like it. It sort of works, if used correctly. There is a learning curve, an especially steep one if your brain is telling you to RUN AWAY. But with some time and determination you too can get there.

The problem to solve

Typically we’re talking about an icon that should be centered vertically to a text of unspecified height. Position: absolute won’t help you here, nor will margin top, since the height varies. What I used to do was use a background image with background-position: center. But these days we have to take retina screens into account. Begone blurry images!

But what about svg?

says you.

Yes, that would also be nice, but legacy systems prevent me from using that (long story, SharePoint is to blame). Also I would like to utilize icon libraries like FontAwesome.

The solution

Use table layout for this! The wrapping parent gets:

1
2
display: table;
padding: 10px; // For good looks

And then every child element gets

1
2
display: table-cell;
vertical-align: middle;

And no padding or margin top or bottom on the children, that messes everything up. Both child elements now becomes as high as the highest of them, and the content is placed in the vertical middle. Magic.

Want a clearer picture and try it out yourself? Here’s a plunker where you can do that.

So you tried this and there’s no magic?

The problem with this method is that it’s mad hard to “debug”. It’s insanely difficult to understand what’s wrong when something is off in the aligning. Try to remove all set height, line-height and margins and paddings on the child elements, as well as all other positioning styling (relative or absolute).

Nothing new under the sun

Yes, people have of course used this before, but that doesn’t mean everyone has, or that it isn’t news to someone. After all, until recently I didn’t use it and I spend a fairly large amount of my day arguing with CSS.

If you came to this post because we met at the Geek Girl Meetup, I’m so, so glad to see you. My goal was to inspire at least one person to actually try this out and get started with creating webapps by using Yeoman. It would make me feel really warm inside that I actually inspired someone to get started and try it out.

If you just stumbled in here by yourself, this is a post where I list the few and wonderously simple steps to generate a webapp to use for web development using Yeoman.

The steps

Install nodejs

Go to nodejs.org to download Node. Install it on your computer.

Test Node Package manager

Open your terminal (if you’re on a Mac), or your Power Shell if you’re on a Windows. Don’t know how to do this? Don’t worry, here is a great guide for Mac, and here is a great guide for Windows. You don’t need to know more than how to open it, and think of how cool you’ll look now!

With it open, type in

1
npm

Press enter. That’s it. You get a response that says stuff about how npm works. Moving on to the next step!

Install Git

Git needs to be installed in order to get some other things (Bower) working. Go to http://git-scm.com/downloads, download and install.

Install Yeoman

Yeoman is a program that helps you generate skeletons for your future web page or web application. Install it by typing this into your terminal/Power Shell:

1
npm install -g yo

This installs Yeoman on your computer (the -g part makes sure it’s installed everwhere). If you want to know more about how Yeoman works, this is a good place to start.

Install Bower

Bower helps you out with dependencies such as jQuery or Bootstrap or something else. Install it by typing:

1
npm install -g bower

Interested in what you can do with Bower, visit this guide.

Install Grunt

Grunt is what you call a “task runner”. It does tasks for you, like minifying CSS and JavaScript, or compiling Sass, or copying files from one place to another. Let’s install it by typing:

1
npm install -g grunt-cli

If you want more about what Grunt can do for you, go this guide, which explains it nicely.

Install Webapp generator

Now we’re at the last installation step, which is to install one of Yeomans’ generators, namely Webapp. It’s a generator that creates a bunch of files and folders containing all you need for your future project. Type

1
npm install -g generator-webapp

Webapp is the most general generator from Yeoman, but there are a bunch of others.

Create project folder

Now it’s time to create a folder where your project will live. Either create it in finder/explorer, or look cool by doing it in your teminal/Power Shell:

1
mkdir my-fancy-project

Then you have to move your terminal/Poweer Shell to your new folder. This is done by the command cd which stands for ‘change directory’. Type in:

1
cd my-fancy-project

Generate your project

Now the time has come for a project to be created, finally! And all you have to do is type:

1
yo webapp

And after you pressed enter all the files and folders and content will be created, it’s almost like magic.

Start up your web application in the browser

Once it’s finished, type

1
grunt serve

This starts up the task manager Grunt, which opens your browser, with the web site on it.

Then what?

So that’s all you need to do, now you can start creating. That’s not always easy, but it’s loads more fun than writing boring HTML and creating folders and so on, which all these steps have done for you.

I made the Counting Down site by using a generator from Yeoman. You can add some JavaScript to the generated JavaScript file to create something that tells time, or just says hello, or shows flash cards from your anatomy class at school, or something entirely different.

It would make me happy if you mailed me at stinaqv@gmail.com with questions, tales or thoughts about this. I hope that you try it out and see where it takes you.

I’m starting to get slightly nervous now. Decided that I was going to hold a talk at Geek Girl Meetup Oresund and now I have to do it. Since I seems to be unable to hold lectures and lessons without knowing monumentally more than what I’m actually going to talk about, I have quite a lot of work to do.

I have named the talk “How to go from idea to webapp in 15 minutes”, or something like it, and it is about how to set up grunt, SASS, and JavaScript structure in under 20 minutes. And also, the will be pictures of kittens, probably.

I hope someone shows up and I hope I do great and that the kittens are cute.

Problem: You have styles you want for regular screens, and styles you want for retina screens. Mostly images with different sizes, but sometimes font sizes or widths.

I was faced with this recently and got annoyed at the amount of repeating I had to do. First it’s the fuck ugly syntax of the media queries, then it’s the browser compatibility, and then I have to repeat it all over my Sass document for different screen sizes and everything else that can change

Queue trying to build a handy mixin for it all

This is what I came up with:

@mixin retinaspecific($maxwidth, $attribute, $value) {
    @media
        only screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: $maxwidth),
        only screen and ( min--moz-device-pixel-ratio: 2) and (max-width: $maxwidth),
        only screen and ( -o-min-device-pixel-ratio: 2/1) and (max-width: $maxwidth),
        only screen and ( min-device-pixel-ratio: 2) and (max-width: $maxwidth),
        only screen and ( min-resolution: 192dpi) and (max-width: $maxwidth),
        only screen and ( min-resolution: 2dppx) and (max-width: $maxwidth) {
        #{$attribute}: $value;
    }
}

It’s a mixin that takes three arguments. The first ($maxwidth) handles the actual media query and when the rule should be applied. The second ($attribute) handles what attribute is affected. Here you put font-size, background-image or something like it. And the last one handles the value of the attribute, so what size should the font be, or what background image do you want.

It is quite handy! Just use it whenever you want something styled for a retina screen. Since you can reuse it for all attributes and screen sizes, it shourtens the code you have to write quite a lot.

Using it like this:

@include retinaspecific(500px, min-width, 55px);

Will compile to this:

@media 
    only screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 500px),
    only screen and (min--moz-device-pixel-ratio: 2) and (max-width: 500px),
    only screen and (-o-min-device-pixel-ratio: 2 / 1) and (max-width: 500px),
    only screen and (min-device-pixel-ratio: 2) and (max-width: 500px),
    only screen and (min-resolution: 192dpi) and (max-width: 500px),
    only screen and (min-resolution: 2dppx) and (max-width: 500px) {
        min-width: 55px;
}

I used it for my app Counting Down and as far as I know it doesn’t work in LESS