diff --git a/css/fixedHeader.dataTables.scss b/css/fixedHeader.dataTables.scss
index 7a6185b..8781884 100644
--- a/css/fixedHeader.dataTables.scss
+++ b/css/fixedHeader.dataTables.scss
@@ -12,6 +12,7 @@ table.fixedHeader-floating.no-footer {
 table.fixedHeader-locked {
 	position: absolute !important;
 	background-color: white;
+	margin: 0 !important;
 }
 
 @media print {
diff --git a/js/dataTables.fixedHeader.js b/js/dataTables.fixedHeader.js
index e2ff12f..b1431f8 100644
--- a/js/dataTables.fixedHeader.js
+++ b/js/dataTables.fixedHeader.js
@@ -81,7 +81,9 @@ var FixedHeader = function ( dt, config ) {
 			tfootHeight: 0,
 			theadHeight: 0,
 			windowHeight: $(window).height(),
-			visible: true
+			visible: true,
+			scrollParentTop: 0,
+			scrollParentVisible: true
 		},
 		headerMode: null,
 		footerMode: null,
@@ -211,14 +213,21 @@ $.extend( FixedHeader.prototype, {
 		var that = this;
 		var dt = this.s.dt;
 
-		$(window)
-			.on( 'scroll'+this.s.namespace, function () {
-				that._scroll();
-			} )
-			.on( 'resize'+this.s.namespace, function () {
+		window.addEventListener('scroll',
+			function () {
+				if (that.c.relativeScroll) {
+				    that._positions();
+				    that._scroll();
+				}
+				else {
+				    that._scroll();
+				}
+			}, true);
+		window.addEventListener('resize',
+			function () {
 				that.s.position.windowHeight = $(window).height();
 				that.update();
-			} );
+			}, true);
 
 		var autoHeader = $('.fh-fixedHeader');
 		if ( ! this.c.headerOffset && autoHeader.length ) {
@@ -375,6 +384,32 @@ $.extend( FixedHeader.prototype, {
 			lastScrollLeft[ item ] = scrollLeft;
 		}
 	},
+	
+	/** 
+	 * Get the closest ancestor element that is scrollable. 
+	 * @private
+	 */ 
+	_scrollParent: function( element ) 
+	{
+		// based on the jQuery UI version of scrollParent()
+		// Copyright jQuery Foundation and other contributors
+		// Released under the MIT license.
+		var position = element.css( "position" ),
+			excludeStaticParent = position === "absolute",
+			overflowRegex = /(auto|scroll)/,
+			scrollParent = element.parents().filter( function() {
+				var parent = $( this );
+				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
+					return false;
+				}
+				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
+					parent.css( "overflow-x" ) );
+			} ).eq( 0 );
+
+		return position === "fixed" || !scrollParent.length ?
+			$( element[ 0 ].ownerDocument.body || document.body ) :
+			scrollParent;		
+	},
 
 	/**
 	 * Change from one display mode to another. Each fixed item can be in one
@@ -410,7 +445,6 @@ $.extend( FixedHeader.prototype, {
 				itemDom.placeholder.remove();
 				itemDom.placeholder = null;
 			}
-
 			this._unsize( item );
 
 			if ( item === 'header' ) {
@@ -425,6 +459,17 @@ $.extend( FixedHeader.prototype, {
 				itemDom.floating = null;
 			}
 		}
+		else if (mode === 'in-relative') {
+			// Remove the header from the read header and insert into a fixed
+			// positioned floating table clone
+			this._clone(item, forceChange);
+
+			itemDom.floating
+				.addClass('fixedHeader-locked')
+				.css('top', item === 'header' ? this.c[item + 'Offset'] + position.scrollParentTop : position.scrollParentTop + position.scrollParentHeight - position.tfootHeight - this.c[item + 'Offset'])
+				.css('left', position.left + 'px')
+				.css('width', position.width + 'px');
+		}
 		else if ( mode === 'in' ) {
 			// Remove the header from the read header and insert into a fixed
 			// positioned floating table clone
@@ -484,6 +529,7 @@ $.extend( FixedHeader.prototype, {
 		var position = this.s.position;
 		var dom = this.dom;
 		var tableNode = $(table.node());
+		var scrollParent = this._scrollParent(tableNode);
 
 		// Need to use the header and footer that are in the main table,
 		// regardless of if they are clones, since they hold the positions we
@@ -498,6 +544,9 @@ $.extend( FixedHeader.prototype, {
 		position.theadTop = thead.offset().top;
 		position.tbodyTop = tbody.offset().top;
 		position.theadHeight = position.tbodyTop - position.theadTop;
+		position.scrollParentTop = scrollParent.offset().top;
+		position.scrollParentVisible = scrollParent.is(':visible');
+		position.scrollParentHeight = scrollParent.outerHeight();
 
 		if ( tfoot.length ) {
 			position.tfootTop = tfoot.offset().top;
@@ -532,7 +581,10 @@ $.extend( FixedHeader.prototype, {
 		}
 
 		if ( this.c.header ) {
-			if ( ! position.visible || windowTop <= position.theadTop - this.c.headerOffset ) {
+			if ( this.c.relativeScroll && position.scrollParentVisible && position.theadTop - position.scrollParentTop < 0 ) {
+				headerMode = 'in-relative';
+			}
+			else if ( this.c.relativeScroll || ! position.visible || windowTop <= position.theadTop - this.c.headerOffset ) {
 				headerMode = 'in-place';
 			}
 			else if ( windowTop <= position.tfootTop - position.theadHeight - this.c.headerOffset ) {
@@ -549,8 +601,11 @@ $.extend( FixedHeader.prototype, {
 			this._horizontal( 'header', windowLeft );
 		}
 
-		if ( this.c.footer && this.dom.tfoot.length ) {
-			if ( ! position.visible || windowTop + position.windowHeight >= position.tfootBottom + this.c.footerOffset ) {
+		if (this.c.footer && this.dom.tfoot.length) {
+			if (this.c.relativeScroll && position.scrollParentVisible && position.tfootTop + position.tfootHeight > position.scrollParentTop + position.scrollParentHeight ) {
+				footerMode = 'in-relative';
+			}
+			else if ( this.c.relativeScroll || ! position.visible || windowTop + position.windowHeight >= position.tfootBottom + this.c.footerOffset ) {
 				footerMode = 'in-place';
 			}
 			else if ( position.windowHeight + windowTop > position.tbodyTop + position.tfootHeight + this.c.footerOffset ) {
@@ -586,7 +641,8 @@ FixedHeader.defaults = {
 	header: true,
 	footer: false,
 	headerOffset: 0,
-	footerOffset: 0
+	footerOffset: 0,
+	relativeScroll: 0
 };