About

Member of the Board of the Polish Linux Users Group. Human rights in digital era hacktivist, Free Software advocate, privacy and anonimity evangelist; expert volunteer to the Panoptykon Foundation; co-organizer of SocHack social hackathons; charter member of the Warsaw Hackerspace; and Telecomix co-operator; biker, sailor.

Formerly President of the Board of the Polish Free and Open Source Software Foundation; CTO of BRAMA Mobile Technologies Laboratory on Warsaw University of Technology and a student at Philosophy Institute on Warsaw University.

Table of Contents

languages:
02.07.2016Dzień, w którym cenzura Sieci w Polsce stała się faktem pl 152 13.04.2015Needless haystacks en 151 12.03.2015e-Dockleracje pl 150 19.01.2015Ban on encryption is not about banning encryption en 149 13.01.2015Pochwała Copyleftu en pl 148 30.12.2014Zmiana klucza GPG en pl 147 18.12.2014Siła wyższa pl 146 04.12.2014Internet jednak bez pornografii? en pl 145 27.11.2014Zablokujmy wszystko! en pl 144 02.11.2014Pod rozwagę: ryśka prawo nieuniknionych konsekwencji en pl 143 09.09.2014Stop pedofilii en pl 142 22.06.2014Even with EME, Mozilla will become "the browser that can't" en 141 21.06.2014EuroDIG 2014 en pl 140 19.06.2014Haker w Radzie ds. Cyfryzacji en pl 139 30.05.2014Anonimowość w konsultacjach społecznych en pl 138 18.05.2014Czemu nie warto być piratem en pl 137 15.05.2014Mozilla, DRM i znaczenie en pl 136 14.05.2014Not-quite-good-enough-Mundial en 135 12.04.2014Nieodpowiedzialne nieujawnienie en pl 134 29.03.2014Ecologic, Ford i inwigilacja en pl 133 15.03.2014Otwórzmy edukację pl 132 10.03.2014Blurry line between private service and public infrastructure en 131 08.03.2014IM IN UR MINISTRY, CONSULTING UR INTERNETZ en pl 130 17.02.2014Szyfrowany VoIP, który działa en pl 129 11.02.2014A więc chcesz cenzurować Sieć... en pl 128 02.02.2014This is why we can't have nice IRC en 127 31.01.2014Prawie jak decentralizacja en pl 126 30.01.2014Żaden link nie jest nielegalny en pl 125 30.01.2014Debaty o prawie autorskim ciąg dalszy en pl 124 26.01.2014Neat HaCSS, or let's de-JS the Web a bit en 123 27.12.2013Information Account Number en 122 14.12.2013HaIPu en 121 20.11.2013Friends of TTIP and data protection in Brussels en 120 19.11.2013Jaki kraj tacy Piraci? en pl 119 05.11.2013A rude comment en 118 20.10.2013TEDx Warsaw Women i prywatność en pl 117 03.10.2013Reforma prawa autorskiego na CopyCamp 2013 en pl 116 22.09.2013Long-expected KMail2 rant en 115 18.09.2013Facebook for schools en 114 12.09.2013W którym wzywam posłów i posłanki Solidarnej Polski do zagwarantowania obywatelom Internetu wolnego od inwigilacji en pl 113 08.09.2013Complaintivism en 112 04.09.2013Sam sobie winien en pl 111 19.08.2013Kłamstwa, kłamstwa, i analityka en pl 110 27.07.2013Najkrótsza debata publiczna o cenzurze Internetu en pl 109 22.07.2013How information sharing uproots conservative business models en es 108 22.07.2013Dostępny jest markup wszystkich postów en pl 107 11.07.2013Kultura wolna i legalna pl 106 07.06.2013Internet nie jest problemem! en pl 105 05.06.2013Libel Culture en 104 17.05.2013Wojtuś Fatalista i wolność w Internecie pl 102 17.05.2013Czemu uważam, że licencje -ND są zbędne i szkodliwe en es pl 101 28.03.2013Wolność nasza codzienna pl 100 17.03.2013Nie wszystko korpo co o wolności w Internecie pl 99 15.03.2013♫ Odpowiadam na e-maile ♫ pl 98 11.02.2013Pierwsza rocznica europejskich protestów Anty-ACTA en pl 97 30.01.2013Nie ma haka na słabe dziennikarstwo? pl 96 30.01.2013Zwalczając czarny PR wokół OZE en pl 95 29.01.2013Jak skutecznie argumentować przeciw pomysłom cenzury Internetu en pl 94 20.11.2012Warunki brzegowe podmiotowości w dobie cyfrowej en pl 93 19.11.2012Blogosfera społecznościowa en pl 92 07.11.2012Fragmentacja nie jest zła en pl 91 02.11.2012SERVICES.TXT en pl 90 24.10.2012Apple finally jumped the shark en es 89 24.09.2012A mury runą... en es pl 88 24.09.2012Minister i Kultura pl 87 24.09.2012Melbourne CryptoParty video message en 86 16.09.2012O marynarskiej wrażliwości, czyli "niebo gwiaździste nade mną" en pl 85 22.08.2012Czarny PR wokół e-Podręczników en pl 84 15.08.2012Regaty utracone pl 83 24.07.2012Hypochristian Love en 82 24.07.2012Trochę nowego Dobra w layoucie en pl 81 17.07.2012Partia 2.0 en pl 80 16.07.2012Prawo autorskie po ACTA pl 79 13.07.2012Partia jako hack na systemie en pl 78 10.06.2012Are corporations dangerous only in collusion with governments? en 77 09.06.2012Proxies! Proxies everywhere! en 76 05.06.2012Automagiczna re-publikacja z Twittera na StatusNet en pl 75 18.05.2012TPSA/Orange i GIMP, czyli rzecz o 5-ciu użytkownikach en pl 74 16.05.2012Słowo o Warsztatach MAiC pl 73 15.04.2012Schowaj gadżeta pl 72 05.04.2012Perfect ToDo-oid en 71 27.03.2012Subiektywnie o Anty-ACTA en pl 70 25.03.2012O prawie autorskim w Budapeszcie en pl 69 23.03.2012Kościoła poczucie odpowiedzialności pl 68 20.03.2012Ucząc się Internetów en pl 67 19.03.2012Kościoła wiara w wiernych pl 66 29.02.2012Safari w Brukseli #1 - konferencja prasowa PE, posiedzenie ITRE en pl 65 21.02.2012Bo ACTA jest passé en pl 64 20.02.2012Tajemnica korespondencji po europejsku en pl 63 17.02.2012Premier Tusk w sprawie ACTA: myliłem się en pl 62 12.02.2012Anonimowi kontra Korponimowi en pl 61 10.02.2012Mieć ciastko i ściągnąć ciastko en pl 60 19.01.2012O ACTA znów w Kancelarii Premiera en pl 59 19.01.2012Wolni i Zjednoczeni en pl 58 16.01.2012Towarzystwo czuje się oszukane pl 57 10.01.2012Warunki Korzystania ze Świadczonych Usług en pl 56 05.01.2012Korporacyjny brak patriotyzmu en pl 55 04.01.2012Terrorystkoptery en pl 54 03.01.2012IceWeasel i prywatność en pl 53 28.12.2011Dobry Wujek Stal... Putin en pl 52 25.12.2011Useful Bash defaults done right en 51 21.12.2011Google Mail, czyli jak poczta staje się publikacją en pl 50 20.12.2011Occupy Gotham en pl 49 11.12.2011Copyfraud en pl 48 08.12.2011Multikino Wikipedia FAIL pl 47 27.11.2011Nie miejsce na pl 46 18.11.2011Cięcie jednostronne en pl 45 12.11.2011Tolerancja dla Kościoła pl 44 11.11.2011Użytkownicy i Obywatele en pl 43 30.10.2011Adhocracy i Net4Change en pl 42 18.10.2011Wojna z Radością en pl 41 16.10.2011Boli mnie w krzyżu pl 40 14.10.2011Technologiczne Samouwielbienie en pl 39 10.10.2011I Can Haz? pl 37 09.10.2011Cisza Wyborcza w Polsce en pl 38 03.10.2011Kibice i kampania pl 36 02.10.2011E-Podręczniki, Johnny Mnemonic, biznes i Sieć en pl 35 19.09.2011CC Global Streaming/Summit/Party pl 33 19.09.2011Czy jest coś takiego jak darmowe śniadanie? pl 34 12.09.2011Faktycznie Super pl 32 12.09.2011Diaspora-Based Comment System en 31 11.09.2011Konflikt wartości en pl 30 06.09.2011Wolność słowa to nie wolność od myślenia ani od krytyki pl 29 06.09.2011Prywatność i anonimowość w Sieci: kamyczek do ogródka en pl 28 04.09.2011O ostrożności w doborze słów en pl 27 03.09.2011W obronie QR Code pl 26 31.08.2011Stolica Nie Tak Święta pl 25 29.08.2011Of malware, hot steam, privacy, using one's brain and paedoparanoia en 24 29.08.2011Kragen Głośno Myśli en pl 23 18.08.2011Ból, blizny, dziewczyny i wiosła pl 22 07.08.2011Worst. Woodstock. Ever! pl 21 27.07.2011Siła woli, wydajność i rower en pl 20 19.07.2011Neo FreeRunner as a WiFi Soundcard en 19 10.07.2011Łikend z prawnikami en pl 18 09.07.2011Krok bliżej ideału en pl 17 04.07.2011Ryś Apostata en pl 16 28.06.2011KToF (Kolejna Tyrada o Facebooku) en pl 15 19.06.2011Wiara w priorytety pl 14 17.06.2011Spotkania ważne, spotkania przyjemne en pl 13 13.06.2011Ooops I en pl 12 30.05.2011Zabawy z Node.js en pl 11 25.05.2011Mozilla, Google i pasek adresu en pl 10 24.05.2011Na konferencji Sektor 3.0 en pl 9 23.05.2011Layout, CSS i RSS/Atom en pl 8 15.05.2011Startup Weekend Network Fun Fun Fun en 7 11.05.2011Nowy szef Bramy pl 6 10.05.2011World's Smallest Open Source Violin en pl 5 10.05.2011Po kolejnym spotkaniu w KPRM pl 4 08.05.2011Inspiracja na niedzielę pl 3 08.05.2011I horizontally the whole blog is that serious pl 2 07.05.2011Rysio ma braga en pl 1

