├── .gitignore ├── scss ├── app.scss └── includes │ ├── _affix.scss │ ├── _bootstrap.scss │ └── _variables.scss ├── html ├── layouts │ └── default.html ├── includes │ └── footerjavascripts.html └── pages │ └── index.html ├── bower.json ├── package.json ├── README.md ├── Gulpfile.js └── assets └── js └── affix.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | bower_components 3 | node_modules 4 | npm-debug.log 5 | _site 6 | .sass-cache 7 | -------------------------------------------------------------------------------- /scss/app.scss: -------------------------------------------------------------------------------- 1 | @import "includes/variables"; 2 | @import "includes/bootstrap"; 3 | @import "includes/affix"; 4 | -------------------------------------------------------------------------------- /scss/includes/_affix.scss: -------------------------------------------------------------------------------- 1 | .affix { 2 | position: fixed; 3 | top: $spacer-y; 4 | } 5 | .affix-bottom { 6 | position: absolute; 7 | } 8 | -------------------------------------------------------------------------------- /html/layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Bootstrap 4 project :: {{title}} 10 | 11 | 12 | 13 | 14 | 15 | {{> body}} 16 | {{> footerjavascripts}} 17 | 18 | 19 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "affix", 3 | "version": "0.0.1", 4 | "authors": [ 5 | "Bass Jobsen (http://bassjobsen.weblogs.fm)" 6 | ], 7 | "description": "Bootstrap 4 with jQuery Affix plugin. Powered by Panini, Sass and Gulp.", 8 | "main": "_site/index.html", 9 | "license": "MIT", 10 | "homepage": "https://github.com/bassjobsen/affix/", 11 | "dependencies": { 12 | "bootstrap": "4", 13 | "tether": "^1.1.2" 14 | }, 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "_site", 20 | "test", 21 | "tests" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /html/includes/footerjavascripts.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /html/pages/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Home 4 | --- 5 |
header
6 |
7 |
8 |
9 |
10 | Affixed sidebar 11 |
12 |
13 |
14 | Content 15 |
16 |
17 |
18 | 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "affix", 3 | "version": "0.0.1", 4 | "description": "Bootstrap 4 with jQuery Affix plugin. Powered by Panini, Sass and Gulp.", 5 | "main": "Gulp.js", 6 | "devDependencies": { 7 | "autoprefixer": "^6.3.6", 8 | "browser-sync": "^2.12.3", 9 | "gulp": "^3.9.1", 10 | "gulp-clean": "^0.3.2", 11 | "gulp-concat": "^2.6.0", 12 | "gulp-postcss": "^6.1.0", 13 | "gulp-sass": "^2.2.0", 14 | "gulp-sourcemaps": "^1.6.0", 15 | "mq4-hover-shim": "^0.3.0", 16 | "panini": "^1.3.0", 17 | "rimraf": "^2.5.2" 18 | }, 19 | "engines": { 20 | "node": ">=0.10.1" 21 | }, 22 | "scripts": { 23 | "start": "gulp", 24 | "build": "gulp build" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/bassjobsen/affix.git" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/bassjobsen/affix/issues", 32 | "email": "bass@w3masters.nl" 33 | }, 34 | "author": "Bass Jobsen (http://bassjobsen.weblogs.fm)", 35 | "license": "MIT", 36 | "private": true 37 | } 38 | -------------------------------------------------------------------------------- /scss/includes/_bootstrap.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.0.0-alpha.2 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | // Core variables and mixins 8 | @import "bootstrap/scss/variables"; 9 | @import "bootstrap/scss/mixins"; 10 | 11 | // Reset and dependencies 12 | @import "bootstrap/scss/normalize"; 13 | @import "bootstrap/scss/print"; 14 | 15 | // Core CSS 16 | @import "bootstrap/scss/reboot"; 17 | @import "bootstrap/scss/type"; 18 | @import "bootstrap/scss/images"; 19 | @import "bootstrap/scss/code"; 20 | @import "bootstrap/scss/grid"; 21 | @import "bootstrap/scss/tables"; 22 | @import "bootstrap/scss/forms"; 23 | @import "bootstrap/scss/buttons"; 24 | 25 | // Components 26 | @import "bootstrap/scss/animation"; 27 | @import "bootstrap/scss/dropdown"; 28 | @import "bootstrap/scss/button-group"; 29 | @import "bootstrap/scss/input-group"; 30 | @import "bootstrap/scss/custom-forms"; 31 | @import "bootstrap/scss/nav"; 32 | @import "bootstrap/scss/navbar"; 33 | @import "bootstrap/scss/card"; 34 | @import "bootstrap/scss/breadcrumb"; 35 | @import "bootstrap/scss/pagination"; 36 | @import "bootstrap/scss/pager"; 37 | @import "bootstrap/scss/labels"; 38 | @import "bootstrap/scss/jumbotron"; 39 | @import "bootstrap/scss/alert"; 40 | @import "bootstrap/scss/progress"; 41 | @import "bootstrap/scss/media"; 42 | @import "bootstrap/scss/list-group"; 43 | @import "bootstrap/scss/responsive-embed"; 44 | @import "bootstrap/scss/close"; 45 | 46 | // Components w/ JavaScript 47 | @import "bootstrap/scss/modal"; 48 | @import "bootstrap/scss/tooltip"; 49 | @import "bootstrap/scss/popover"; 50 | @import "bootstrap/scss/carousel"; 51 | 52 | // Utility classes 53 | @import "bootstrap/scss/utilities"; 54 | @import "bootstrap/scss/utilities-background"; 55 | @import "bootstrap/scss/utilities-spacing"; 56 | @import "bootstrap/scss/utilities-responsive"; 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bootstrap 4 with Affix plugin 2 | 3 | Bootstrap 4 drops the Affix jQuery plugin. They recommend using a `position: sticky` polyfill instead. See the [HTML5 Please](http://html5please.com/#sticky) entry for details and specific polyfill recommendations. If you were using Affix to apply additional, non-position styles, the polyfills might not support your use case. One option for such uses is the third-party [ScrollPos-Styler](https://github.com/acch/scrollpos-styler) library. 4 | 5 | Alternatively this template will show you how to use the Bootstrap 3 plugin with Bootstrap 4. 6 | 7 | Bootstrap 4 with jQuery Affix plugin. It includes a Sass compiler and a set of Panini HTML templates for you. [Panini](https://github.com/zurb/panini) is a super simple flat file generator for use with Gulp. It compiles a series of HTML pages using a common layout. These pages can also include HTML partials, external Handlebars helpers, or external data as JSON or YAML. 8 | 9 | ## Installation 10 | 11 | To use this template, your computer needs: 12 | 13 | - [NodeJS](https://nodejs.org/en/) (0.12 or greater) 14 | - [Git](https://git-scm.com/) 15 | 16 | This template can be installed with the Bootstrap CLI, or downloaded and set up manually. 17 | 18 | ### Using the CLI 19 | 20 | Install the Bootstrap CLI with this command: 21 | 22 | ```bash 23 | [sudo] npm install -g gulp bower 24 | npm install bootstrap-cli --global 25 | ``` 26 | 27 | Use this command to set up an empty Bootstrap 4 project: 28 | 29 | ```bash 30 | bootstrap new --template affix 31 | ``` 32 | 33 | The CLI will prompt you to give your project a name. The code will be downloaded into a folder with this name. 34 | 35 | ### Manual Setup 36 | 37 | To manually set up the project, first download it with Git: 38 | 39 | ```bash 40 | git clone https://github.com/bassjobsen/empty-bootstrap-project-gulp projectname 41 | ``` 42 | 43 | Then open the folder in your command line, and install the needed dependencies: 44 | 45 | ```bash 46 | cd projectname 47 | npm install 48 | bower install 49 | ``` 50 | 51 | Finally, run `npm start` to run the Sass and HTML template compiler. They will re-run every time you save a Sass or HTML temaplate file. 52 | 53 | ### Do not forget to to declare the required CSS classes: 54 | 55 | ```scss 56 | .affix { 57 | position: fixed; 58 | top: 1rem; 59 | } 60 | 61 | .affix-bottom { 62 | position: absolute; 63 | } 64 | ``` 65 | 66 | 67 | -------------------------------------------------------------------------------- /Gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var clean = require('gulp-clean'); 3 | var sass = require('gulp-sass'); 4 | var sourcemaps = require('gulp-sourcemaps'); 5 | var postcss = require('gulp-postcss'); 6 | var autoprefixer = require('autoprefixer'); 7 | var mq4HoverShim = require('mq4-hover-shim'); 8 | var rimraf = require('rimraf').sync; 9 | var browser = require('browser-sync'); 10 | var panini = require('panini'); 11 | var concat = require('gulp-concat'); 12 | var port = process.env.SERVER_PORT || 8080; 13 | var bowerpath = process.env.BOWER_PATH || 'bower_components/'; 14 | 15 | // Starts a BrowerSync instance 16 | gulp.task('server', ['build'], function(){ 17 | browser.init({server: './_site', port: port}); 18 | }); 19 | 20 | // Watch files for changes 21 | gulp.task('watch', function() { 22 | gulp.watch('scss/**/*', ['compile-sass', browser.reload]); 23 | gulp.watch('html/pages/**/*', ['compile-html']); 24 | gulp.watch(['html/{layouts,includes,helpers,data}/**/*'], ['compile-html:reset','compile-html']); 25 | }); 26 | 27 | // Erases the dist folder 28 | gulp.task('clean', function() { 29 | rimraf('_site'); 30 | }); 31 | 32 | // Copy assets 33 | gulp.task('copy', function() { 34 | gulp.src(['assets/**/*']).pipe(gulp.dest('_site')); 35 | }); 36 | 37 | var sassOptions = { 38 | errLogToConsole: true, 39 | outputStyle: 'expanded', 40 | includePaths: bowerpath 41 | }; 42 | 43 | gulp.task('compile-sass', function () { 44 | var processors = [ 45 | mq4HoverShim.postprocessorFor({ hoverSelectorPrefix: '.bs-true-hover ' }), 46 | autoprefixer({ 47 | browsers: [ 48 | // 49 | // Official browser support policy: 50 | // http://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#supported-browsers 51 | // 52 | 'Chrome >= 35', // Exact version number here is kinda arbitrary 53 | // Rather than using Autoprefixer's native "Firefox ESR" version specifier string, 54 | // we deliberately hardcode the number. This is to avoid unwittingly severely breaking the previous ESR in the event that: 55 | // (a) we happen to ship a new Bootstrap release soon after the release of a new ESR, 56 | // such that folks haven't yet had a reasonable amount of time to upgrade; and 57 | // (b) the new ESR has unprefixed CSS properties/values whose absence would severely break webpages 58 | // (e.g. `box-sizing`, as opposed to `background: linear-gradient(...)`). 59 | // Since they've been unprefixed, Autoprefixer will stop prefixing them, 60 | // thus causing them to not work in the previous ESR (where the prefixes were required). 61 | 'Firefox >= 31', // Current Firefox Extended Support Release (ESR) 62 | // Note: Edge versions in Autoprefixer & Can I Use refer to the EdgeHTML rendering engine version, 63 | // NOT the Edge app version shown in Edge's "About" screen. 64 | // For example, at the time of writing, Edge 20 on an up-to-date system uses EdgeHTML 12. 65 | // See also https://github.com/Fyrd/caniuse/issues/1928 66 | 'Edge >= 12', 67 | 'Explorer >= 9', 68 | // Out of leniency, we prefix these 1 version further back than the official policy. 69 | 'iOS >= 8', 70 | 'Safari >= 8', 71 | // The following remain NOT officially supported, but we're lenient and include their prefixes to avoid severely breaking in them. 72 | 'Android 2.3', 73 | 'Android >= 4', 74 | 'Opera >= 12' 75 | ] 76 | })//, 77 | //cssnano(), 78 | ]; 79 | return gulp.src('./scss/app.scss') 80 | .pipe(sourcemaps.init()) 81 | .pipe(sass(sassOptions).on('error', sass.logError)) 82 | .pipe(postcss(processors)) 83 | .pipe(sourcemaps.write()) 84 | .pipe(gulp.dest('./_site/css/')); 85 | }); 86 | 87 | gulp.task('compile-html', function() { 88 | gulp.src('html/pages/**/*.html') 89 | .pipe(panini({ 90 | root: 'html/pages/', 91 | layouts: 'html/layouts/', 92 | partials: 'html/includes/', 93 | helpers: 'html/helpers/', 94 | data: 'html/data/' 95 | })) 96 | .pipe(gulp.dest('_site')) 97 | .on('finish', browser.reload); 98 | }); 99 | 100 | gulp.task('compile-html:reset', function(done) { 101 | panini.refresh(); 102 | done(); 103 | }); 104 | 105 | gulp.task('compile-js', function() { 106 | return gulp.src([bowerpath+ 'jquery/dist/jquery.min.js', bowerpath+ 'tether/dist/js/tether.min.js', bowerpath+ 'bootstrap/dist/js/bootstrap.min.js','assets/js/affix.js']) 107 | .pipe(concat('app.js')) 108 | .pipe(gulp.dest('./_site/js/')); 109 | }); 110 | 111 | 112 | gulp.task('build', ['clean','copy','compile-js','compile-sass','compile-html']); 113 | gulp.task('default', ['server', 'watch']); 114 | -------------------------------------------------------------------------------- /assets/js/affix.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: affix.js v3.3.6 3 | * http://getbootstrap.com/javascript/#affix 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // AFFIX CLASS DEFINITION 14 | // ====================== 15 | 16 | var Affix = function (element, options) { 17 | this.options = $.extend({}, Affix.DEFAULTS, options) 18 | 19 | this.$target = $(this.options.target) 20 | .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) 21 | .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) 22 | 23 | this.$element = $(element) 24 | this.affixed = null 25 | this.unpin = null 26 | this.pinnedOffset = null 27 | 28 | this.checkPosition() 29 | } 30 | 31 | Affix.VERSION = '3.3.6' 32 | 33 | Affix.RESET = 'affix affix-top affix-bottom' 34 | 35 | Affix.DEFAULTS = { 36 | offset: 0, 37 | target: window 38 | } 39 | 40 | Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { 41 | var scrollTop = this.$target.scrollTop() 42 | var position = this.$element.offset() 43 | var targetHeight = this.$target.height() 44 | 45 | if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false 46 | 47 | if (this.affixed == 'bottom') { 48 | if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' 49 | return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' 50 | } 51 | 52 | var initializing = this.affixed == null 53 | var colliderTop = initializing ? scrollTop : position.top 54 | var colliderHeight = initializing ? targetHeight : height 55 | 56 | if (offsetTop != null && scrollTop <= offsetTop) return 'top' 57 | if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' 58 | 59 | return false 60 | } 61 | 62 | Affix.prototype.getPinnedOffset = function () { 63 | if (this.pinnedOffset) return this.pinnedOffset 64 | this.$element.removeClass(Affix.RESET).addClass('affix') 65 | var scrollTop = this.$target.scrollTop() 66 | var position = this.$element.offset() 67 | return (this.pinnedOffset = position.top - scrollTop) 68 | } 69 | 70 | Affix.prototype.checkPositionWithEventLoop = function () { 71 | setTimeout($.proxy(this.checkPosition, this), 1) 72 | } 73 | 74 | Affix.prototype.checkPosition = function () { 75 | if (!this.$element.is(':visible')) return 76 | 77 | var height = this.$element.height() 78 | var offset = this.options.offset 79 | var offsetTop = offset.top 80 | var offsetBottom = offset.bottom 81 | var scrollHeight = Math.max($(document).height(), $(document.body).height()) 82 | 83 | if (typeof offset != 'object') offsetBottom = offsetTop = offset 84 | if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) 85 | if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) 86 | 87 | var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) 88 | 89 | if (this.affixed != affix) { 90 | if (this.unpin != null) this.$element.css('top', '') 91 | 92 | var affixType = 'affix' + (affix ? '-' + affix : '') 93 | var e = $.Event(affixType + '.bs.affix') 94 | 95 | this.$element.trigger(e) 96 | 97 | if (e.isDefaultPrevented()) return 98 | 99 | this.affixed = affix 100 | this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null 101 | 102 | this.$element 103 | .removeClass(Affix.RESET) 104 | .addClass(affixType) 105 | .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') 106 | } 107 | 108 | if (affix == 'bottom') { 109 | this.$element.offset({ 110 | top: scrollHeight - height - offsetBottom 111 | }) 112 | } 113 | } 114 | 115 | 116 | // AFFIX PLUGIN DEFINITION 117 | // ======================= 118 | 119 | function Plugin(option) { 120 | return this.each(function () { 121 | var $this = $(this) 122 | var data = $this.data('bs.affix') 123 | var options = typeof option == 'object' && option 124 | 125 | if (!data) $this.data('bs.affix', (data = new Affix(this, options))) 126 | if (typeof option == 'string') data[option]() 127 | }) 128 | } 129 | 130 | var old = $.fn.affix 131 | 132 | $.fn.affix = Plugin 133 | $.fn.affix.Constructor = Affix 134 | 135 | 136 | // AFFIX NO CONFLICT 137 | // ================= 138 | 139 | $.fn.affix.noConflict = function () { 140 | $.fn.affix = old 141 | return this 142 | } 143 | 144 | 145 | // AFFIX DATA-API 146 | // ============== 147 | 148 | $(window).on('load', function () { 149 | $('[data-spy="affix"]').each(function () { 150 | var $spy = $(this) 151 | var data = $spy.data() 152 | 153 | data.offset = data.offset || {} 154 | 155 | if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom 156 | if (data.offsetTop != null) data.offset.top = data.offsetTop 157 | 158 | Plugin.call($spy, data) 159 | }) 160 | }) 161 | 162 | }(jQuery); 163 | -------------------------------------------------------------------------------- /scss/includes/_variables.scss: -------------------------------------------------------------------------------- 1 | // Variables 2 | 3 | // Table of Contents 4 | // 5 | // Colors 6 | // Options 7 | // Spacing 8 | // Body 9 | // Links 10 | // Grid breakpoints 11 | // Grid containers 12 | // Grid columns 13 | // Fonts 14 | // Components 15 | 16 | // General variable structure 17 | // 18 | // Variable format should follow the `$component-modifier-state-property` order. 19 | 20 | 21 | // Colors 22 | // 23 | // Grayscale and brand colors for use across Bootstrap. 24 | 25 | $gray-dark: #373a3c; 26 | $gray: #55595c; 27 | $gray-light: #818a91; 28 | $gray-lighter: #eceeef; 29 | $gray-lightest: #f7f7f9; 30 | 31 | $brand-primary: #0275d8; 32 | $brand-success: #5cb85c; 33 | $brand-info: #5bc0de; 34 | $brand-warning: #f0ad4e; 35 | $brand-danger: #d9534f; 36 | 37 | 38 | // Options 39 | // 40 | // Quickly modify global styling by enabling or disabling optional features. 41 | 42 | $enable-flex: false; 43 | $enable-rounded: true; 44 | $enable-shadows: false; 45 | $enable-gradients: false; 46 | $enable-transitions: false; 47 | $enable-hover-media-query: false; 48 | $enable-grid-classes: true; 49 | 50 | 51 | // Spacing 52 | // 53 | // Control the default styling of most Bootstrap elements by modifying these 54 | // variables. Mostly focused on spacing. 55 | 56 | $spacer: 1rem; 57 | $spacer-x: $spacer; 58 | $spacer-y: $spacer; 59 | $spacers: ( 60 | 0: ( 61 | x: 0, 62 | y: 0 63 | ), 64 | 1: ( 65 | x: $spacer-x, 66 | y: $spacer-y 67 | ), 68 | 2: ( 69 | x: ($spacer-x * 1.5), 70 | y: ($spacer-y * 1.5) 71 | ), 72 | 3: ( 73 | x: ($spacer-x * 3), 74 | y: ($spacer-y * 3) 75 | ) 76 | ); 77 | $border-width: 1px; 78 | 79 | 80 | // Body 81 | // 82 | // Settings for the `` element. 83 | 84 | $body-bg: #fff; 85 | $body-color: $gray-dark; 86 | 87 | 88 | // Links 89 | // 90 | // Style anchor elements. 91 | 92 | $link-color: $brand-primary; 93 | $link-decoration: none; 94 | $link-hover-color: darken($link-color, 15%); 95 | $link-hover-decoration: underline; 96 | 97 | 98 | // Grid breakpoints 99 | // 100 | // Define the minimum and maximum dimensions at which your layout will change, 101 | // adapting to different screen sizes, for use in media queries. 102 | 103 | $grid-breakpoints: ( 104 | // Extra small screen / phone 105 | xs: 0, 106 | // Small screen / phone 107 | sm: 544px, 108 | // Medium screen / tablet 109 | md: 768px, 110 | // Large screen / desktop 111 | lg: 992px, 112 | // Extra large screen / wide desktop 113 | xl: 1200px 114 | ); 115 | 116 | 117 | // Grid containers 118 | // 119 | // Define the maximum width of `.container` for different screen sizes. 120 | 121 | $container-max-widths: ( 122 | sm: 576px, 123 | md: 720px, 124 | lg: 940px, 125 | xl: 1140px 126 | ); 127 | 128 | 129 | // Grid columns 130 | // 131 | // Set the number of columns and specify the width of the gutters. 132 | 133 | $grid-columns: 12; 134 | $grid-gutter-width: 1.875rem; // 30px 135 | 136 | 137 | // Typography 138 | // 139 | // Font, line-height, and color for body text, headings, and more. 140 | 141 | $font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; 142 | $font-family-serif: Georgia, "Times New Roman", Times, serif; 143 | $font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace; 144 | $font-family-base: $font-family-sans-serif; 145 | 146 | // Pixel value used to responsively scale all typography. Applied to the `` element. 147 | $font-size-root: 16px; 148 | 149 | $font-size-base: 1rem; 150 | $font-size-lg: 1.25rem; 151 | $font-size-sm: .875rem; 152 | $font-size-xs: .75rem; 153 | 154 | $font-size-h1: 2.5rem; 155 | $font-size-h2: 2rem; 156 | $font-size-h3: 1.75rem; 157 | $font-size-h4: 1.5rem; 158 | $font-size-h5: 1.25rem; 159 | $font-size-h6: 1rem; 160 | 161 | $display1-size: 6rem; 162 | $display2-size: 5.5rem; 163 | $display3-size: 4.5rem; 164 | $display4-size: 3.5rem; 165 | 166 | $display1-weight: 300; 167 | $display2-weight: 300; 168 | $display3-weight: 300; 169 | $display4-weight: 300; 170 | 171 | $line-height: 1.5; 172 | 173 | $headings-margin-bottom: ($spacer / 2); 174 | $headings-font-family: inherit; 175 | $headings-font-weight: 500; 176 | $headings-line-height: 1.1; 177 | $headings-color: inherit; 178 | 179 | $lead-font-size: 1.25rem; 180 | $lead-font-weight: 300; 181 | 182 | $text-muted: $gray-light; 183 | 184 | $abbr-border-color: $gray-light; 185 | 186 | $blockquote-small-color: $gray-light; 187 | $blockquote-font-size: ($font-size-base * 1.25); 188 | $blockquote-border-color: $gray-lighter; 189 | 190 | $hr-border-color: rgba(0,0,0,.1); 191 | $hr-border-width: $border-width; 192 | 193 | $dt-font-weight: bold; 194 | 195 | $nested-kbd-font-weight: bold; 196 | 197 | $list-inline-padding: 5px; 198 | 199 | 200 | // Components 201 | // 202 | // Define common padding and border radius sizes and more. 203 | 204 | $line-height-lg: (4 / 3); 205 | $line-height-sm: 1.5; 206 | 207 | $border-radius: .25rem; 208 | $border-radius-lg: .3rem; 209 | $border-radius-sm: .2rem; 210 | 211 | $component-active-color: #fff; 212 | $component-active-bg: $brand-primary; 213 | 214 | $caret-width: .3em; 215 | $caret-width-lg: $caret-width; 216 | 217 | 218 | // Tables 219 | // 220 | // Customizes the `.table` component with basic values, each used across all table variations. 221 | 222 | $table-cell-padding: .75rem; 223 | $table-sm-cell-padding: .3rem; 224 | 225 | $table-bg: transparent; 226 | $table-bg-accent: #f9f9f9; 227 | $table-bg-hover: #f5f5f5; 228 | $table-bg-active: $table-bg-hover; 229 | 230 | $table-border-width: $border-width; 231 | $table-border-color: $gray-lighter; 232 | 233 | 234 | // Buttons 235 | // 236 | // For each of Bootstrap's buttons, define text, background and border color. 237 | 238 | $btn-padding-x: 1rem; 239 | $btn-padding-y: .375rem; 240 | $btn-font-weight: normal; 241 | 242 | $btn-primary-color: #fff; 243 | $btn-primary-bg: $brand-primary; 244 | $btn-primary-border: $btn-primary-bg; 245 | 246 | $btn-secondary-color: $gray-dark; 247 | $btn-secondary-bg: #fff; 248 | $btn-secondary-border: #ccc; 249 | 250 | $btn-info-color: #fff; 251 | $btn-info-bg: $brand-info; 252 | $btn-info-border: $btn-info-bg; 253 | 254 | $btn-success-color: #fff; 255 | $btn-success-bg: $brand-success; 256 | $btn-success-border: $btn-success-bg; 257 | 258 | $btn-warning-color: #fff; 259 | $btn-warning-bg: $brand-warning; 260 | $btn-warning-border: $btn-warning-bg; 261 | 262 | $btn-danger-color: #fff; 263 | $btn-danger-bg: $brand-danger; 264 | $btn-danger-border: $btn-danger-bg; 265 | 266 | $btn-link-disabled-color: $gray-light; 267 | 268 | $btn-padding-x-sm: .75rem; 269 | $btn-padding-y-sm: .25rem; 270 | 271 | $btn-padding-x-lg: 1.25rem; 272 | $btn-padding-y-lg: .75rem; 273 | 274 | // Allows for customizing button radius independently from global border radius 275 | $btn-border-radius: $border-radius; 276 | $btn-border-radius-lg: $border-radius-lg; 277 | $btn-border-radius-sm: $border-radius-sm; 278 | 279 | 280 | // Forms 281 | 282 | $input-padding-x: .75rem; 283 | $input-padding-y: .375rem; 284 | 285 | $input-bg: #fff; 286 | $input-bg-disabled: $gray-lighter; 287 | 288 | $input-color: $gray; 289 | $input-border-color: #ccc; 290 | $input-btn-border-width: $border-width; // For form controls and buttons 291 | $input-box-shadow: inset 0 1px 1px rgba(0,0,0,.075); 292 | 293 | $input-border-radius: $border-radius; 294 | $input-border-radius-lg: $border-radius-lg; 295 | $input-border-radius-sm: $border-radius-sm; 296 | 297 | $input-border-focus: #66afe9; 298 | $input-box-shadow-focus: rgba(102,175,233,.6); 299 | 300 | $input-color-placeholder: #999; 301 | 302 | $input-padding-x-sm: .75rem; 303 | $input-padding-y-sm: .275rem; 304 | 305 | $input-padding-x-lg: 1.25rem; 306 | $input-padding-y-lg: .75rem; 307 | 308 | $input-height: (($font-size-base * $line-height) + ($input-padding-y * 2)); 309 | $input-height-lg: (($font-size-lg * $line-height-lg) + ($input-padding-y-lg * 2)); 310 | $input-height-sm: (($font-size-sm * $line-height-sm) + ($input-padding-y-sm * 2)); 311 | 312 | $form-group-margin-bottom: $spacer-y; 313 | 314 | $input-group-addon-bg: $gray-lighter; 315 | $input-group-addon-border-color: $input-border-color; 316 | 317 | $cursor-disabled: not-allowed; 318 | 319 | // Form validation icons 320 | $form-icon-success: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjNWNiODVjIiBkPSJNMjMzLjggNjEwYy0xMy4zIDAtMjYtNi0zNC0xNi44TDkwLjUgNDQ4LjhDNzYuMyA0MzAgODAgNDAzLjMgOTguOCAzODljMTguOC0xNC4yIDQ1LjUtMTAuNCA1OS44IDguNGw3MiA5NUw0NTEuMyAyNDJjMTIuNS0yMCAzOC44LTI2LjIgNTguOC0xMy43IDIwIDEyLjQgMjYgMzguNyAxMy43IDU4LjhMMjcwIDU5MGMtNy40IDEyLTIwLjIgMTkuNC0zNC4zIDIwaC0yeiIvPjwvc3ZnPg=="; 321 | $form-icon-warning: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjZjBhZDRlIiBkPSJNNjAzIDY0MC4ybC0yNzguNS01MDljLTMuOC02LjYtMTAuOC0xMC42LTE4LjUtMTAuNnMtMTQuNyA0LTE4LjUgMTAuNkw5IDY0MC4yYy0zLjcgNi41LTMuNiAxNC40LjIgMjAuOCAzLjggNi41IDEwLjggMTAuNCAxOC4zIDEwLjRoNTU3YzcuNiAwIDE0LjYtNCAxOC40LTEwLjQgMy41LTYuNCAzLjYtMTQuNCAwLTIwLjh6bS0yNjYuNC0zMGgtNjEuMlY1NDloNjEuMnY2MS4yem0wLTEwN2gtNjEuMlYzMDRoNjEuMnYxOTl6Ii8+PC9zdmc+"; 322 | $form-icon-danger: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjZDk1MzRmIiBkPSJNNDQ3IDU0NC40Yy0xNC40IDE0LjQtMzcuNiAxNC40LTUyIDBsLTg5LTkyLjctODkgOTIuN2MtMTQuNSAxNC40LTM3LjcgMTQuNC01MiAwLTE0LjQtMTQuNC0xNC40LTM3LjYgMC01Mmw5Mi40LTk2LjMtOTIuNC05Ni4zYy0xNC40LTE0LjQtMTQuNC0zNy42IDAtNTJzMzcuNi0xNC4zIDUyIDBsODkgOTIuOCA4OS4yLTkyLjdjMTQuNC0xNC40IDM3LjYtMTQuNCA1MiAwIDE0LjMgMTQuNCAxNC4zIDM3LjYgMCA1MkwzNTQuNiAzOTZsOTIuNCA5Ni40YzE0LjQgMTQuNCAxNC40IDM3LjYgMCA1MnoiLz48L3N2Zz4="; 323 | 324 | 325 | // Dropdowns 326 | // 327 | // Dropdown menu container and contents. 328 | 329 | $dropdown-bg: #fff; 330 | $dropdown-border-color: rgba(0,0,0,.15); 331 | $dropdown-border-width: $border-width; 332 | $dropdown-divider-bg: #e5e5e5; 333 | 334 | $dropdown-link-color: $gray-dark; 335 | $dropdown-link-hover-color: darken($gray-dark, 5%); 336 | $dropdown-link-hover-bg: #f5f5f5; 337 | 338 | $dropdown-link-active-color: $component-active-color; 339 | $dropdown-link-active-bg: $component-active-bg; 340 | 341 | $dropdown-link-disabled-color: $gray-light; 342 | 343 | $dropdown-header-color: $gray-light; 344 | 345 | 346 | // Z-index master list 347 | // 348 | // Warning: Avoid customizing these values. They're used for a bird's eye view 349 | // of components dependent on the z-axis and are designed to all work together. 350 | 351 | $zindex-navbar: 1000; 352 | $zindex-dropdown: 1000; 353 | $zindex-popover: 1060; 354 | $zindex-tooltip: 1070; 355 | $zindex-navbar-fixed: 1030; 356 | $zindex-navbar-sticky: 1030; 357 | $zindex-modal-bg: 1040; 358 | $zindex-modal: 1050; 359 | 360 | 361 | // Navbar 362 | 363 | $navbar-border-radius: $border-radius; 364 | $navbar-padding-horizontal: $spacer; 365 | $navbar-padding-vertical: ($spacer / 2); 366 | 367 | $navbar-dark-color: rgba(255,255,255,.5); 368 | $navbar-dark-hover-color: rgba(255,255,255,.75); 369 | $navbar-dark-active-color: rgba(255,255,255,1); 370 | $navbar-dark-disabled-color: rgba(255,255,255,.25); 371 | 372 | $navbar-light-color: rgba(0,0,0,.3); 373 | $navbar-light-hover-color: rgba(0,0,0,.6); 374 | $navbar-light-active-color: rgba(0,0,0,.8); 375 | $navbar-light-disabled-color: rgba(0,0,0,.15); 376 | 377 | 378 | // Navs 379 | 380 | $nav-link-padding: .5em 1em; 381 | $nav-link-hover-bg: $gray-lighter; 382 | 383 | $nav-disabled-link-color: $gray-light; 384 | $nav-disabled-link-hover-color: $gray-light; 385 | 386 | $nav-tabs-border-color: #ddd; 387 | 388 | $nav-tabs-link-border-width: $border-width; 389 | $nav-tabs-link-hover-border-color: $gray-lighter; 390 | 391 | $nav-tabs-active-link-hover-bg: $body-bg; 392 | $nav-tabs-active-link-hover-color: $gray; 393 | $nav-tabs-active-link-hover-border-color: #ddd; 394 | 395 | $nav-tabs-justified-link-border-color: #ddd; 396 | $nav-tabs-justified-active-link-border-color: $body-bg; 397 | 398 | $nav-pills-border-radius: $border-radius; 399 | $nav-pills-active-link-hover-bg: $component-active-bg; 400 | $nav-pills-active-link-hover-color: $component-active-color; 401 | 402 | 403 | // Pagination 404 | 405 | $pagination-padding-x: .75rem; 406 | $pagination-padding-y: .5rem; 407 | $pagination-padding-x-sm: .75rem; 408 | $pagination-padding-y-sm: .275rem; 409 | $pagination-padding-x-lg: 1.5rem; 410 | $pagination-padding-y-lg: .75rem; 411 | 412 | 413 | $pagination-color: $link-color; 414 | $pagination-bg: #fff; 415 | $pagination-border-width: $border-width; 416 | $pagination-border-color: #ddd; 417 | 418 | $pagination-hover-color: $link-hover-color; 419 | $pagination-hover-bg: $gray-lighter; 420 | $pagination-hover-border: #ddd; 421 | 422 | $pagination-active-color: #fff; 423 | $pagination-active-bg: $brand-primary; 424 | $pagination-active-border: $brand-primary; 425 | 426 | $pagination-disabled-color: $gray-light; 427 | $pagination-disabled-bg: #fff; 428 | $pagination-disabled-border: #ddd; 429 | 430 | 431 | // Pager 432 | 433 | $pager-bg: $pagination-bg; 434 | $pager-border-width: $border-width; 435 | $pager-border-color: $pagination-border-color; 436 | $pager-border-radius: 15px; 437 | 438 | $pager-hover-bg: $pagination-hover-bg; 439 | 440 | $pager-active-bg: $pagination-active-bg; 441 | $pager-active-color: $pagination-active-color; 442 | 443 | $pager-disabled-color: $pagination-disabled-color; 444 | 445 | 446 | // Jumbotron 447 | 448 | $jumbotron-padding: 2rem; 449 | $jumbotron-bg: $gray-lighter; 450 | 451 | 452 | // Form states and alerts 453 | // 454 | // Define colors for form feedback states and, by default, alerts. 455 | 456 | $state-success-text: #3c763d; 457 | $state-success-bg: #dff0d8; 458 | $state-success-border: darken($state-success-bg, 5%); 459 | 460 | $state-info-text: #31708f; 461 | $state-info-bg: #d9edf7; 462 | $state-info-border: darken($state-info-bg, 7%); 463 | 464 | $state-warning-text: #8a6d3b; 465 | $state-warning-bg: #fcf8e3; 466 | $state-warning-border: darken($state-warning-bg, 5%); 467 | 468 | $state-danger-text: #a94442; 469 | $state-danger-bg: #f2dede; 470 | $state-danger-border: darken($state-danger-bg, 5%); 471 | 472 | 473 | // Cards 474 | $card-spacer-x: 1.25rem; 475 | $card-spacer-y: .75rem; 476 | $card-border-width: 1px; 477 | $card-border-radius: $border-radius; 478 | $card-border-color: #e5e5e5; 479 | $card-border-radius-inner: $card-border-radius; 480 | $card-cap-bg: #f5f5f5; 481 | $card-bg: #fff; 482 | 483 | $card-link-hover-color: #fff; 484 | 485 | 486 | // Tooltips 487 | 488 | $tooltip-max-width: 200px; 489 | $tooltip-color: #fff; 490 | $tooltip-bg: #000; 491 | $tooltip-opacity: .9; 492 | 493 | $tooltip-arrow-width: 5px; 494 | $tooltip-arrow-color: $tooltip-bg; 495 | 496 | 497 | // Popovers 498 | 499 | $popover-bg: #fff; 500 | $popover-max-width: 276px; 501 | $popover-border-width: $border-width; 502 | $popover-border-color: rgba(0,0,0,.2); 503 | 504 | $popover-title-bg: darken($popover-bg, 3%); 505 | 506 | $popover-arrow-width: 10px; 507 | $popover-arrow-color: $popover-bg; 508 | 509 | $popover-arrow-outer-width: ($popover-arrow-width + 1); 510 | $popover-arrow-outer-color: fade-in($popover-border-color, 0.05); 511 | 512 | 513 | // Labels 514 | 515 | $label-default-bg: $gray-light; 516 | $label-primary-bg: $brand-primary; 517 | $label-success-bg: $brand-success; 518 | $label-info-bg: $brand-info; 519 | $label-warning-bg: $brand-warning; 520 | $label-danger-bg: $brand-danger; 521 | 522 | $label-color: #fff; 523 | $label-link-hover-color: #fff; 524 | $label-font-weight: bold; 525 | 526 | 527 | // Modals 528 | 529 | // Padding applied to the modal body 530 | $modal-inner-padding: 15px; 531 | 532 | $modal-title-padding: 15px; 533 | $modal-title-line-height: $line-height; 534 | 535 | $modal-content-bg: #fff; 536 | $modal-content-border-color: rgba(0,0,0,.2); 537 | 538 | $modal-backdrop-bg: #000; 539 | $modal-backdrop-opacity: .5; 540 | $modal-header-border-color: #e5e5e5; 541 | $modal-footer-border-color: $modal-header-border-color; 542 | 543 | $modal-lg: 900px; 544 | $modal-md: 600px; 545 | $modal-sm: 300px; 546 | 547 | 548 | // Alerts 549 | // 550 | // Define alert colors, border radius, and padding. 551 | 552 | $alert-padding: 15px; 553 | $alert-border-radius: $border-radius; 554 | $alert-link-font-weight: bold; 555 | $alert-border-width: $border-width; 556 | 557 | $alert-success-bg: $state-success-bg; 558 | $alert-success-text: $state-success-text; 559 | $alert-success-border: $state-success-border; 560 | 561 | $alert-info-bg: $state-info-bg; 562 | $alert-info-text: $state-info-text; 563 | $alert-info-border: $state-info-border; 564 | 565 | $alert-warning-bg: $state-warning-bg; 566 | $alert-warning-text: $state-warning-text; 567 | $alert-warning-border: $state-warning-border; 568 | 569 | $alert-danger-bg: $state-danger-bg; 570 | $alert-danger-text: $state-danger-text; 571 | $alert-danger-border: $state-danger-border; 572 | 573 | 574 | // Progress bars 575 | 576 | $progress-bg: #f5f5f5; 577 | $progress-bar-color: #fff; 578 | $progress-border-radius: $border-radius; 579 | 580 | $progress-bar-bg: $brand-primary; 581 | $progress-bar-success-bg: $brand-success; 582 | $progress-bar-warning-bg: $brand-warning; 583 | $progress-bar-danger-bg: $brand-danger; 584 | $progress-bar-info-bg: $brand-info; 585 | 586 | 587 | // List group 588 | 589 | $list-group-bg: #fff; 590 | $list-group-border-color: #ddd; 591 | $list-group-border-width: $border-width; 592 | $list-group-border-radius: $border-radius; 593 | 594 | $list-group-hover-bg: #f5f5f5; 595 | $list-group-active-color: $component-active-color; 596 | $list-group-active-bg: $component-active-bg; 597 | $list-group-active-border: $list-group-active-bg; 598 | $list-group-active-text-color: lighten($list-group-active-bg, 40%); 599 | 600 | $list-group-disabled-color: $gray-light; 601 | $list-group-disabled-bg: $gray-lighter; 602 | $list-group-disabled-text-color: $list-group-disabled-color; 603 | 604 | $list-group-link-color: #555; 605 | $list-group-link-hover-color: $list-group-link-color; 606 | $list-group-link-heading-color: #333; 607 | 608 | 609 | // Image thumbnails 610 | 611 | $thumbnail-padding: .25rem; 612 | $thumbnail-bg: $body-bg; 613 | $thumbnail-border-width: $border-width; 614 | $thumbnail-border-color: #ddd; 615 | $thumbnail-border-radius: $border-radius; 616 | 617 | 618 | // Breadcrumbs 619 | 620 | $breadcrumb-padding-vertical: .75rem; 621 | $breadcrumb-padding-horizontal: 1rem; 622 | 623 | $breadcrumb-bg: $gray-lighter; 624 | $breadcrumb-divider-color: $gray-light; 625 | $breadcrumb-active-color: $gray-light; 626 | $breadcrumb-divider: "/"; 627 | 628 | 629 | // Carousel 630 | 631 | $carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6); 632 | 633 | $carousel-control-color: #fff; 634 | $carousel-control-width: 15%; 635 | $carousel-control-opacity: .5; 636 | $carousel-control-font-size: 20px; 637 | 638 | $carousel-indicator-active-bg: #fff; 639 | $carousel-indicator-border-color: #fff; 640 | 641 | $carousel-caption-color: #fff; 642 | 643 | 644 | // Close 645 | 646 | $close-font-weight: bold; 647 | $close-color: #000; 648 | $close-text-shadow: 0 1px 0 #fff; 649 | 650 | 651 | // Code 652 | 653 | $code-color: #bd4147; 654 | $code-bg: #f7f7f9; 655 | 656 | $kbd-color: #fff; 657 | $kbd-bg: #333; 658 | 659 | $pre-bg: #f7f7f9; 660 | $pre-color: $gray-dark; 661 | $pre-border-color: #ccc; 662 | $pre-scrollable-max-height: 340px; 663 | --------------------------------------------------------------------------------