Category: CSS

More shape-outside (troubleshooting) tips

There are some excellent resources on the CSS property shape-outside that should be studied to understand how it works and how you can use it. This new property now enjoys a lot of browser support and it’s something you can generally apply without worrying about how it looks in non-supported environments, so it’s good to use in production now.

When I started playing around with it I did stumble over a couple of things. I figured I would write down some additional tidbits and tips that aren’t covered explicitly elsewhere. First, do read up on shape-outside on MDN, from the wonderful Sara Soueidan at ListApart and Robin Rendle’s working with shapes article on css-tricks.com. Michelle Barker also has a nice article on experimental layouts using shape-outside, including advice on using inverted shape techniques.

Tips

Floated elements only

Shape-outside can only be applied on floated elements right now, so knowing how floats work is very important to be able to understand how to implement an effect using shape-outside. There are some limitations and quirks that you might bump against. And the way the shape area is implemented might surprise you.

How to get a shape to fill the height of its parent

not with position absolute

One of the first things I’ve tried to implement was a shape that expands along with the content and this proved to be pretty difficult. Shapes can be defined using relative units, but a floated element can’t be given dimensions which respond to the content around it. If you want your shape to be the length of the content it’s supposed to affect, tough luck getting it to expand and shrink in an elegant way. One way to get a floated element to stretch in either direction to match the height of the container’s contents is to use position absolute and set top/bottom/left or right, but position absolute will also destroy the intended behaviour, as the contents won’t flow around it.

probably not with height: 100% either

Setting a proportional height such as height 100% will only work if the height of the container has been set. In most cases this won’t be workable, if you’re working with an unpredictable length of content it’s unlikely you want to set an absolute height on its container element and using a relative height is not enough.

using javascript

I’ve found no way to make a floated element fit its container with css only, so the alternative is some javascript. Here’s an example I wrote that adds height attributes to elements inline. It recalculates automatically when the viewport is resized.

How the shape area relates to the bounding box of the floated element

The shape’s locus of influence sits within the dimensions of the bounding box of the floated element. The shape you define can never expand beyond the dimensions you specify on the floated element. So your shape may have dimensions that are larger than the floated element, that shape will simply clip at the edges of your floated element.

Floats, shape-outside and clipping

A floated element may escape beyond its container (demo). There are different ways to deal with that behaviour. You can force the container to expand to fit the floated element. You do that by setting overflow: hidden on the container. You can also let the float clip, while hiding it by stacking it behind subsequent elements using z-index.

The shape-area does not observe your stacking instructions!

The clipped portion of your shape, i.e. the part that exceeds the container it’s floated in can’t be stacked below other elements. And this can be a bit of a surprise. As text in subsequent elements even outside the container of your floated element may wrap around your shape-area. Here is a demo to demonstrate. For further reading it’s worth reading up on w3.org.

floated element using shape-outside interacting with adjacent elements
This green floated element is higher than its container and it breaches adjacent containers. The ellipse shape it defines continues to affect the contents of elements down the page. (The handles you see are from the Firefox dev tools control).
shape-outside interacting with elements with a higher z-index
The orange div here has a z-index of 2, which obscures the green floated element’s contents and background color, but you see that its own contents is still wrapping around the ellipse shape.

You can use pseudo :before and pseudo :after to created floated elements

The cool thing is that floated elements can be pseudo elements, which in turn can have shape-outside defined on them. That means you won’t have to add a physical element in your markup to insert your shape effect.

You can use a transparent png to define the shape-area

Just note that when you specify the url in your shape-outside property, it’s not actually going to display your image, it’s going to compute the area of the image and redirect words and elements around the resulting shape. To have the image display you have to do so separately.

(Check here if you have issues getting transparent pngs to work as a shape)

Firefox has a very nifty shape editor in its developer tools console

To access it, look at the rules panel while you’ve selected the floated element. For the shape-outside property you’ll see an icon which you can click on. It will highlight the shape in the browser while letting you manipulate the points.

 

Shape-outside and transparent PNGs troubleshooting tips