Neat HaCSS, or let's de-JS the Web a bit

en | txt src
This entry does not seem to be available in the language of your browser; displaying in: en.

I like playing with technology, and I am particularly fond of playing with CSS/HTML. Not a big fan of JavaScript, though.

Don't get me wrong, I understand the utility of JavaScript, and the power of jQuery, I really do. However, I believe both are overused and abused — much, if not most, of functionality of "rich Internet applications" (also known simply as "websites"), including transitions, animations and whatnot, can be implemented in HTML5 and CSS3, with JS used for AJAX requests. The advantages being: faster processing, smoother animations, more readable code, better separation of logic and presentation.

Lately I dived into 2 side-projects that allowed me to dust-off my CSS-fu while making a point about how JS is becoming less and less needed as far as presentation layer is concerned.

Sailing in the Cloud

The first little project is Sailors.MD, a simple website for my sailors-and-medical-professionals friends.

The second one is implementing something ownCloud (that great little project letting everyone self-host their own "cloud") once had had that has later sadly been removed: sharing calendars and events publicly via a link with a token, or "link-sharing". I know of at least one potential deployment where that was a show-stopper. So after complaining for a few months I decided to implement it myself.

JS-in-a-dropbox

Sailors.MD was a no-brainer — a completely new project, a simple static website (that will grow, some day, but not just yet), no magical mumbo-jumbo, it just needs to look nice and be functional. No JS needed there, period!

