One of the biggest pains in a web development, apart from vertical centering (except for inside a table cell), is a W3C box model, which doesn't include padding and borders into the width. You can't use "padding: 10px; width: 100%;", because the element will be 20px wider, than the parent element.
Fortunately, in CSS3 there's box-sizing property. Default value is "content-box", which behaves as the W3C model, but if you set the property to "border-box", it solves the problem with padding/border and the width. I noticed almost all major CSS frameworks adds this property to every element, like this:
* {
box-sizing: border-box;
}
In the past (in terms of internet it was more like an ancient history), comparable pain was an old Internet Explorer's own box model concept, which included border and padding into the width (so basically like "box-sizing: border-box"), whilst Netscape Navigator (ancestor of Firefox) followed W3C standards.
Side note: I don't like Microsoft doing stuff his own way, but this was actually better, than standards.
Anyway, when designing a web page you had to hack this differences, usually by using two divs instead of one. Outer div had the 100% width, inner div had the padding and border. Width of the inner div has been calculated automatically. And this wasn't the worst hack at the time, webdesign was often close to a witchcraft :-)
Microsoft added "standard mode" (now we call it "almost standard") into IE6, but kept so called "quirks mode" default and switching of those modes has been guided by DOCTYPE. This changed with IE7, where W3C mode became default (according to my test in IE11 dev tools).
Now, if you use HTML5 doctype <!DOCTYPE html>, you will get the best results - so use it always!
And about the vertical centering, you can use display property with CSS2.1 value "table-cell", so even div can behave like a table cell, with working vertical-align: middle, like this:
.verticenter {
display: table-cell;
vertical-align: middle;
}
But don't forget you should to make it a proper table! So parent div will have "display: table-row;" and it's parent div will have "display: table;". Happy styling!
Saturday, April 11, 2015
Tuesday, April 7, 2015
WPF styles
I knew WPF styles are powerful, but the XML code is sooo long that I've never felt the need to expand my app with tons of new lines. Until now.
Recently I moved to dark skins everywhere. In PhpStorm I switched to Dracula theme with modified Zenburn schema, Geany has Zenburn schema as well, for Thunderbird and Firefox I found magnificent DeepDark theme and earlier this year I updated Quiky editor to Monokai-like colors.
I finally decided to darker even the viewer part of Quiky. Panels were easy, it's possible to set colors as variables (e.g. <SolidColorBrush x:Key="GuiBackgroundBrushColor" Color="#666666" /> and then <Setter Property="Foreground" Value="{DynamicResource GuiForegroundBrushColor}"/>). The troubles came with a TreeView.
I spent few minutes googling how-to and I found a StackOverflow a solved question about styling TreeView items. I also wanted the whole line to be selected, not only the text background.
It took me a while to get the solution working, because honestly I didn't want to understand all that, felt like I won't need it. But I had to, so ultimately I even tweaked it a little. And because I learned what's going on (restyling is often recreating controls, all in XML), I decided to style the whole app.
My next concern were scrollbars. I wanted Apple-like and I found a solution as well. It also needed some tweaking, but it looks quite good. I added hover effect on the thumb (slider), so it fades in and out.
Finally I styled buttons, textboxes and comboboxes, but it would need a little more time (some finishing touches), so I did only some basic stuff. I want some subtle effects (animations), but I didn't like anything I made so far.
I'm satisfied, for now:
Recently I moved to dark skins everywhere. In PhpStorm I switched to Dracula theme with modified Zenburn schema, Geany has Zenburn schema as well, for Thunderbird and Firefox I found magnificent DeepDark theme and earlier this year I updated Quiky editor to Monokai-like colors.
I finally decided to darker even the viewer part of Quiky. Panels were easy, it's possible to set colors as variables (e.g. <SolidColorBrush x:Key="GuiBackgroundBrushColor" Color="#666666" /> and then <Setter Property="Foreground" Value="{DynamicResource GuiForegroundBrushColor}"/>). The troubles came with a TreeView.
I spent few minutes googling how-to and I found a StackOverflow a solved question about styling TreeView items. I also wanted the whole line to be selected, not only the text background.
It took me a while to get the solution working, because honestly I didn't want to understand all that, felt like I won't need it. But I had to, so ultimately I even tweaked it a little. And because I learned what's going on (restyling is often recreating controls, all in XML), I decided to style the whole app.
My next concern were scrollbars. I wanted Apple-like and I found a solution as well. It also needed some tweaking, but it looks quite good. I added hover effect on the thumb (slider), so it fades in and out.
Finally I styled buttons, textboxes and comboboxes, but it would need a little more time (some finishing touches), so I did only some basic stuff. I want some subtle effects (animations), but I didn't like anything I made so far.
I'm satisfied, for now:
![]() | |
| Before redesign |
![]() |
| After redesign |
Wednesday, March 25, 2015
March 2015
I often find some piece of nice software and I like to read about "behind the scenes" about it, when a blog is available. Then it makes me slightly sad, when I find out the latest post is from 2 years ago. And yesterday I was like: "Hey, that's MY blog as well!" :)
Then I thought about it. It's quite hard to do a job and then to blog about it. Even I'd like to, but I can't promise I'll do better in the future. Self made publicity steals time from the object of publicity, more time blogging means less time coding.
On the other hand - who says I have to write a War and Piece every time? I have about 20 unfinished posts in stock, so now it might be a right time to slice them into smaller finished ones.
Anyway. What I've been up to with QetriX? Finishing the concept. I did another iteration, quite finished Java version after PHP has been usable. From that point I understood the PHP version is wrong yet again, so now I'm reeingineering and refactoring.
The finished will be even more consistent among platforms. I discarded "index" script as the entry point and introduced "app" and "file". For PHP it's handled by .htaccess, for Java it's handled by web.xml.
The WebApp will contain a HTML generator (basically Components with Converters to HTML) for internal WebView, which fits perfectly into the QetriX idea. I love this!
Finally I settled to separate data from users and data from geodata. Coordinates and user info in data (= mostly in Particles) will be still supported, but not recommended.
I finished my tracker app for iOS, which works well and replaced Moves for good. I was really crossed that Moves is not working offline and unfortunately the biggest test for the tracker so far, my short trip to Dubai, failed, because I screwed up a final update and the app crashed on startup. But never mind.
Last month I exported my first worksheed from my time tracker as well, works like a charm. I'm thinking of merging it together with the tracker, so it will know when I arrived to work and when I left.
I would like to write "and that's about it" now, but it isn't. But I'll get into it in some of the next posts.
Then I thought about it. It's quite hard to do a job and then to blog about it. Even I'd like to, but I can't promise I'll do better in the future. Self made publicity steals time from the object of publicity, more time blogging means less time coding.
On the other hand - who says I have to write a War and Piece every time? I have about 20 unfinished posts in stock, so now it might be a right time to slice them into smaller finished ones.
Anyway. What I've been up to with QetriX? Finishing the concept. I did another iteration, quite finished Java version after PHP has been usable. From that point I understood the PHP version is wrong yet again, so now I'm reeingineering and refactoring.
The finished will be even more consistent among platforms. I discarded "index" script as the entry point and introduced "app" and "file". For PHP it's handled by .htaccess, for Java it's handled by web.xml.
The WebApp will contain a HTML generator (basically Components with Converters to HTML) for internal WebView, which fits perfectly into the QetriX idea. I love this!
Finally I settled to separate data from users and data from geodata. Coordinates and user info in data (= mostly in Particles) will be still supported, but not recommended.
I finished my tracker app for iOS, which works well and replaced Moves for good. I was really crossed that Moves is not working offline and unfortunately the biggest test for the tracker so far, my short trip to Dubai, failed, because I screwed up a final update and the app crashed on startup. But never mind.
Last month I exported my first worksheed from my time tracker as well, works like a charm. I'm thinking of merging it together with the tracker, so it will know when I arrived to work and when I left.
I would like to write "and that's about it" now, but it isn't. But I'll get into it in some of the next posts.
Monday, February 2, 2015
All about performance
My key request for the new system was good performance, no matter how achieved. I ended up with a single data table and a lot of cache around it. In Particle Database I have a search cache and coordinate cache in MySQL and each entity in JSON file. Entity contains all own attributes and relations, plus top 5 foreign relations. Each foreign relation type to each entity type has own JSON file cache.
There are several situations, where indexes can't be used. If you perform LIKE wildcard search, only col LIKE 'abc%' or col LIKE 'a%c%' use indexes, but col LIKE '%abc%' and col LIKE %abc' and col LIKE col2 don't - because of the way B-Tree index is designed. Or if you have to do a string operation before comparsion, e.g. UPPER(col) LIKE 'ABC', all rows has to be loaded. In such case consider adding a new column, with cached upper-case values.
This way I tried the best approach for zero padding or type casting from string to number.
Encourage browser caching for static resources, using Expires header, Last-Modified date or ETags in the HTTP header.
Use different URL root for your resources, because browsers allows 4 to 8 simultaneous requests per domain, so using different domain will increase. And it will be cookie free (cookies are sent even for CSS or images). There are public CDN resources for widely used stuff, like jQuery or Bootstrap.
Minimized file can be even smaller using GZip compression, widely supported by browsers. This way you can 58 kB file compress to 12 kB. But always keep the original file and never edit the minified one. The only downside is debug on production server, as you can`t get a proper line number, where problem occured, becuse everything may be on a single line.
I know JS libraries/frameworks, like jQuery or Dojo, are really handy and I like to use them, but only if I can't do it with pure ("Vanilla") JS. And it's valid for CSS boilerplate frameworks as well (Bootstrap, Foundation). Because it's universal, it contains a lot of code you never use, but browser parses it on every page load. If you want to use it, remove all unnecessary stuff, if you can (there are tools for that). jQuery is 85 kB of code just to make another code works. Using JS lib only for element addressing is pure blasphemy and I don't even want to comment using more than one JS library on single page.
Next step is reducing HTTP request count. I merged all JS into single file, the same with CSS. Then I created so calloed "CSS sprite" - all graphis (pictures), where possible, migrate into single PNG file ("spritesheet") and instead whole CSS background, specify just backgroud-position. You have to do it cleverly, because of mixing repeating (backgrounds) and non-repeating images (icons). I can't really recommend data URIs, because it can't be cached and therefore you will download it over and over again. The only time it was extremely hand was when I got the picture already as base64 from REST web service.
One of the most difficult steps was to minimize HTML code. Some browsers (with blue "E" in logo ;-) in some previous (but still used) versions can't handle innerHTML manipulations without another DIV, so every time I want to use element.innerHTML = someText, I have to specifiy extra inner DIV. There are certain situations, when the HTML code is really bloated and I can't do anything about it. If you write the code in HTML5, you can at least get rid of the ending slash on non-pair HTML tags, like INPUT or IMG.
It's also good to check for invalid stuff over time. You may not use the widget or page layout any more, but linked scripts and CSS may still be out there. Also check for unused JS functions/methods and unused CSS classes.
Always use proper image format - JPEG (JPG) for photos and PNG for everything else. Because JPEG is lossy format, you can tweak quality (from 0 being crappiest but smallest to 100 being best, but large) to achieve best ratio between quality and file size. You may need just to re-save JPEG photos, even it slightly impacts quality - but often greatly lowers file size. For both formats there are online and downloadable optimization tools, that help lower their file size.
Many effects, achieved by images in the past, are nowadays possible just by CSS effects. They are significantly smaller, of course, but increases CPU time required for their rendering. A lot of shadows, gradients and transitions may kill performance on (low end = mostly used) mobile devices.
Consider resizing large photos, especially for mobile websites. On the other hand, because of different dpi, you may need double the size of graphics elements based on image to look good or hi-res displays. The best option is to use SVG, but like CSS, it may also affect performance if not used wisely.
You may not load the content (photo, video...), if it's not yet visible. This technique is called "lazy loading". You can detect it's vertical position and compare it to the scrollbar position. When they meet, you can trigger download.
Try not to use webfonts on mobile version. The only sensible use there is for icon fonts, which are often better choice, than image icons - if you want different icon color on :active or even :hover, you just change CSS color property, not the whole image.
Social network buttons can be trouble too, especially when they are loaded directly from that site (with Like counters etc). If you want them, make it yourself and add them to your spritesheet / icon font.
MySQL
Indexing of MySQL tables is crucial, too little is bad and too much is bad as well. Best practice is to work tightly with DESCRIBE command and index columns used in JOIN and WHERE clauses.There are several situations, where indexes can't be used. If you perform LIKE wildcard search, only col LIKE 'abc%' or col LIKE 'a%c%' use indexes, but col LIKE '%abc%' and col LIKE %abc' and col LIKE col2 don't - because of the way B-Tree index is designed. Or if you have to do a string operation before comparsion, e.g. UPPER(col) LIKE 'ABC', all rows has to be loaded. In such case consider adding a new column, with cached upper-case values.
PHP
I always checked what approach in PHP would be the fastest, especially for functionality in iteration (loop). I used simple script with a timer:function test1()
{
$t = microtime();
while ($i < 1000) {
// HERE TESTED CODE
++$i;
}
return microtime() - $t;
}
This way I tried the best approach for zero padding or type casting from string to number.
Server
Activate GZIP compression.Encourage browser caching for static resources, using Expires header, Last-Modified date or ETags in the HTTP header.
Use different URL root for your resources, because browsers allows 4 to 8 simultaneous requests per domain, so using different domain will increase. And it will be cookie free (cookies are sent even for CSS or images). There are public CDN resources for widely used stuff, like jQuery or Bootstrap.
Client side
I also deeply enhanced client side for speed. First thing was to minimize external files - CSS and JS. Minimized code strips out all unnecessary stuff, like whitespaces or comments. Deep minification also rewrites variable and method names to contain as few characters as possible. Every byte counts.Minimized file can be even smaller using GZip compression, widely supported by browsers. This way you can 58 kB file compress to 12 kB. But always keep the original file and never edit the minified one. The only downside is debug on production server, as you can`t get a proper line number, where problem occured, becuse everything may be on a single line.
I know JS libraries/frameworks, like jQuery or Dojo, are really handy and I like to use them, but only if I can't do it with pure ("Vanilla") JS. And it's valid for CSS boilerplate frameworks as well (Bootstrap, Foundation). Because it's universal, it contains a lot of code you never use, but browser parses it on every page load. If you want to use it, remove all unnecessary stuff, if you can (there are tools for that). jQuery is 85 kB of code just to make another code works. Using JS lib only for element addressing is pure blasphemy and I don't even want to comment using more than one JS library on single page.
Next step is reducing HTTP request count. I merged all JS into single file, the same with CSS. Then I created so calloed "CSS sprite" - all graphis (pictures), where possible, migrate into single PNG file ("spritesheet") and instead whole CSS background, specify just backgroud-position. You have to do it cleverly, because of mixing repeating (backgrounds) and non-repeating images (icons). I can't really recommend data URIs, because it can't be cached and therefore you will download it over and over again. The only time it was extremely hand was when I got the picture already as base64 from REST web service.
One of the most difficult steps was to minimize HTML code. Some browsers (with blue "E" in logo ;-) in some previous (but still used) versions can't handle innerHTML manipulations without another DIV, so every time I want to use element.innerHTML = someText, I have to specifiy extra inner DIV. There are certain situations, when the HTML code is really bloated and I can't do anything about it. If you write the code in HTML5, you can at least get rid of the ending slash on non-pair HTML tags, like INPUT or IMG.
It's also good to check for invalid stuff over time. You may not use the widget or page layout any more, but linked scripts and CSS may still be out there. Also check for unused JS functions/methods and unused CSS classes.
Webdesign
Responsive webdesign is neat, but you have to transfer all the code thru slow mobile connections (LTE or even 3G is still a dream in a lot of countries). Much better is to create lite mobile version. Don't immitate specific GUI (like iOS), it will look ridiculous on other platforms or after a platform redesign!Always use proper image format - JPEG (JPG) for photos and PNG for everything else. Because JPEG is lossy format, you can tweak quality (from 0 being crappiest but smallest to 100 being best, but large) to achieve best ratio between quality and file size. You may need just to re-save JPEG photos, even it slightly impacts quality - but often greatly lowers file size. For both formats there are online and downloadable optimization tools, that help lower their file size.
Many effects, achieved by images in the past, are nowadays possible just by CSS effects. They are significantly smaller, of course, but increases CPU time required for their rendering. A lot of shadows, gradients and transitions may kill performance on (low end = mostly used) mobile devices.
Consider resizing large photos, especially for mobile websites. On the other hand, because of different dpi, you may need double the size of graphics elements based on image to look good or hi-res displays. The best option is to use SVG, but like CSS, it may also affect performance if not used wisely.
You may not load the content (photo, video...), if it's not yet visible. This technique is called "lazy loading". You can detect it's vertical position and compare it to the scrollbar position. When they meet, you can trigger download.
Try not to use webfonts on mobile version. The only sensible use there is for icon fonts, which are often better choice, than image icons - if you want different icon color on :active or even :hover, you just change CSS color property, not the whole image.
Social network buttons can be trouble too, especially when they are loaded directly from that site (with Like counters etc). If you want them, make it yourself and add them to your spritesheet / icon font.
Conclusion
Optimize your web for optimal performance is not easy task. It may feel it's better to start from scratch, but who says you have to adopt all of it? Try this and that now, but next time you build a new site, try to use as much as possible. Not only it will be faster for your readers or visitors, but you will decrease server load as a bonus. If you host your site in the cloud, it means you can reduce required hardware and lower the cost.
Subscribe to:
Posts (Atom)