Shape-outside is a revelatory addition to CSS, allowing designers to creatively bend text around shapes and since Firefox version 62 it enjoys over 80% browser support. There are several excellent resources on applying shape-outside but not that many articles demo the ability to use transparent PNGs. I was having trouble getting it to work initially, but there’s a couple of reasons why the effect might not show. Here are some tips:

  • Did you check that your element has width/height set?
  • Did you apply float to the element?
  • Did you double check that the PNG you are using uses transparency?
  • Is your PNG much larger than than the element itself?

If the effect still isn’t showing, maybe there is an issue with how the PNG is being fetched. Try replacing the url with a data URI instead and see if that makes a difference. If it now works, there is an issue fetching the PNG from your image url. For that see the notes on CORS and  Shape-outside urls on MDSN.

An Exploration Of Website Layout Patterns

A blog commenter I came across recently was praising the merits of sticking to the tried and tested layout of a header, title, post content with a sidebar on the left or right and a footer at the bottom. It was a commentary on the complex layout options found in bulky commercial themes and the flexibility marketed in the various page builder plugins. Sticking to a basic layout is simple and it works but also a bit dull. Truth is, most of the popular sites have very unique layout patterns.

Currently I’m working on a theme framework for my WordPress projects and I was looking for a good system to support a large variety of layout use cases. So I went to do a bit of research and explored a sampling of popular sites and attempted to note down broad layout patterns in varying detail.

I looked at sites in a wide browser window, just to maximize the layout possibilities. What struck me was that there’s quite a variety of layouts. Optimal layout has a lot to do with the type of content on offer and so it’s interesting to see the different approaches. There are some interesting trends finding their way into these high traffic sites. Grids are very popular across the board, some sites make decent use of infinite scrolling (pinterest), linear layouts without sidebars have become very popular too (see Paypal’s new home page). Content heavy sites still make heavy use of sidebars, but the way they are implemented is quite diverse. Also interesting is seeing sites utilize a separate sidebar starting at the comments section under an article (SBNation and Techcrunch do that).

I decided to share some notes I took below. It’s not meant to be exhaustive or completely accurate, just an impression really. Thought I might as well publish it as a quasi-interesting work note.

layout-variations-on-the-web

 

CSS3 PIE 2 and WordPress integration

A new release of CSS3 Pie has been announced, PIE 2.0 Beta 1. It comes with lots of goodies such as a bit of background size support and rgba support in simple linear gradients and box-shadow rendering. For a more precise break down check out the release post, as not all of the newly supported features work in all contexts.

I had written a method for integrating version 1 of PIE into WordPress for plugin and theme authors but as the new version of PIE uses a different load method, I found it useful to post an updated method. The main difference with PIE 2.0 is that the htc file is very small now (<2kB) and it will conditionally load javascript files based on the version of IE. The advantages are that you can load these js files from any server (such as a CDN) and now that unnecessary code is left out, the download will be a lot smaller. Caching works a lot better out of the box as well.

The method I’ve suggested for PIE remains mostly the same except we now have to add in a custom load path so PIE.htc will load the javascript files from the right location. By default, PIE will look for the javascript files in the same folder PIE.htc is located. Because the implementation I’m detailing here doesn’t point straight to the PIE.htc file, the script won’t be able to find the javascript by itself. A custom path to the javascript files can be specified with a pie specific css rule called ‘-pie-load-path’. You could hardcode this rule in your stylesheet and be done with it, but it’s more flexible to do this dynamically with an inline style element.

note: It’s important to note that the implementation I’m detailing here is geared toward plugin and theme authors looking to package PIE with their distribution. If you’re just trying to get PIE working on your own sites it’s easier to move the PIE files to the root folder of the domain, in a folder right off the root or in the wp-content folder. You can just follow the normal instructions and forgo with having to set a custom load path and simply point directly to PIE.htc.

The benefits to the method I’m using are the same as before:

  • avoid having to hardcode the path to PIE.htc in your css
  • avoid having to mess with php in your stylesheets to insert the path to PIE.htc dynamically
  • avoid having to move PIE.htc to the domain root or elsewhere
  • avoid having to mess with relative urls when pointing to PIE, just use an easy to remember absolute url
  • a short url and easy to remember url for referring to the PIE file in your css