Now, ownCloud, on the other hand... JavaScript. JavaScript everywhere! Hacking together a nice CSS/HTML-based interface for internal- and link-sharing of calendars and events, with JS providing just the bare minimum of AJAX-ness, stemmed from the frustration of debugging JavaScript-based interface.

The Problem Challenge

I wanted the interface to retain full functionality — including animations, showing/hiding parts of the interface, etc — even without JavaScript enabled. There were several things that needed implementing in pure CSS/HTML, which seemed hard without JS:

  • sections of the interface collapsing/extending upon click...
  • ...that are both directly linkable (i.e. via :target links), and persistent, allowing the user to interact with their contents and sub-sections;
  • showing some controls only when JS is enabled (a reverse-<noscript>, if you will);
  • elegant tooltips.
  • making element's appearance depend on the state of elements that follow it (remember, there is no CSS selector/operator for being a parent of, and the general sibling operator ~ is one-way only);

IMPOSSIBURU, right?

Let's hack!

First of all, some caveats: the below has not been tested on anything other than up-to-date versions of Firefox, Chromium and Rekonq (although IE 10+ should work). If you want to test them in anything else, be my guest, and I would love some feedback.

Secondly, all code in examples linked below is MIT-licensed (info in the examples themselves also).
Why at all? Because it's good practice to put some license on your (even simple) code so that the rules of the road are clear for other developers.
Why MIT? Well, I'm a staunt supporter of copyleft licenses like the AGPL, but this is just too small a thing, and bulding on too many great ideas of other people for me to feel comfortable with slapping AGPL on it.

