CSS

Drupal 8 custom throbber

Replace the default ajax progress with a fullscreen overlay CSS spinner.

.ajax-progress,
.ajax-progress-throbber,
.ajax-progress-fullscreen {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  -webkit-border-radius: 0;
  border-radius: 0;
  opacity: 1;
  background: rgba(255, 255, 255, 0.8);
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999999;
  overflow: hidden;
  text-indent: -99999em;
}

.ajax-progress-throbber:before,
.ajax-progress-fullscreen:before {
  content: " ";
  display: block;
  width: 120px;
  height: 120px;
  -webkit-animation: spin 0.8s infinite linear;
  animation: spin 0.8s infinite linear;
  border-radius: 120px;
  border-width: 10px;
  border-style: solid;
  border-color: #D6232F transparent #D6232F transparent;
  overflow: hidden;
  text-indent: -99999em;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

@-webkit-keyframes spin {
  to {
    transform: rotate(360deg); 
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

See demo

CSS proportional box and vertical align

Proportional box:

.box {
    width: 100%;
    height: 0;
    padding-top: 56.25%; /* 16:9 */
}

16:9 ⇔ 9/16=0.5625 ⇒ 0.5625*100=56.25%

Vertical alignment 1:

<div class="valign">
    <div class="valign-inner">
       Vertically aligned content.
    </div>
</div>
.valign {
    display: table;
    table-layout: fixed;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

.valign-inner {
    display: table-cell;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    vertical-align: middle;
}

Vertical alignment 2:

.valign {
    display: flex;
    align-items: center;
    justify-content: center;
}

.valign-inner {
    flex: 1;
}

Proportional box with background image and vertically centered content:

<div class="box" style="background-image: url('path/to/image');">
    <div class="box-inner">
        <div class="valign">
            <div class="valign-inner">
               Vertically aligned content.
            </div>
        </div>
    </div>
</div>
.box {
    position: relative;
    width: 100%;
    height: 0;
    padding-top: 56.25%; /* 16:9 */
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
}

.box-inner {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    text-align: center;
}

.valign {
    display: table;
    table-layout: fixed;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

.valign-inner {
    display: table-cell;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    vertical-align: middle;
}

Simple HTML5 placeholders fallback for IE9 and older

I hoped I will never hear about IE9 and its lack of support for the placeholder attribute, … I had high hopes.

I’ve boiled a simple fallback, late in the evening and in a rush, using IE conditional comments for browser detection.

<!--[if IE 8 ]>    <html class="ie8 lt-ie10"> <![endif]-->
<!--[if IE 9 ]>    <html class="ie9 lt-ie10"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html><!--<![endif]-->
$(document).ready(function() {

	// HTML5 placeholders fallback for IE9 and older
	if ($('html').hasClass('lt-ie10')) {

		// add the placeholder text as value
		$('textarea, input:text').each(function() {
			$(this).attr('value', $(this).attr('placeholder'));
		});

		// clear form fields on focus
		$('textarea, input:text').on('focus click', function(){
			if (this.value == this.defaultValue) {
			this.value = '';
			}
		}).on('blur', function(){
			if (this.value == '') {
			this.value = this.defaultValue;
			}
		});
	}

});

CSS target elements by partial class or ID name

This can simply be achieved using attribute selectors.

div[attr^="elem"]

// Matches any “div” with an “attr” attribute that begins with “elem”.

div[attr$="elem"]

// Matches any “div” with an “attr” attribute that ends with “elem”.

div[attr*="elem"]

// Matches any “div” with an “attr” attribute that contains the substring “elem”.

div[attr|='elem']

// Matches any “div” with an “attr” attribute that starts with “elem” and may continue with a dash (ex. “elem-string”).

Ex. target a “form” with the id=”login-[ID]-form” (where [ID] is a generated form ID)

form[id^="login"]
// or
form[id^="login"][id$="form"]
// or
form[id*="login"][id*="-form"]
// or
div[id|='login']

CSS propeller

Just for fun!

See demo CSS3 Keyframe Animation Propeller

<html>
  <head>
    <title>CSS3 Propeller</title>
  </head>
  <body>
    <div class="propeller"></div>
  </body>
</html>
.propeller {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  
  width: 0px;
  height: 0px;
  border-width: 200px;
  border-style: solid;
  border-color: #fff #00f #fff #00f;
  border-radius: 50%;

  -webkit-animation-duration: 0.2s;
  -moz-animation-duration: 0.2s;
  -o-animation-duration: 0.2s;
  animation-duration: 0.2s;

  -webkit-animation-name: rotateCircle;
  -moz-animation-name: rotateCircle;
  -o-animation-name: rotateCircle;
  animation-name: rotateCircle;

  -webkit-animation-iteration-count: infinite;
  -moz-animation-iteration-count: infinite;
  -o-animation-iteration-count: infinite;
  animation-iteration-count: infinite;

  -webkit-animation-timing-function: linear;
  -moz-animation-timing-function: linear;
  -o-animation-timing-function: linear;
  animation-timing-function: linear;
}

@-webkit-keyframes rotateCircle {
  from {
    transform: rotate(0deg); 
  }

  to {
    transform: rotate(360deg);
  }
}

@-moz-keyframes rotateCircle {
  from {
    transform: rotate(0deg); 
  }

  to {
    transform: rotate(360deg);
  }
}

@-o-keyframes rotateCircle {
  from {
    transform: rotate(0deg); 
  }

  to {
    transform: rotate(360deg);
  }
}

@keyframes rotateCircle {
  from {
    transform: rotate(0deg); 
  }

  to {
    transform: rotate(360deg);
  }
}

More on CSS animations you can find here:
https://developer.mozilla.org/en-US/docs/Web/CSS/animation
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations
https://css-tricks.com/almanac/properties/a/animation
https://css-tricks.com/snippets/css/keyframe-animation-syntax

SASS sqrt function

There are times when a method of calculating the square root of a number is needed in SASS; for example calculating the sides of a right triangle, when the length of the hypotenuse is known, or the other way around, for a triangle mixin.

SASS provides us with some basic number operations, and there are libraries which implement more advanced math functions, but I wanted to experiment.

Using Newton’s method algorithm from Wikipedia, transcribed in SCSS scripting, we get the following:

@function sqrt($r) {
  $x0: 1; // initial value
  $solution: false;

  @for $i from 1 through 10 {
    @if abs(2 * $x0) < 0,00000000000001 { // Don't want to divide by a number smaller than this
      $solution: false;
    }

    $x1: $x0 - ($x0 * $x0 - abs($r)) / (2 * $x0) !global;

    @if ( abs($x1 - $x0) / abs($x1)) < 0,0000001 { // 7 digit accuracy is desired
      $solution: true;
    }

    $x0: $x1;
  }

  @if $solution == true {
    // If $r is negative, then the output will be multiplied with <a href="http://en.wikipedia.org/wiki/Imaginary_number">i = √-1</a>
    // (√xy = √x√y) => √-$r = √-1√$r
    @if $r < 0 {
      @return $x1 #{i};
    }
    @else {
      @return $x1;
    }
  }
  @else {
    @return "No solution";
  }
}

Which works, but looks too complicated.

We can simplify it into,

@function sqrt($r) {
  $x0: 1;
  $x1: $x0;

  @for $i from 1 through 10 {
    $x1: $x0 - ($x0 * $x0 - abs($r)) / (2 * $x0);
    $x0: $x1;
  }

  @return $x1;
}

Note: By default SASS computations are done with a precision of 5 decimals, if you need a higher precision use the “–precision N” (where N is the number of decimals) flag when compiling.

Slide out hamburger menu

It is known that the slide out menus ( or hamburger menus ) are the best way of making a menu usable for mobile.

This method uses jQuery in order to clone the markup of the desktop version menu, and make it slide out. Check out the demo.

<body>
	<div id="container">
		<div id="header">
			<div id="navigation">
				<ul>
					<li>
						<a href="#">Lorem Ipsum</a>
					</li>
					<li>
						<a href="#">Lorem Ipsum</a>
					</li>
				</ul>
			</div>
			<span id="toggle-menu">Menu</span>
		</div>
	</div>
</body>
$('#navigation').clone().prependTo('body').addClass('mobile-navigation').removeAttr('id');
$('div.mobile-navigation').prepend('<span class="close">Close</span>');

$('#toggle-menu').bind('click touch', function(){
	if( $('div.mobile-navigation').hasClass('open') ){
		$('div.mobile-navigation').animate({width: "0px"}, 300).removeClass('open');
		$('#container').animate({left: "0px"}, 300);
	} else {
		$('div.mobile-navigation').animate({width: "210px"}, 300).addClass('open');
		$('#container').animate({left: "-210px"}, 300);
	}
});

$('div.mobile-navigation span.close').bind('click touch', function(){
	$('div.mobile-navigation').animate({width: "0px"}, 300).removeClass('open');
	$('#container').animate({left: "0px"}, 300);
});
#container {
  position: relative;
  width: 100%;
}

.mobile-navigation {
  width: 0;
  height: 100%;
  overflow: hidden;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 200;
}

Check out demo.

Rudimentary text expander

There are jQuery plugins, like TextExpander, which work well with portions of text wrapped inside a single element (like a ‘<p>’ tag), but when it comes to collapse block elements, the animation is not so smooth.

Here is a very rudimentary (but working) solution for truncating sections of text paragraphs and adding a ‘read more’ button.

<div class="expandable">
    <div class="inner">
        <p>Some text ...</p>
        <p>Some text ...</p>
    </div>
</div>
.expandable .inner {
    overflow: hidden;
}
$('div.expandable > div.inner').each(function(){
	var expadable_height = $(this).height();
	var visible_lines = 42; //the height of the minimum visible lines of text in px
	$(this).css('height', visible_lines); 
	$(this).parent('div.expandable').append('<span class="see-more">See More</span>');
	
	var toggle = 0;
	$(this).siblings('.see-more').click(function(){
		if( toggle == 1 ){
			$(this).siblings('div.inner').animate({height: visible_lines}, 500);
			$(this).text('See More');
			toggle = 0;
		} else {
			$(this).siblings('div.inner').animate({height: expadable_height}, 500);
			$(this).text('See Less');
			toggle = 1;
		}
	});
});

Demo

Change the default throbber in Drupal 7

‘Throbber’ in Drupal is the animated loader ( found at  /misc/throbber.gif ), used to indicate Ajax progress.

If you want to change it evenly across your theme, don’t even think to just replace the ‘/misc/throbber.gif’, instead save your .gif file in your drupal theme, and in your theme’s .css file override drupal’s default CSS rules which style the ‘throbber’. This default CSS can be found ( but not edited ) at ‘/modules/system/system.base.css’, and you just have to copy them to your css file, as shown below.

Keep in mind that ‘throbber.gif’ is in fact a sprite image, which contains two states ( one static, used for idle state, and one animated used for progress ).

Add these in your theme’s .css, and tweak them accordingly to your animated loader :

/* these apply to auto-completing form fields */
html.js input.form-autocomplete {
  background-image: url(path-to-your/loader.gif); /* tweak this according to your gif */
  background-position: 100% 0px; /* tweak this according to your gif */
  background-repeat: no-repeat;
}
html.js input.throbbing {
  background-position: 100% -20px; /* tweak this according to your gif */
}

/* these apply to all ajax progresses */
.ajax-progress {
  display: inline-block;
  *display: inline;
  *zoom: 1;
}
.ajax-progress .throbber {
  background: transparent url(path-to-your/loader.gif) no-repeat 0px 0px; /* tweak this according to your gif */
  float: left;
  height: 20px; /* tweak this according to your gif */
  width: 20px; /* tweak this according to your gif */
  margin: 2px;
}

Custom select input

Using some jQuery and CSS you can make a cross-browser custom select (dropdown) box.

<div class="select-wrapper">
    <select>
        <option selected="selected" value="1">Option 1</option>
        <option value="2">Option 2</option>
        <option value="3">Option 3</option>
        <option value="4">Option 4</option>
        <option value="5">Option 5</option>
    </select>
</div>
.select-wrapper {
  position: relative;
  width: 215px;
  height: 30px;
  padding: 0 25px 0 0;
  margin: 0;
  border: 1px solid #0D5995;
  overflow: hidden;
  background: url(select-arrow.png) no-repeat right center transparent;
}

select {
  position: absolute;
  left: 0;
  top: 0;
  opacity : 0;
  width: 240px;
  height: 30px;
  padding: 5px 0;
  border: none;
  background: transparent !important;
  -webkit-appearance: none;
}

.select-wrapper span {
  display: block;
  width: 210px;
  height: 30px;
  line-height: 30px;
  padding: 0 0 0 5px;
}
$(document).ready(function() {
  $('select').after('<span>' + $('option:selected', this).text() + '</span>');
  
  $('select').click(function(event) {
    $(this).siblings('span').remove();
    $(this).after('<span>' + $('option:selected', this).text() + '</span>');
  });
})

See the demo.

Remove dashed outline of contextual links in drupal

Annoying dashed border ( which isn’t even a border, is an outline ) appears around the blocks when the “gear” edit link is hovered, but more annoying is when you want to hide some text by the old “text-indent: -9999em” method; then the annoying border stretches all the way to the left ( normally, cause of the ‘-9999em’ ).

A quick way to remove it:

.block.contextual-links-region-active {
	outline: 0;
}

Add repeating CSS selectors

Have you ever needed a way to style the elements of a set ( lets say 5 ) individually, but the same rules to be applied to other set ( of 5 ) ?

For example:

<div>
     <h4>first</h4>
     <p>lorem ipsum ...</p>
     <h4>second</h4>
     <h4>third</h4>
     <h4>forth</h4>
     <div>lorem ipsum ...</div>
     <h4>fifth</h4>
     <!-- here end our first set -->
     <h4>first</h4>
     <h4>second</h4>
     <h2>lorem ipsum ...</h2>
     <h4>third</h4>
     <span>lorem ipsum ...</span>
     <h4>forth</h4>
     <h4>fifth</h4>
     <!-- here end our 2nd set -->
</div>

and we want that the first h4 in the first set have same styles as the first h4 in the second and so on, of course our h4’s are not grouped, but they are scattered between other elements, and other h4’s can be added in the future.

If we have a way to distinguish our elements from the other then we can make a short script with jQuery to add classes.

For a group of five css classes that will repeat after a number ( for this example we took, n = 5 ), this means that our h4’s from 1 to 5 will have same classes with the h4’s from 6 to 10, and so on; for this we will use something that in math is called ‘modulo’, basically gives us the remaining of the division of two numbers, and as we can get the index of our element we can see which position has in our set ( in this case of 5 ).

$('div h4').each(function(index) {

	if(index%5 == 0){
		$(this).addClass('first');
	} else if(index%5 == 1){
		$(this).addClass('second');
	} else if(index%5 == 2){
		$(this).addClass('third');
	} else if(index%5 == 3){
		$(this).addClass('forth');
	} else if(index%5 == 4){
		$(this).addClass('fifth');
	}
});

the result would be:

<div>
     <h4 class="first">first</h4>
     <p>lorem ipsum ...</p>
     <h4 class="second">second</h4>
     <h4 class="third">third</h4>
     <h4 class="forth">forth</h4>
     <div>lorem ipsum ...</div>
     <h4 class="fifth">fifth</h4>
     <!-- here end our first set -->
     <h4 class="first">first</h4>
     <h4 class="second">second</h4>
     <h2>lorem ipsum ...</h2>
     <h4 class="third">third</h4>
     <span>lorem ipsum ...</span>
     <h4 class="forth">forth</h4>
     <h4 class="fifth">fifth</h4>
     <!-- here end our 2nd set -->
</div>

CSS3 for IE with PIE

PIE stands for “Progressive Internet Explorer”, and is capable to add support for the most useful, cool CSS3 features, to the old and grumpy internet explorer (6, 7 and 8), and make your life easier.

Look and this page ( http://www.antimath.info/demos/csspie/ ) in internet explorer, … border-radius, box-shadow, background gradient, …good bye images and useless markup, hello PIE.

.element {
   width: 250px;
   height: 150px;
   line-height: 150px;
   font-style: italic;
   text-align: center;

    border: 1px solid #999;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;

    -webkit-box-shadow: #444 0 0 10px;
    -moz-box-shadow: #444 0 0 10px;
    box-shadow: #444 0 0 10px;

    background: #CCC; /*non-CSS3 browsers will use this*/
    background: -webkit-gradient(linear, 0 0, 0 100%, from(#BEE224) to(#E9F648)); /*old webkit*/
    background: -webkit-linear-gradient(#BEE224, #E9F648); /*new webkit*/
    background: -moz-linear-gradient(#BEE224, #E9F648); /*gecko*/
    background: -ms-linear-gradient(#BEE224, #E9F648); /*IE10 preview*/
    background: -o-linear-gradient(#BEE224, #E9F648); /*opera 11.10+*/
    background: linear-gradient(#BEE224, #E9F648); /*future CSS3 browsers*/
    -pie-background: linear-gradient(#BEE224, #E9F648); /*PIE*/

    behavior: url(pathTo/PIE.htc);
}

CSS3 PIE supports:

  • border-radius
  • box-shadow
  • border-image
  • multiple background images
  • linear-gradient as background image

See more on css3pie.com

Float & margin

Hi,

I am sure you all know this, but i will make a short description anyway. It is about the code below:

<div id="container">
	<img style="display: block; float: left;" src="http://placehold.it/468x60" alt="" />
	<p class="element" style="margin-top: 30px;">
		Sed ut perspiciatis unde omnis ...
	</p>
</div>

an element containing a floated element and a block element wrapping around the float, but you want that the block element to be lower than the floated one, so you set a margin on the block element, but the floated one is pushed by the margin… annoying. ( ex. demo 1 ).  So the simplest solution is to set a padding of 1px on the same direction as the margin on the container.

<div id="container" style="padding-top: 1px;">
	<img style="display: block; float: left;" src="http://placehold.it/468x60" alt="" />
	<p class="element" style="margin-top: 30px;">
		Sed ut perspiciatis unde omnis ...
	</p>
</div>

see it on demo 2 .

CSS fixed background

Sometimes you will need to make a background image fixed ( not to scroll with the page ), that because you have a very large image that does not repeat, or you want to make something like an watermark, the solution is simple and is around for ages, all you have to do is use the CSS background-attachment property.

Background-attachment supports three values: scroll ( which is default ), fixed and inherit.

In most cases the fixed background is applied to the body element, but can be applied to any HTML element. Without further ado, … the CSS code.

body {
      background-image: url('path/to/background.jpg');
      background-repeat: no-repeat;
      background-attachment: fixed;
      background-position: center;
}

Below is the shorthand version .


body {
      background: url('path/to/background.jpg') no-repeat fixed center;
}

Here you have a demo.