The Implementation

Normally, when inserting scripts and styles, you would want to hook into wp_enqueue_scripts and use a WordPress function such a wp_add_inline_style for inline style elements. In this case, we only want to have the browser read the style element if it’s Internet Explorer, so we want to wrap our style element in the familiar conditional code to target IE only. For that reason, I opted to go for a more straight forward approach and attach the function that prints this code straight in the head section through the wp_head hook. Another benefit to this is that we can place this code before other stylesheets are loaded. (I haven’t tested to see if this makes an actual difference in terms of how fast PIE applies its styling, but it makes sense on paper)

if( ! function_exists( 'css_pie' ) ) {
	function css_pie ( $vars ) {
		$vars[] = 'pie';
		return $vars;
	}
	add_filter( 'query_vars' , 'css_pie');
}

if( ! function_exists( 'load_pie' ) ) {
	function load_pie() {
		if ( get_query_var( 'pie' ) == "true" ) {
			header( 'Content-type: text/x-component' );
			header( 'Cache-Control: max-age=2592000' );
			readfile( get_stylesheet_directory() . '/inc/PIE/PIE.htc' );    
			// Stop WordPress from loading further
			exit;
		}
	}
	add_action( 'template_redirect', 'load_pie' );
}

if( ! function_exists( 'set_pie_path' ) ) {
	function set_pie_path(){
		$piepath = get_stylesheet_directory_uri() . '/inc/PIE/';
		?>
		<!--[if IE]>
		<style type="text/css">
		html { -pie-load-path:"<?php echo $piepath;?>";}                
		</style>
                <![endif]-->
		<?php    
	}
	add_action( 'wp_head', 'set_pie_path', 7 ); // just before stylesheets are printed
}

To adjust this code to your project, keep in mind where your PIE files can be found. In this example I created a folder called PIE in the includes folder of my theme directory. You’ll need a different url path if you’re including PIE from within a plugin. If you are loading PIE within your theme – which is probably going to be the case most of the time – you may want to set the paths to look for the parent theme instead of checking the child theme. In that case you can replace get_stylesheet_directory() and get_stylesheet_directory_uri() with get_template_directory() and get_template_directory_uri() respectively.

Applying PIE in your css is as easy as cake, just use:

behavior: url(?pie=true);

 

Transparent PNGs and IE6: Some False Hope

While working on achieving the best possible crossbrowser compatible experience, going as far back as Internet Explorer 6, I was excited to see a site called Tinypng.org. It’s aim is to create a smaller version of your png assets while preserving transparency as it converts the file from 24 bit to 8 bit. It does these things very well and it even works in IE6. Yes you can have working transparent PNGs in IE6, as long as they are of the 8 bit variety. But there’s a gotcha. The transparency it supports is binary alpha, or in other words, each pixel will be fully transparent or fully non-transparent. Yes, that’s just like your basic GIF image.

To get an opaque png working in IE6 you could try the alpha image loader filter, but frankly, I think it gives you more trouble than it really is worth. But hey, it’s 2012 and global IE6 usage is down to around 1% or less in most Western countries. For the majority of websites, IE6 shouldn’t be an issue anymore.

How To Specify Top Level Selectors Within Mixins With LESSphp

While creating mixins for cool snippets of reusable css, I had trouble figuring out a way to set styles for top level elements while inside a mixin. To illustrate, let’s look at this example from CSS tricks which uses pseudo elements to create a bar that breaks out a container to touch both sides of the screen.

section {
   width: 50%;
   margin: 0 auto;
}
h2 {
   position: relative;
   background: black;
}
h2:before, h2:after {
   content: '';
   position: absolute;
   background: black;  /* Match the background */
   top: 0;
   bottom: 0;
   width: 9999px;   /* some huge width */
}
h2:before {
   right: 100%;
}
h2:after {
   left: 100%;
}
html, body {
    overflow-x: hidden;
}

