Christian Heilmann

You are currently browsing the archives for the General category.

Archive for the ‘General’ Category

“Tweet this page” bookmarklet

Friday, August 23rd, 2019

Update: Moved the code to GitHub, make sure to drag it from there to your toolbars
Update: Fixed now for Chrome – there were some issues with whitespace :(

I like tweeting about pages I read in the following format:

"Headline"
https://example.com

Most “share this” buttons add a lot of cruft and if there is none, it is annoying having to copy the text first and then the URL into Twitter.

With this bookmarklet, you can highlight some text, click the bookmarklet and get a tweet window in a new tab. This is the source in a more readable manner – this will not work as a bookmarklet, see the link below instead!

(function(){
    n=getSelection().anchorNode;
    if(!n) {
        t = document.title;
    } else {
        t = n.nodeType === 3 ? n.data : n.innerText;
    }
    t = 'β€œ' + t.trim() + '”\n\n';
    window.open(
        `https://twitter.com/intent/tweet?text=
        ${encodeURIComponent(t)}
        ${document.location.href}`
    )
})();

Explanation:

  • We wrap the whole thing in an IIFE to avoid the browser redirecting to “javascript://”
  • We get the anchorNode of the current Selection object
  • If there is no highlighted text, we grab the document title
  • We check the type. If it’s a text node, we read the data, if it is HTML, we get the innerText
  • We remove any whitespace, add the quotes and some line breaks
  • We open a window (which these days results in a new tab) and call the Twitter intend with the text followed by two line breaks and the URL of the document.

That’s it. Drag the bookmarklet to the toolbar from the GitHub Demo page or check the code.

Voilà, happy tweeting.

Quick tip: using scrollIntoView() to show added elements to a container with overflow

Friday, August 9th, 2019

Often we want to have an interface where we have a container with overflow: scroll with a header and a footer.
One problem with that is that when we add new elements to the container, they do get added to the end of it but the element won’t show up before the user scrolls down.

In the past we hacked around this issue by comparing scrollHeight and clientHeight and setting the scrollTop property of the element. This is error prone and seems overly complicated.

Enter scrollIntoView. Using this API ensuring that a new element shows up to the user is as simple as calling it on the element itself.

Say we have the following list of characters and a button to add more of them.

HTML:

<div class="scrollbody">
    <ul>
        <li>Billy Butcher</li>
        <li>Hughie Campbell</li>
        <li>Mother's Milk</li>
        <li>The Frenchman</li>
  </ul>
</div> 
<button>Add new character</button>

In the CSS, we limit the body to scroll and set it to overflow.

.scrollbody {
  height: 6em;
  overflow: scroll;
}

With a bit of JavaScript, we can now add new characters every time we click the button:

let characters = ['The Female (of the Species)',
'Lieutenant Colonel Greg D. Mallory','The Legend','The Homelander',
'Black Noir','Queen Maeve','A-Train','The Deep','Jack from Jupiter',
'The Lamplighter','Starlight','Mister Marathon','Big Game',
'DogKnott','PopClaw','Blarney Cock','Whack Job',
'Gunpowder','Shout Out'];
 
let count = 0;
document.querySelector('button').addEventListener('click', (ev) => {
    if (count < characters.length) {
    let item = document.createElement('li');
    item.innerText = characters[count];
    document.querySelector('ul').appendChild(item);
    count = count + 1;
  }
  ev.preventDefault;
});

Now, if you try this out, you see that the new characters are in fact added, but not visible until you scroll down to them.

elements not showing until the user scrolls

That’s bad. To remedy this, you all you need to to is to add the scrollIntoView call after adding the new list item:

/* list of characters */
let count = 0;
document.querySelector('button').addEventListener('click', (ev) => {
    if (count < characters.length) {
    let item = document.createElement('li');
    item.innerText = characters[count];
    document.querySelector('ul').appendChild(item);
 
    item.scrollIntoView();
 
    count = count + 1;
  }
  ev.preventDefault;
});

scrollintoview showing the new elements

As an extra bonus, you can define the behaviour of the scroll to be smooth, which scrolls it in slowly and not as jarringly:

/* list of characters */
let count = 0;
document.querySelector('button').addEventListener('click', (ev) => {
    if (count < characters.length) {
    let item = document.createElement('li');
    item.innerText = characters[count];
    document.querySelector('ul').appendChild(item);
 
    item.scrollIntoView({behavior: 'smooth'});
 
    count = count + 1;
  }
  ev.preventDefault;
});

scrollintoview showing the new elements smoothly

Another reminder to keep looking into what’s in the standard these days rather than finding an old solution on StackOverFlow and keep too complex and not browser-optimised code alive.

Using CSS Custom attributes generated by JavaScript as a handover mechanism

Monday, July 29th, 2019

Update: there was a simplification about Custom Attributes being not supporting concatenation, thanks to Sime Vidas, Brian Kardell and Greg Whitworth to set this straight.

Over the last few iterations of CSS the boundaries between CSS and JavaScript started to blur. CSS was a static language, meant to define colours, look and feel, but not interactivity. You could use percentages in dimensions as sort of interactivity to the enviroment, but reacting to things changing was the job of JavaScript.

In the days of old HTML was there to give structure, CSS look and feel and JavaScript interactivity. Or, as I put it in my book in 2006, if your website were a movie HTML would be the script, CSS the cinematography and direction and JavaScript the special effects.

Nowadays, CSS is much more powerful. We have animations, transitions, calc() and much more flexible values like em, rem, vw, vh and more. We also have interactivity with pseudo selectors like hover, focus and states of interactive elements like buttons. We can even hack with checkboxes to write full games in pure CSS.

This is great! CSS aficionados are much more likely to have the patience and knowledge to make an animation or interaction look and behave exactly right. And CSS engines are responsible to perform well and not clobber the interactivity or battery life of the end user device. Browser makers can concentrate on optimising the engine rather than competing with the developer on who has the job to keep things smooth.

However, there are still boundaries and use cases where CSS is not enough, and you need JavaScript. Often these are about reading the current state of something happening to the browser window or an interaction not considered in the CSS spec.

Switching fully to JavaScript in that case feels like a knee-jerk reaction and it makes more sense to me to find a way for JavaScript and CSS to interact. JavaScript to read the value and to make it available to CSS in some way.

In the past, the only way to do that was to store classes on parent elements or remove classes when certain conditions were met. But with Custom Properties (“CSS variables”), it has become much easier to interact between JavaScript and CSS.

Custom properties allow you to set “variables” in CSS and use them later. For example:

::root {
  --company-blue: #369;
} 
 
h1 {
  color: var(--company-blue);
}

Custom properties are somehow limited and are not strings like they are in CSS preprocessors, so you can’t readily concatenate them Custom properties work differently to CSS variables in preprocessors. You can concatenate them, but there are limitations.

Thanks to Šime Vidas who showed a working demo on Twitter and to Brian Kardell pointing to the discussion on the CSS standards group .

As my colleague Greg Whitworth explains:

This is not actually true regarding custom props. The issue I think you’re primarily referring to are potential limitations in CSS in general, although I noticed that Sime already showed you that concatenation can be done but probably not in all scenarios where the only desire is to join actual strings (eg: “bar” calc(5 + 8) will get converted to \”foo\” calc(58) since it isn’t a valid calc and thus those are converted to a string as well but with escaped quotes. Everything within the variable is tokenized, so it can be a string or not depending on what the value is determined by the tokenizer. If it isn’t an invalid ident but isn’t one that can be matched, then it is converted to a string for use within CSS. Anything passed to JS is converted to a string. You can see this in this JSBin

The simplest way to alter CSS custom properties is to use calc() to multiply them with a value:

::root {
  --startwidth: 200;
} 
 
h1 {
  width: (var(--startwidth) * 1px);
}
h2 {
  width: (var(--startwidth) * 0.5px);
}

Now, as you can also define custom properties in JavaScript and add them to the styles collection of any element, this is a great way to only use JavaScript to read a value and leave the rest to CSS.

For example, if you wanted to know how far the document has scrolled, you can read this in JavaScript with an event handler and modify a CSS custom attribute:

JavaScript:

window.addEventListener('scroll', (e) => {
  document.body.style.setProperty('--scrolly', window.scrollY);
});

CSS:

h1 {
  position: fixed;
  width: calc(var(--scrolly)*1px);  
  background: #339;
}

You can try this out in this JSBin

By no means, this is a sensible demo, but I really like the fact that you can use JavaScript to reach where CSS can not, and still allow CSS to be the main driver and definition of interactivity.

Passing the mic

Friday, July 19th, 2019

I realised this week that I’ve been presenting at technology events for about 13 years now. The latter years were more or less dedicated to this and in some cases I covered 30 conferences a year.

Painting of me handing a microphone to a unicorn by Anke Mehlert
Painting by Anke Mehlert

It is exhausting, but also fun work. And it brings a lot of extra opportunities. Both professionally – making contacts, meetings with companies and exposure. And on a personal level – seeing the world, trying out new places, meeting friends.

At a certain stage of your career speaking at a lot of events is great. You get outside validation, you bring back insights to your company and you make a name for yourself. If you are your own boss or you make money by speaking and giving courses, it is of course a no-brainer.

There comes a time in your career though where being on the road all the time becomes counter productive. And, even worse, it can become a barrier for others to engage and make their mark. I don’t want to be in the way – I want to pave a path.

Currently, my job is to empower others and to aid communication between departments. And to help coach and mentor people to become more visible inside and outside the company. This takes a lot of time and effort. But it is also rewarding to use your experience to help others avoid mistakes you made and follow best practices you discovered.

This is why I will take a step back from covering lots of conferences myself. I am lucky to know a lot of people that I can help fill in the spots, so please keep the offers coming. I hope that there is a great opportunity to get other people to make your event a success. I will try especially hard to ensure that the people I connect you to:

  • are reliable and great at their job
  • are new and different faces with more diverse backgrounds than me
  • get all the help they need to ensure that working with you is easy
  • find their own unique voice and get channels to get heard

On a related note, I am impressed about some of the talent that cropped up the last years on the speaking circuit. There are a lot of incredible people to choose from and it is exciting to find and support new people with different ideas.

I understand that there are harsh realities of having to sell tickets for your event. I also understand that picking well-known headliners make this a safer bet. I hope that there is a middle ground though. I can help get new people on stage and amplify their presence at your event on my communication channels.

I’m seeing a lot of new talent burn out and people who have been around for ages becoming repetitive. I don’t want to become either and I’d prefer helping new voices get onto the circuit without burning out.

I’m looking forward to hearing from you and try to make that happen.

A worrying change in Open Source perception

Thursday, July 11th, 2019

Welcome Sign

Open Source is an excellent idea. It proved itself to create large and complex products with a shared workforce. It also allows products to follow the input and guidance from several players. Products don’t have to follow the demands of one company or their stakeholders. We build for the platform and the community, not for the next financial quarter.

Open source is a win for companies

For companies, open-sourcing their products means throwing them out to the scrutiny of the masses. People can contribute and build functionality the company hasn’t considered as it didn’t have that need. It is also an amazing opportunity for recruitment. Hiring people is hard and expensive. Cutting down on the time you need to ramp up a new employee is a real business benefit. Contributors are potential hires that already come with expert knowledge. It also is a way of ensuring quality. It is much harder to hide flawed code in plain sight than in a company internal repository.

Open source was my way in

I owe a lot of my career to Open Source and similar ideas like Creative Commons. That’s why I keep contributing and publishing. Without shared, open, free knowledge I wouldn’t have started working in web development. I couldn’t afford Frontpage and couldn’t find a cracked version. Instead, I downloaded the HTML and CSS spec from htmlhelp.com, opened a text editor and got on with it. This was a time where I didn’t have any connection at home, so I needed the docs offline.

Starting with this, I always felt that being open from the get-go is the right thing to do. To pay forward what I enjoyed, so to say.

When I started, releasing open source and using open source products was not the norm. As a professional, you had to use professional tools, and why give away for free when you could make people pay for it?

Open source is now front and center

Now, things look different. Open Source has become a household phenomenon and it is not a small group of enthusiasts any longer. It proved its value and the size of communities and open source releases exploded.

The problem with open source is the same problem with many other things: people. Communication is hard and considering what you say and do before doing it seems too much to ask. I was pretty naive about this in the beginning, too. I thought that people who share things would be nice and open people. I assumed a lot of them would also be in on my liberal views on other topics. I was wrong. People are people and they come with their flaws and ideas, biases and prejudices. They also come with their own issues they deal with. Those influence how they communicate with others.

And communication is the life blood of open source. It is not about writing some code, throwing it out there and letting people deal with it. It is about building a community around your code. It is about triaging requests and features to other people. This ensures the product can grow and prosper when you are bored of it or your company stops sponsoring it. It is about making it easy to share, to contribute, to use and to tweak to your needs.

This doesn’t gel with the image of the 10x developer and the drive for constant change and growth in the market. With lots of money and opportunity comes a lot of greed and arrogance. And thus, I keep hearing open source horror stories:

  • The lone, burned out OSS developer crushed by millions of requests without empathy for his time.
  • The arrogant coder who doesn’t bother with documentation and rejects any contribution. Giving anyone the feeling of not being good enough to use the code as they don’t understand it.
  • The first time contributor drowning in an avalanche of negative feedback.
  • The willing contributor shut out by overzealous code style and contribution guidelines
  • Possible contributors failing to help out because the product’s build process.
  • Fierce competition amongst contributors with personal attacks and automated rejection of pull requests.

The problem reaches far. Open Source is getting a reputation for being arrogant, aggressive, hard to get into. In its most extreme way it gets as far as recommending OSS being a Code of Conduct violation.

Disregarding the questionable argument in this case, there is a problem. It is frustrating to see that an open, collaborative idea like Open Source is getting a bad reputation. One of being exclusive and discouraging, no less. The very thing it set out to disrupt and change.

Open Source should bring a positive experience

I’ve worked in OSS for a long time, and I have on the whole had a great experience. I also am a white man who comes with a lot of credibility because of what I have done in the past. So my personal experience isn’t a universal one – by a long shot. I also had bad experiences. I’ve seen bigotry, arrogance and straight up malice. I’ve seen a lot of “play by those rules or leave the sandbox”. I’ve experienced far too much “are you better than this other person?”. I have experienced blocking by association and acts of other people affecting my reputation.

To a degree, things were much better before social media and the cult of the “persona”. Things were better before we compared each other by our number of products. And before our online presence became a way to land a job or get sponsorship.

It might be time to move away from releasing for the sake of visibility and go back to the more human and collaborative ideas of OSS. Hiring a person who shows great communication skills and empathy in their OSS dealings is a great investment for your company. These are the people who will power long-term growth and stability. Hiring the loudest, most active and aggressive people is a good short-term boost. The tech press and shareholders love a “go-getter” and “innovative and disruptive” story. Keeping those people happy in a company is a different task though companies often fail at.

The same applies to open source rockstars taking their product to the next level by starting a company around it. I’d love to see great stories around that. Instead I see explosive growth with a rushed human side of an employment relationship . It is tough moving from coder to employer and company owner. You need to deal with a lot of human issues and being all about the “hustle” is counterproductive to that.

Disregarding OSS as an amazing evolution of software development and great idea based on the actions of individuals is unfair and makes no sense. The very fact that the human interaction is part of the process is what makes open source interesting to me. Consider the opportunities:

  • You can learn a lot by contributing to open source
  • You can build on the work of others and learn a lot by seeing what they do
  • You can contribute from whereever and whenever
  • You can contribute in many ways: code, documentation, bugfixing, testing…
  • You learn about tools of the trade by contributing (build processes, linters, compilers…)

Of course, this comes with a flipside:

  • You work for free. This shouldn’t be a thing only for people who can afford to work for free. Open Source should be the thing to choose because you want to, not because you can afford to.
  • Your contributions’ currency is impact and feedback. If what you spent a lot of time on and effort results in a “this is not good enough” or “we don’t work this way here” you feel short-changed.
  • The quality of OSS products is so high, it can be daunting. It doesn’t help to feel inadequate when you look into contributing.
  • The sheer amount of contributions and length of communications around products is overwhelming.

That means we have to play by rules that run any human interaction. If we do that, Open Source might get a better reputation again.

  • Assuming that people know what you know is never a winning move. Explaining what you did to others makes you learn a lot. You learn by teaching. So, instead of throwing out code and hoping it prospers, taking an extra step and documenting it is a big winner. You can collaborate on that.
  • Moving our stance from “here is the solution for this” to a “here is a way to solve this, what do you think” invites participation.
  • It is OK not to have time for people’s contributions. It is not OK to snap at them or leave them hanging. A simple “sorry, I am not available right now” and asking for people to help you out with that is much better.
  • We should consider the setups of possible contributors. Adding to a JavaScript package shouldn’t mean downloading gigabytes of files or having a $3000 computer.
  • Personal attacks are never OK. This is about people working together. You have no idea what’s happening in the life of the person you try to “win” against. We all felt down and horrible at one time, remember that time and how you would feel is someone attacked you personally then.
  • Just because it is easy to contact someone, doesn’t mean it is OK to. Especially not when why you contact them isn’t related to the project.
  • Just because someone releases some code, they don’t automatically become your help desk. They put a lot of effort into releasing this, it is fair that you are expected to put some into using it. Instead of demanding better docs, why not document your journey and contribute it?
  • We all have different levels of skill. If someone isn’t as “good” as you are, doesn’t mean that person couldn’t become a great contributor with time. That won’t happen if you discourage them upfront. Yes, they may do things “wrong” from your point of view, but having someone else explain the why is more helpful than you venting.

I’d hate something that impactful and great being taken down by the actions of a few bad or deluded actors.