Okay, enough of this, on with the code!

The Targetable Displayable

Making sections of a website show/collapse upon click is not that hard once you wrap your head around one beautifully simple hack: CSS Checkbox Tabs. But I wanted more:

  • being able to put the menu in a completely different place in code than the section (i.e. making a menu on top of the site, for example, with sections hidden within the bowels);
  • section targeting via :target, so that they are directly linkable by users.

The first one is rather easy once you get that you can put a <label> wherever you like in the document, regardless where the relevant checkbox is, as long as you set label's for attribute to checkboxes id.

Enabling :target was more tricky, tough: #target links do not set checkboxes :checked. Also, simply setting the id attribute on the section we want to have #target-linkable will not work: when the user clicks on a checkbox label to choose a different section, that one will still be expanded. Checkbox checking does not change the :target.

We could use:

:checked ~ :target {
  /*
   * rules making the :target collapsed
   */
}

...but that would not work for any situation where the :target element is before the :checked checkbox (the sibling operator ~ is one-way, remember?).

Hey, why not use just :target and forget about checkboxes? Well, then we wouldn't be able to have sub-sections, as there would be no way of saying "keep this section open even if the user chooses something else (the subsection)", and there is no "parent of" operator (so there is no way of saying "keep it open if any of its children is a :target). So:

  • :checked on checkboxes/radioboxes keeps state, and that's a biggie;
  • :target is directly linkable;
  • there is no way to connect the two.

Or is there? If the :target elements are always before the checkboxes, and these are always directly in front of the element that contains our expandable/contractable section, we might be able to get what we want. As long as all :target-able elements are in before of all relevant checkboxes. Tada!

What happens is:

  • from the get-go, no navigational checkbox/radiobox is checked;
  • if there is a #target, CSS rules for the right section container (based on the :target-ed hidden element) kick-in;
  • if now the user selects any sections, these are handled via checkboxes/radioboxes, and because the CSS :target rules for specific elements have the :not(:checked) sibling in chain required, :target rules stop working.

Magic!

Reverse-<noscript>

This seems a simple thing, right? Display elements when JavaScript is enabled gets tricky, however, when we're not allowed to use JS to display them. Now, we all know the <noscript> tag, but here we need to do something exactly opposite, and <script> won't do, as we're not going to use JS for that.

Of course we can always use a style-within-noscript:

<noscript>
 <style>
  #some-element {
   display:none;
  }
 </style>
</noscript>