It’s a pretty neat effect. The question is, how would you turn this into a mixin, so you can use it on an element of your choice?

Most likely you’ll start out with something like this:

.extended-bar() {
     position: relative;
     background: black;
   &:before, &:after {
     content: '';
     position: absolute;
     background: black;  /* Match the background */
     top: 0;
     bottom: 0;
     width: 9999px;   /* some huge width */
   }
   &:before {
     right: 100%;
   }
   &:after {
     left: 100%;
   }
}

You could then drop this in where you like it. Let’s for example apply it to a h3 heading:

h3 {
   .extended-bar;
}

But we’re missing something. The effect relies on a parent container to have a width. In this example  it’s the section element. We can reasonably assume that this will be specified in the normal course of the stylesheet anyway.

The property applied to the html and body element though is really important (it prevents a horizontal scrollbar from displaying). How do we put that in there? We can’t just drop this into the mixin because it will be prefixed by whatever element the mixin is applied to, in this case the h3 selector. A problem.

So I looked at a different technique as a workaround and arrived at cool feature called selector expressions. This functionality allows you to dynamically create a selector based on a given parameter. With this we can create a mixin that we can call from the top level and let it generate our desired selector dynamically.

.extended-bar( @selector ) {
  html, body {
    overflow-x: hidden;
  }
 }
 (e (@selector ) {
   position: relative;
   background: black; 

 &:before, &:after {
   content: '';
   position: absolute;
   background: black;  /* Match the background */
   top: 0;
   bottom: 0;
   width: 9999px;   /* some huge width */
 }
 &:before {
   right: 100%;
 }
 &:after {
   left: 100%;
 }

}

To create our effect we just need to call it with the desired selector:

.extended-bar( h2 )

This solution will print out the styles like the original css example. This mixin is not the best piece of less to actually use in the wild. In the event that you call the mixin multiple times ugly style duplication issues arise.

I am working on a CSS post processing tool that remedies style duplication issues, if you’re interested, sign up to my newsletter list below and I’ll let you know when I release it.
[yks-mailchimp-list id=”85fd778c18″]

Organizing Your WordPress Theme’s CSS

Stylesheet files can get ridiculously long. The Twenty Eleven theme has over 2500 lines  of css (unminified). That can be a pain if you’re trying to make significant adjustments to a theme. Quite a few theme frameworks take a more modular approach to css and separate their CSS into different files. That is a big improvement, but it does come at a cost. The more files you import, the more requests you’re making to the server. Secondly, persons who have to work with the CSS now need to figure out what files contain what style specifications. Thirdly, the built-in editor in the administration screen is not that user-friendly when you have to hunt down specific files instead of editing the basic style.css file.

I use the LESS language these days which makes CSS management heaps easier. You can have multiple less files and you can generate a single css file from those files. The question now becomes: what’s a good way to organize the less files?

There are quite a few different ways to organize your CSS logically and the problem here is that you can easily run into overlap situations. Do you put your CSS targeted for small screens in a separate file, or do put them in the file that targets those specific elements? If we have a file dedicated to structure as well as for different content elements, from widgets, to post-formats, how do we make the separations? If you have CSS for your images, do you include them with the file that handles galleries, or do you put them in the file that addresses media elements. These are just a few examples.

So far, I haven’t come up with a system that has perfect clarity. I don’t think it’s possible. The conclusion I’ve come to is that you have to do what’s most in alignment with your workflow. If you have to figure out what file to make an adjustment, there should be no more than 2 obvious candidates to choose from, and they should be obvious. If I want to make an alignment adjustment to a widget area for tablet screens, I don’t want to have to check a widgets file, a structure file, an alignments file and a responsive file.

I’ve been taking advantage of the LESSphp library to get around some of these file organization dilemmas. You can drop in your media queries like you would do a mixin. That way you can keep all the CSS relating to a group of elements organized in one logical area. There is one downside at the moment: the output isn’t perfect yet since it can cause your CSS to contain a lot of redundant data (similar media query statements aren’t grouped automatically into a single media query). I’m working on a css post-processor (the Flawless Styles Compiler plugin) to fix this and make the output cleaner and lighter in general.

Here’s my current file organization setup for those that are interested:

  • variables.less
  • mixins.less
  • reset.less
  • structure.less
  • typography.less
  • general.less
  • navigation.less
  • header-area.less
  • footer-area.less
  • page-templates.less
  • post-formats.less
  • media-elements.less (images, video, audio etc)
  • form-elements.less (input elements, search box, contact forms etc)
  • ui-elements.less (button’s etc)
  • sliders.less
  • gallery.less
  • comments.less
  • states.less
  • print.less
  • widgets.less
  • misc.less

Potential tweaks to this organization? I’m thinking further separation of individual page templates and post formats. Post types can fall into either page template or post format category but it might make sense to have a dedicated file for post types as well.

LESS and convenient file organization make things a lot easier. But I want managing a site’s design to be even easier and this is why I’m building a plugin called ‘Flawless Styles Compiler’ which will take CSS development for WordPress to a whole new level.

Beautify Your LESS Stylesheets With Indentation Etc

After a couple of cut and paste jobs I had some LESS files with really ugly looking indentation. After a fruitless search for a tool to auto-format my LESS stylesheets, I decided to build a quick and dirty php script to do the job.

I’m a notepad++ user and while it comes with some nice auto-formatting functions that provide the proper indentation and such, it chokes on LESS stylesheets. I’ve tried other editors such as Crunch and SublimeText but they don’t provide auto-formatting for LESS either, not even through a plugin package.

There are quite a few online code beautifiers that do a fine job with formatting ordinary CSS, but present them with nested styles and parametric functions and they all turn to mush. What else is there to try? Well I decided it wouldn’t be that hard to code a php script and here it is:

[php]<?php

/* Quick and dirty way to clean up LESS stylesheets
* !Warning! don’t run this on a live webserver online, use it on localhost or adapt the code to make it safer
* This code doesn’t reflect perfect coding practices, it’s just a quick and dirty script to quickly format Less files.
* The clean_up_less function will sort out indentation, trim whitespaces and add whitespace
* If you have a missing or extra bracket somewhere, you will have bad results.
* The code only adds tabs for indentation and removes/adds whitespace so your Less won’t get borked
*/

?>
<form method=”post”>
<input type=”submit” value=”format less” />
<textarea name=”nonformatted” id=”nonformatted” style=”display: block; position:relative;float:left;width: 45%;min-height: 400px; height: 100%;”></textarea>
<textarea name=”formatted” id=”formatted” style=”display: block; width: 45%;position:relative;float:left;min-height: 400px; height: 100%;”><?php
if ( $_POST[“nonformatted”] ){
echo clean_up_less( $_POST[“nonformatted”] );
}
?></textarea>
</form>
<?php
function clean_up_less( $css ){
$lines = explode( “n”, $css );
$currentnest = 0;
foreach($lines as $line){
$newline = trim ( $line );
$newline = str_replace( ‘{‘, ‘ {‘, $newline); // make sure left bracket always is preceed by whitespace
$newline = preg_replace(‘/ss+/’, ‘ ‘, $newline); //remove extraneous whitespace
$pos = strpos ( $line, ‘}’ );
if ( $pos > -1 ){
$currentnest = $currentnest – 1;
}
$tabs = ”;
$i = 0;
while( $i < $currentnest ){
$tabs .= “t”;
$i++;
}
if( strpos( $line, ‘{‘ ) ){
$currentnest++;
}
if ($currentnest > 0 ){
$newcss .= $tabs.$newline.”n”;
} else {
$newcss .= $newline.”n”;
}
}
return $newcss;
}
?>[/php]

It’s not a world class script but it got the job done for me. If you’re running a local server setup you can quite easily plug in this script and beautify your LESS in the blink of an eye.

Got a better way to do it? Did you find a tool or plugin that can format LESS stylesheets? Please let it know in the comments because I’d love to know.

*update* http://www.prettyprinter.de/module.php?name=PrettyPrinter does a pretty good job at this too