...but that's inelegant. First of all, we're not supposed to have <style> tags within <body>, just as we're not supposed to have <noscript> within <head>. Secondly, we might want to have the element gone from the element tree when JS is disabled to pull off other hacks — like a Displayable above, for instance.

Turns out, we can put HTML comments inside <noscript>. Not just that: we can put the start of a comment (<!--) in a different <noscript> element than the end (-->). And apparently these will be interpreted as start/end HTML comment tags only if JS is disabled (they are within <noscript> elements, after all!). That means that this:

<noscript><!--</noscript>
  <div>SomeText</div>
<noscript>--></noscript>

...works like a reverse-<noscript> element. The <div> will get shown and included in the document tree only if JS is enabled. Here, check for yourselves by enabling and disabling JS in your browser and visiting the test case.

CSS Tooltips (aka TooltipCSS)

There is a myriad of tooltip JS/jQuery libraries, I'm not even going to link to them. Creating a HTML/CSS tooltip for a given element is also trivially easy (create a child element, use :hover on the parent to show it). Creating a tool-tip on any element matching a selector, without any additional HTML (no additional child elements, etc) — now this is a challenge!

What we need is a way to squeeze a new style-able element or two from any element in the DOM tree, without adding HTML, in pure CSS. Turns out that we have two: ::before and ::after. Yes, they are style-able, yes, we can put whatever we want in them. Unfortunately no, they can't have child nodes.

But, can we conveniently pass tooltip text to them without making a separate CSS rule for each? Yes, we can.

The content property conveniently accepts attr() form. So we can have a single style stanza saying for example:

 a[title]::before {
  content:attr("title")
 }

...and bam!, all <a> elements with the title attribute set will have ::before pseudo-element containing the value of title attribute.

We can style ::before just like any other element; by making the parent element (the one being "tooltiped", <a> in example above) relatively positioned and our ::before positioned absolutely we also have pretty good control how and where the tooltip appears.

Because pseudo-elements can't have child elements (all HTML inside will get rendered as text), it seems we can't have the small notch that makes a tooltip from a simple bubble. Ah, but we have ::after too, right! We can use it as our notch. If only there was a way to make a pure-CSS triangle from an element...

Add a bit of CSS transitions to the mix (I'm using rgba() background/border colours instead of opacity, as opacity for some reason makes elements move just a tiny, annoying bit), remember to hide the elements that constitute our new shiny tooltip so that they won't obstruct other elements (hint: use visibility:hidden instead of display:none, otherwise transitions won't work) — et voilà!

A CSS Tooltip appears! It's super-effective!

Depending on the state of the elements that follow

Well, that is simply impossible, as the ~ is one-way, and there is no parent of element. No, seriously.

But what we can do is play with the order of elements in the mix. Making all the elements (checkboxes, radio controls) the state we want to depend on precede the element we want to style depending on their state is the only way to go. The next logical step is to make that element be displayed in front of them.

That is no rocket surgery and can be achieved in a myriad of ways, for example by enclosing both the depending element and the source elements in a common container, set position: relative on the container and use position:absolute; top:0px on the element we want to be displayed first, like thus — and here's how it works.

With all their powers combined...

Dry examples are fun and informational (don't forget to test them with JavaScript disabled, too!), but only once you see it all working together the power of it all gets evident. So, enjoy. This example uses minimal JS to set checkboxes back and forth (in a way that is used in ownCloud calendar sharing interface), but nothing more. With JS disabled it should show the group's status ("all checked", "some checked", "none-checked").

All examples are valid HTML5 and valid CSS3. Of course, the code is on-line, you can grab it here. I'd love to hear your opinion, or see some other non-JS hacks.

Y U NO USE CSS?

There is some serious magic that can be done with CSS. Once we get an "is parent of" and a truly universal sibling selectors it will open up even more possibilities. JS seems convenient, but more and more people are looking with distrust (or disgust) at JS-infested websites, due to performance and privacy issues involved.

If something can be done in pure CSS/HTML, why not do it that way?