├── src
├── img
│ └── .gitkeep
├── templates
│ ├── partials
│ │ └── partial.twig
│ ├── components
│ │ ├── component.twig
│ │ └── navbar.twig
│ ├── page.twig
│ ├── layouts
│ │ └── default.twig
│ ├── demo.twig
│ └── index.twig
├── robots.txt
├── js
│ ├── main.js
│ ├── vendor
│ │ ├── windowwidth.js
│ │ ├── plugins.js
│ │ ├── smartresize.js
│ │ └── smoothscrolling.js
│ └── components
│ │ └── navbar.js
└── sass
│ ├── main.scss
│ ├── _variables.scss
│ ├── base
│ ├── _minireset.scss
│ ├── _print.scss
│ └── _mixins.scss
│ ├── _typography.scss
│ ├── components
│ ├── _buttons.scss
│ └── _navbar.scss
│ └── vendor
│ ├── _bootstrap.scss
│ └── _normalize.scss
├── .gitignore
├── LICENSE.md
├── package.json
├── README.md
└── gulpfile.js
/src/img/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/templates/partials/partial.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/templates/components/component.twig:
--------------------------------------------------------------------------------
1 | {% if foo is defined %}
2 | foo: {{ foo }}
3 | {% endif %}
4 |
--------------------------------------------------------------------------------
/src/robots.txt:
--------------------------------------------------------------------------------
1 | # www.robotstxt.org/
2 |
3 | # Allow crawling of all content
4 | User-agent: *
5 | Disallow:
6 |
--------------------------------------------------------------------------------
/src/js/main.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Main
3 | * Custom Scripts
4 | */
5 |
6 | $(function() {
7 | // Document Ready
8 | })
9 |
10 | $(window).smartresize(function() {
11 | // Debouncing function from John Hann
12 | // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
13 | });
14 |
--------------------------------------------------------------------------------
/src/templates/page.twig:
--------------------------------------------------------------------------------
1 | {% extends 'layouts/default.twig' %}
2 | {% set head_title = 'Sample Page' %}
3 | {% set body_class = '' %}
4 | {% set menu_active = 'sample-page' %}
5 |
6 | {% block page %}
7 |
8 | {% include 'components/navbar.twig' %}
9 |
10 |
11 |
12 | Hello World
13 |
14 |
15 |
16 | {% endblock %}
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependency directories
2 | node_modules
3 | bower_components
4 | dist
5 |
6 | # Optional npm cache directory
7 | .npm
8 |
9 | # SASS Cache
10 | .sass-cache
11 | .sass-cache/*
12 |
13 | # Logs
14 | logs
15 | *.log
16 | npm-debug.log*
17 |
18 | # OSX
19 | *.DS_Store
20 | .AppleDouble
21 | .LSOverride
22 |
23 | # Windows
24 | Thumbs.db
25 | ehthumbs.db
26 |
27 | # Misc
28 | .publish
29 |
--------------------------------------------------------------------------------
/src/sass/main.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Project: Project name
3 | * Author: Author name
4 | */
5 |
6 | // Vendor
7 | @import "vendor/bootstrap";
8 | @import 'vendor/normalize';
9 |
10 | // Base
11 | @import 'base/print';
12 | @import 'base/mixins';
13 | @import 'base/minireset';
14 |
15 | // Variables
16 | @import 'variables';
17 |
18 | // Typography
19 | @import 'typography';
20 |
21 | // Components
22 | @import 'components/**/*.scss';
23 |
24 | /**
25 | * Custom styles
26 | */
27 |
--------------------------------------------------------------------------------
/src/js/vendor/windowwidth.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Check Document Window Width
3 | */
4 |
5 | function checkWindowWidth() {
6 | if ($(window).width() < 576) {
7 | // XS
8 | } else if ($(window).width() < 768) {
9 | // SM and down
10 | } else if ($(window).width() < 992) {
11 | // MD and down
12 | } else if ($(window).width() < 1200) {
13 | // LG and down
14 | } else {
15 | // XL and up
16 | }
17 | }
18 |
19 | $(function() {
20 | // checkWindowWidth();
21 | })
22 |
23 | $(window).smartresize(function() {
24 | // checkWindowWidth();
25 | });
26 |
--------------------------------------------------------------------------------
/src/js/vendor/plugins.js:
--------------------------------------------------------------------------------
1 | // Avoid `console` errors in browsers that lack a console.
2 | (function() {
3 | var method;
4 | var noop = function () {};
5 | var methods = [
6 | 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
7 | 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
8 | 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
9 | 'timeline', 'timelineEnd', 'timeStamp', 'trace', 'warn'
10 | ];
11 | var length = methods.length;
12 | var console = (window.console = window.console || {});
13 |
14 | while (length--) {
15 | method = methods[length];
16 |
17 | // Only stub undefined methods.
18 | if (!console[method]) {
19 | console[method] = noop;
20 | }
21 | }
22 | }());
23 |
24 | // Place any jQuery/helper plugins in here.
25 |
--------------------------------------------------------------------------------
/src/js/vendor/smartresize.js:
--------------------------------------------------------------------------------
1 | // debouncing function from John Hann
2 | // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
3 |
4 | (function($,sr){
5 |
6 | var debounce = function (func, threshold, execAsap) {
7 | var timeout;
8 |
9 | return function debounced () {
10 | var obj = this, args = arguments;
11 | function delayed () {
12 | if (!execAsap)
13 | func.apply(obj, args);
14 | timeout = null;
15 | };
16 |
17 | if (timeout)
18 | clearTimeout(timeout);
19 | else if (execAsap)
20 | func.apply(obj, args);
21 |
22 | timeout = setTimeout(delayed, threshold || 100);
23 | };
24 | }
25 | // smartresize
26 | jQuery.fn[sr] = function(fn){ return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };
27 |
28 | })(jQuery,'smartresize');
29 |
--------------------------------------------------------------------------------
/src/js/components/navbar.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Navbar
3 | */
4 |
5 | $(function() {
6 |
7 | // Navbar toggler
8 | var navbarToggler = $('.js-navbar-toggler'),
9 | navbarOpened = 'navbar--opened';
10 |
11 | navbarToggler.on('click', function(e) {
12 | e.preventDefault();
13 | $('body').toggleClass('navbar--opened');
14 | });
15 |
16 | /*
17 | Add class to navbar after certain amount of pixels are scrolled
18 | if navbar has class navbar-fixed-top then enable it
19 | e.g. when you want to provide some opacity to the background color
20 | */
21 | var navbar = $('.js-navbar'),
22 | navbarScrolled = 'navbar--scrolled';
23 |
24 | if (navbar.hasClass('navbar--fixed')) {
25 | $(window).scroll(function () {
26 | if ($(this).scrollTop() > 100) {
27 | navbar.addClass(navbarScrolled);
28 | } else {
29 | navbar.removeClass(navbarScrolled);
30 | }
31 | });
32 | }
33 |
34 | })
35 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) Frontie - Front-end HTML5 Boilerplate
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/src/templates/layouts/default.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ head_title }} · Frontie
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {% block page %}{% endblock %}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/sass/_variables.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Variables
3 | */
4 |
5 | // Colors
6 | $primary: #007bff;
7 |
8 | // Fonts
9 | $font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;
10 | $font-size-base: 1rem;
11 | $line-height-base: 1.5;
12 | $body-color: #222;
13 |
14 | // Transition
15 | $transition-base: all .2s ease-in-out;
16 |
17 | /**
18 | * Typography Variables
19 | */
20 |
21 | // Paragraph
22 | $paragraph-margin-bottom: 1rem;
23 |
24 | // Headings
25 | $headings-margin-bottom: 1rem;
26 | $headings-font-family: $font-family;
27 | $headings-font-weight: 500;
28 | $headings-line-height: inherit;
29 | $headings-color: inherit;
30 |
31 | // Headings Font Size
32 | $h1-font-size: $font-size-base * 2.5 !default;
33 | $h2-font-size: $font-size-base * 2 !default;
34 | $h3-font-size: $font-size-base * 1.75 !default;
35 | $h4-font-size: $font-size-base * 1.5 !default;
36 | $h5-font-size: $font-size-base * 1.25 !default;
37 | $h6-font-size: $font-size-base !default;
38 |
39 | // Links
40 | $link-color: #007bff;
41 | $link-decoration: none;
42 | $link-hover-color: darken($link-color, 15%);
43 | $link-hover-decoration: underline;
44 |
--------------------------------------------------------------------------------
/src/sass/base/_minireset.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Reset, normalization of HTML elements
3 | */
4 |
5 | *,
6 | *::before,
7 | *::after {
8 | box-sizing: border-box; // Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
9 | }
10 |
11 | html {
12 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
13 | }
14 |
15 | ol,
16 | ul,
17 | dl {
18 | margin-top: 0;
19 | margin-bottom: 1rem;
20 | }
21 |
22 | ol ol,
23 | ul ul,
24 | ol ul,
25 | ul ol {
26 | margin-bottom: 0;
27 | }
28 |
29 | figure {
30 | margin: 0;
31 | }
32 |
33 | img {
34 | vertical-align: middle;
35 | border-style: none; // Remove the border on images inside links in IE 10-.
36 | max-width: 100%;
37 | height: auto;
38 | }
39 |
40 | svg:not(:root) {
41 | overflow: hidden; // Hide the overflow in IE
42 | }
43 |
44 | input,
45 | button,
46 | select,
47 | optgroup,
48 | textarea {
49 | margin: 0; // Remove the margin in Firefox and Safari
50 | font-family: inherit;
51 | font-size: inherit;
52 | line-height: inherit;
53 | }
54 |
55 | button,
56 | input {
57 | overflow: visible; // Show the overflow in Edge
58 | }
59 |
60 | button,
61 | select {
62 | text-transform: none; // Remove the inheritance of text transform in Firefox
63 | }
64 |
65 | table {
66 | border-collapse: collapse; // Prevent double borders
67 | }
68 |
--------------------------------------------------------------------------------
/src/sass/_typography.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Typography
3 | */
4 |
5 | html {
6 | font-family: $font-family;
7 | font-size: $font-size-base;
8 | color: $body-color;
9 | line-height: $line-height-base;
10 | }
11 |
12 | p {
13 | margin-top: 0;
14 | margin-bottom: $paragraph-margin-bottom;
15 | }
16 |
17 | h1,
18 | h2,
19 | h3,
20 | h4,
21 | h5,
22 | h6,
23 | .h1,
24 | .h2,
25 | .h3,
26 | .h4,
27 | .h5,
28 | .h6 {
29 | margin-top: 0;
30 | margin-bottom: $headings-margin-bottom;
31 | font-family: $headings-font-family;
32 | font-weight: $headings-font-weight;
33 | line-height: $headings-line-height;
34 | color: $headings-color;
35 | }
36 |
37 | h1,
38 | .h1 {
39 | font-size: $h1-font-size;
40 | }
41 | h2,
42 | .h2 {
43 | font-size: $h2-font-size;
44 | }
45 | h3,
46 | .h3 {
47 | font-size: $h3-font-size;
48 | }
49 | h4,
50 | .h4 {
51 | font-size: $h4-font-size;
52 | }
53 | h5,
54 | .h5 {
55 | font-size: $h5-font-size;
56 | }
57 | h6,
58 | .h6 {
59 | font-size: $h6-font-size;
60 | }
61 |
62 | a {
63 | color: $link-color;
64 | text-decoration: $link-decoration;
65 | background-color: transparent; // Remove the gray background on active links in IE 10.
66 | -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.
67 | &:hover {
68 | color: $link-hover-color;
69 | text-decoration: $link-hover-decoration;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/js/vendor/smoothscrolling.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Smooth Scrolling
3 | * https://css-tricks.com/snippets/jquery/smooth-scrolling/
4 | */
5 |
6 | // Select all links with hashes
7 | $('.is-scroll')
8 | // Remove links that don't actually link to anything
9 | .not('[href="#"]')
10 | .not('[href="#0"]')
11 | .click(function(event) {
12 | // On-page links
13 | if (
14 | location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
15 | &&
16 | location.hostname == this.hostname
17 | ) {
18 | // Figure out element to scroll to
19 | var target = $(this.hash);
20 | target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
21 | // Does a scroll target exist?
22 | if (target.length) {
23 | // Only prevent default if animation is actually gonna happen
24 | event.preventDefault();
25 | $('html, body').animate({
26 | scrollTop: target.offset().top
27 | }, 1000, function() {
28 | // Callback after animation
29 | // Must change focus!
30 | var $target = $(target);
31 | $target.focus();
32 | if ($target.is(":focus")) { // Checking if the target was focused
33 | return false;
34 | } else {
35 | $target.attr('tabindex','-1'); // Adding tabindex for elements not focusable
36 | $target.focus(); // Set focus again
37 | };
38 | });
39 | }
40 | }
41 | });
42 |
--------------------------------------------------------------------------------
/src/templates/demo.twig:
--------------------------------------------------------------------------------
1 | {% extends 'layouts/default.twig' %}
2 | {% set head_title = 'Components' %}
3 | {% set body_class = '' %}
4 | {% set menu_active = 'demo' %}
5 |
6 | {% block page %}
7 |
8 | {% include 'components/navbar.twig' %}
9 |
10 |
28 |
29 |
30 |
31 | Scroll down to see fixed navbar feature
32 |
33 |
34 |
35 |
36 |
37 | Sample Twig features
38 |
39 | ---
40 |
41 | Let's loop over item in a sequence using twig "for" function
42 |
43 | {% for i in 0..3 %}
44 |
For Item: {{ i }}
45 | {% endfor %}
46 |
47 | ---
48 |
49 | Include component / partial
50 |
51 | {% include 'components/component.twig' %}
52 |
53 | {% include 'partials/partial.twig' %}
54 |
55 | ---
56 |
57 | Include component / partial with variable
58 |
59 | {% include 'components/component.twig' with {'foo': 'bar'} %}
60 |
61 |
62 |
63 | {% endblock %}
64 |
--------------------------------------------------------------------------------
/src/sass/components/_buttons.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Buttons
3 | */
4 |
5 | $btn-bg: $primary;
6 | $btn-text-color: white;
7 | $btn-font-weight: inherit;
8 | $btn-font-size: inherit;
9 | $btn-padding-x: .75rem;
10 | $btn-padding-y: .5rem;
11 | $btn-border-color: transparent;
12 | $btn-border-width: 1px;
13 | $btn-border-radius: 0;
14 |
15 | $btn-hover-bg: darken($primary, 10%);
16 | $btn-hover-text-color: white;
17 | $btn-hover-border-color: transparent;
18 |
19 | .btn {
20 | display: inline-block;
21 | padding: $btn-padding-y $btn-padding-x;
22 | border: $btn-border-width solid transparent;
23 | background-color: $btn-bg;
24 | color: $btn-text-color;
25 | vertical-align: middle;
26 | text-align: center;
27 | white-space: nowrap;
28 | font-size: $btn-font-size;
29 | font-weight: $btn-font-weight;
30 | cursor: pointer;
31 | transition: $transition-base;
32 | user-select: none;
33 | text-decoration: none;
34 | border-radius: $btn-border-radius;
35 |
36 | &:hover,
37 | &:focus {
38 | text-decoration: none;
39 | }
40 |
41 | &:focus {
42 | outline: 0;
43 | }
44 |
45 | &:hover {
46 | background-color: $btn-hover-bg;
47 | color: $btn-hover-text-color;
48 | border-color: $btn-hover-border-color;
49 | }
50 | }
51 |
52 | .btn-block {
53 | display: block;
54 | width: 100%;
55 | }
56 |
57 | .btn-outline {
58 | border: 1px solid $btn-bg;
59 | background-color: transparent;
60 | color: $btn-bg;
61 | &:hover {
62 | border-color: $btn-bg;
63 | background-color: $btn-bg;
64 | color: $btn-hover-text-color;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/sass/base/_print.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Print styles.
3 | * Taken from https://github.com/h5bp/html5-boilerplate
4 | */
5 |
6 | /* ==========================================================================
7 | Print styles.
8 | Inlined to avoid the additional HTTP request:
9 | https://www.phpied.com/delay-loading-your-print-css/
10 | ========================================================================== */
11 |
12 | @media print {
13 | *,
14 | *:before,
15 | *:after {
16 | background: transparent !important;
17 | color: #000 !important; /* Black prints faster */
18 | -webkit-box-shadow: none !important;
19 | box-shadow: none !important;
20 | text-shadow: none !important;
21 | }
22 |
23 | a,
24 | a:visited {
25 | text-decoration: underline;
26 | }
27 |
28 | a[href]:after {
29 | content: " (" attr(href) ")";
30 | }
31 |
32 | abbr[title]:after {
33 | content: " (" attr(title) ")";
34 | }
35 |
36 | /*
37 | * Don't show links that are fragment identifiers,
38 | * or use the `javascript:` pseudo protocol
39 | */
40 |
41 | a[href^="#"]:after,
42 | a[href^="javascript:"]:after {
43 | content: "";
44 | }
45 |
46 | pre {
47 | white-space: pre-wrap !important;
48 | }
49 | pre,
50 | blockquote {
51 | border: 1px solid #999;
52 | page-break-inside: avoid;
53 | }
54 |
55 | /*
56 | * Printing Tables:
57 | * http://css-discuss.incutio.com/wiki/Printing_Tables
58 | */
59 |
60 | thead {
61 | display: table-header-group;
62 | }
63 |
64 | tr,
65 | img {
66 | page-break-inside: avoid;
67 | }
68 |
69 | p,
70 | h2,
71 | h3 {
72 | orphans: 3;
73 | widows: 3;
74 | }
75 |
76 | h2,
77 | h3 {
78 | page-break-after: avoid;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/templates/index.twig:
--------------------------------------------------------------------------------
1 | {% extends 'layouts/default.twig' %}
2 | {% set head_title = 'Index' %}
3 | {% set body_class = 'index' %}
4 |
5 | {% block page %}
6 |
7 |
53 |
54 |
55 |
56 | Project Name
57 |
58 |
59 | This is the demo index page with basic styles for listing all of your pages.
60 |
61 | Tip: can be useful when showing the site preview to a client.
62 |
63 |
71 |
72 |
73 | {% endblock %}
74 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontie",
3 | "version": "1.1.0",
4 | "description": "Front-end Boilerplate. Frontie is a front-end boilerplate using Gulp for task automation. Based on normalize.css, Bootstrap 4 Grid & Responsive breakpoints and enhanced with Twig.js, Sass, Autoprefixer plus Browsersync.",
5 | "main": "gulpfile.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/tomaszbujnowicz/frontie.git"
12 | },
13 | "keywords": [
14 | "gulp",
15 | "frontend",
16 | "front-end boilerplate",
17 | "browsersync",
18 | "front-end development",
19 | "sass",
20 | "boilerplate",
21 | "bootstrap grid",
22 | "twig"
23 | ],
24 | "author": {
25 | "name": "Tomasz Bujnowicz",
26 | "email": "tomasz@prollective.com",
27 | "url": "https://prollective.com"
28 | },
29 | "license": "MIT",
30 | "bugs": {
31 | "url": "https://github.com/tomaszbujnowicz/frontie/issues"
32 | },
33 | "homepage": "https://github.com/tomaszbujnowicz/frontie#readme",
34 | "devDependencies": {
35 | "bootstrap": "^4.1.3",
36 | "browser-sync": "^2.26.3",
37 | "css-clean": "^2.2.5",
38 | "del": "^3.0.0",
39 | "gulp": "^3.9.1",
40 | "gulp-autoprefixer": "^6.0.0",
41 | "gulp-changed": "^3.2.0",
42 | "gulp-concat": "^2.6.1",
43 | "gulp-foreach": "^0.1.0",
44 | "gulp-gh-pages": "^0.5.4",
45 | "gulp-notify": "^3.2.0",
46 | "gulp-plumber": "^1.2.0",
47 | "gulp-sass": "^4.0.2",
48 | "gulp-sass-glob": "^1.0.9",
49 | "gulp-sass-lint": "^1.4.0",
50 | "gulp-sourcemaps": "^2.6.4",
51 | "gulp-twig": "^1.2.0",
52 | "gulp-uglify": "^3.0.1",
53 | "gulp-watch": "^5.0.1",
54 | "run-sequence": "^2.2.1"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/templates/components/navbar.twig:
--------------------------------------------------------------------------------
1 | {#
2 | .navbar--fixed
3 | If navbar shouldn't be fixed,
4 | remove the class "navbar--fixed" below and top padding from body {} in _navbar.scss
5 | CSS: /sass/components/_navbar.scss
6 |
7 | .js-navbar
8 | Navbar becomes automatically transparent when scrolling more than 100px down
9 | We add class "navbar--scrolled" to the "navbar", you can tweak opacity in _navbar.scss
10 | CSS: /sass/components/_navbar.scss
11 | JS: /js/components/navbar.js
12 | #}
13 |
14 |
15 |
16 |
17 |
18 | Logo
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | {#
27 | In case you want to implement front-end in WordPress, please follow below instructions:
28 | Replace everything inside including
with the following WordPress Menu code
29 | 'menu navbar__menu',
32 | 'container_class' => 'navbar__collapse'
33 | ) );
34 | ?>
35 | #}
36 |
37 |
38 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/sass/vendor/_bootstrap.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Bootstrap 4.1.3
3 | * Via /node_modules + some modifications
4 |
5 | http://getbootstrap.com/docs/4.1/getting-started/theming/
6 | Import bootstrap-grid.scss
7 |
8 | The only change comparing to the original structure is that we don't import whole "variables.scss" from Bootstrap.
9 | We don't all Bootstrap variagbles variables anyway.
10 |
11 | We comment // @import "variables"; and define Grids and Breakpoints variables directly here.
12 | */
13 |
14 | /*!
15 | * Bootstrap Grid v4.1.3 (https://getbootstrap.com/)
16 | * Copyright 2011-2018 The Bootstrap Authors
17 | * Copyright 2011-2018 Twitter, Inc.
18 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
19 | */
20 |
21 | @at-root {
22 | @-ms-viewport { width: device-width; } // stylelint-disable-line at-rule-no-vendor-prefix
23 | }
24 |
25 | html {
26 | box-sizing: border-box;
27 | -ms-overflow-style: scrollbar;
28 | }
29 |
30 | *,
31 | *::before,
32 | *::after {
33 | box-sizing: inherit;
34 | }
35 |
36 | @import "node_modules/bootstrap/scss/functions";
37 |
38 | // @import "variables";
39 |
40 | // Grid breakpoints
41 | //
42 | // Define the minimum dimensions at which your layout will change,
43 | // adapting to different screen sizes, for use in media queries.
44 |
45 | $grid-breakpoints: (
46 | xs: 0,
47 | sm: 576px,
48 | md: 768px,
49 | lg: 992px,
50 | xl: 1200px
51 | ) !default;
52 |
53 | @include _assert-ascending($grid-breakpoints, "$grid-breakpoints");
54 | @include _assert-starts-at-zero($grid-breakpoints);
55 |
56 | // Grid containers
57 | //
58 | // Define the maximum width of `.container` for different screen sizes.
59 |
60 | $container-max-widths: (
61 | sm: 540px,
62 | md: 720px,
63 | lg: 960px,
64 | xl: 1140px
65 | ) !default;
66 |
67 | @include _assert-ascending($container-max-widths, "$container-max-widths");
68 |
69 | // Grid columns
70 | //
71 | // Set the number of columns and specify the width of the gutters.
72 |
73 | $grid-columns: 12 !default;
74 | $grid-gutter-width: 30px !default;
75 | $enable-grid-classes: true !default;
76 |
77 | @import "node_modules/bootstrap/scss/mixins/breakpoints";
78 | @import "node_modules/bootstrap/scss/mixins/grid-framework";
79 | @import "node_modules/bootstrap/scss/mixins/grid";
80 |
81 | @import "node_modules/bootstrap/scss/grid";
82 | @import "node_modules/bootstrap/scss/utilities/display";
83 | @import "node_modules/bootstrap/scss/utilities/flex";
84 |
85 | /**
86 | * Demo: Bootstrap Media Queries
87 | * http://getbootstrap.com/docs/4.1/layout/overview/#responsive-breakpoints
88 | */
89 |
90 | @include media-breakpoint-up(sm) {}
91 | @include media-breakpoint-up(md) {}
92 | @include media-breakpoint-up(lg) {}
93 | @include media-breakpoint-up(xl) {}
94 |
95 | @include media-breakpoint-down(xs) {}
96 | @include media-breakpoint-down(sm) {}
97 | @include media-breakpoint-down(md) {}
98 | @include media-breakpoint-down(lg) {}
99 |
100 | @include media-breakpoint-only(xs) {}
101 | @include media-breakpoint-only(sm) {}
102 | @include media-breakpoint-only(md) {}
103 | @include media-breakpoint-only(lg) {}
104 | @include media-breakpoint-only(xl) {}
105 |
--------------------------------------------------------------------------------
/src/sass/components/_navbar.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Navbar
3 | */
4 |
5 | $navbar-height-desktop: 80px;
6 | $navbar-height-mobile: 50px;
7 | $navbar-bg: #fafafa;
8 | $navbar-link-color: $primary;
9 | $navbar-hover-link-color: darken($primary, 15%);
10 | $z-index-navbar: 1000;
11 | $z-index-navbar-toggler: 1010;
12 |
13 | .navbar {
14 |
15 | background-color: $navbar-bg;
16 | z-index: $z-index-navbar;
17 |
18 | &__wrapper {
19 | display: flex;
20 | align-items: center;
21 | }
22 | &__brand {
23 | &:hover {
24 | text-decoration: none;
25 | }
26 | }
27 | &__toggler {
28 | display: none;
29 | background: none;
30 | border: none;
31 | border-radius: 0;
32 | &:focus {
33 | outline: none;
34 | }
35 | }
36 | &__menu {
37 | display: flex;
38 | list-style: none;
39 | margin: 0;
40 | padding: 0;
41 | }
42 | .menu-item {
43 | a {
44 | transition: $transition-base;
45 | color: $navbar-link-color;
46 | &:hover {
47 | color: $navbar-hover-link-color;
48 | text-decoration: none;
49 | }
50 | }
51 | }
52 | .current-menu-item {
53 | a {
54 | color: $navbar-hover-link-color;
55 | text-decoration: none;
56 | }
57 | }
58 |
59 | @include media-breakpoint-down(sm) {
60 | &__wrapper {
61 | height: $navbar-height-mobile;
62 | }
63 | &__collapse {
64 | transition: $transition-base;
65 | opacity: 0;
66 | visibility: hidden;
67 | position: fixed;
68 | top: 0;
69 | left: 0;
70 | right: 0;
71 | bottom: 0;
72 | width: 100%;
73 | height: 100%;
74 | overflow-x: hidden;
75 | overflow-y: auto;
76 | pointer-events: auto;
77 | }
78 | &__toggler {
79 | display: inline-block;
80 | position: relative;
81 | margin-left: auto;
82 | width: 40px;
83 | height: 32px;
84 | cursor: pointer;
85 | z-index: $z-index-navbar-toggler;
86 | }
87 | &__toggler-line {
88 | transition: $transition-base;
89 | display: block;
90 | position: absolute;
91 | top: 8px;
92 | left: 8px;
93 | background-color: black;
94 | height: 1px;
95 | width: 24px;
96 | &:nth-child(2) {
97 | top: 16px;
98 | }
99 | &:nth-child(3) {
100 | top: 24px;
101 | }
102 | }
103 | &__menu {
104 | align-items: center;
105 | justify-content: center;
106 | flex-direction: column;
107 | min-height: 100vh;
108 | background-color: $navbar-bg;
109 | padding: 2rem 0; // add some top / bottom padding in case there is more items that doesn't fit in the viewport
110 | }
111 | .menu-item {
112 | &:not(:last-child) {
113 | margin-bottom: 1rem;
114 | }
115 | }
116 | body.navbar--opened & {
117 | &__collapse {
118 | visibility: visible;
119 | opacity: 1;
120 | }
121 | &__toggler-line {
122 | &:nth-child(1) {
123 | top: 15px;
124 | transform: rotate(45deg);
125 | }
126 | &:nth-child(3) {
127 | top: 15px;
128 | transform: rotate(-45deg);
129 | }
130 | &:nth-child(2) {
131 | opacity: 0;
132 | }
133 | }
134 | }
135 | }
136 |
137 | @include media-breakpoint-up(md) {
138 | &__wrapper {
139 | height: $navbar-height-desktop;
140 | }
141 | &__brand {
142 | margin-right: auto;
143 | }
144 | &__menu {
145 | flex-direction: row;
146 | }
147 | .menu-item {
148 | &:not(:last-child) {
149 | margin-right: 2rem;
150 | }
151 | }
152 | }
153 | }
154 |
155 | // Prevent vertical scrollbar when navbar is opened on smaller devices
156 |
157 | body.navbar--opened {
158 | overflow: hidden;
159 | }
160 |
161 | /**
162 | * Navbar Fixed
163 | */
164 |
165 | .navbar.navbar--fixed {
166 | position: fixed;
167 | top: 0;
168 | left: 0;
169 | width: 100%;
170 | }
171 |
172 | // Make navbar transparent when scrolling more than 100px down
173 |
174 | .navbar.navbar--scrolled {
175 | transition: $transition-base;
176 | opacity: .25;
177 | &:hover {
178 | opacity: 1;
179 | }
180 | }
181 |
182 | // When the navbar is fixed you should also add some padding to body tag as well - most likely that should be height of the navbar
183 |
184 | body {
185 | @include media-breakpoint-down(sm) {
186 | padding-top: $navbar-height-mobile;
187 | }
188 | @include media-breakpoint-up(md) {
189 | padding-top: $navbar-height-desktop;
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # There is more up to date boilerplate based on Gulp 4 and Webpack. Please consider using this one instead https://github.com/tomaszbujnowicz/frontie-webpack
2 |
3 | # Frontie - Front-end Boilerplate
4 |
5 | **Frontie is a front-end boilerplate using Gulp for task automation.**
6 |
7 | Based on normalize.css, Bootstrap 4 Grid & Responsive breakpoints and enhanced with Twig.js, Sass, Autoprefixer plus Browsersync.
8 | These tools make it a solid front-end boilerplate to get a new project off the ground.
9 |
10 | ## Features
11 |
12 | * [Gulp](http://gulpjs.com/) for task automation
13 |
14 | * [Bootstrap 4 Grid System](https://getbootstrap.com/docs/4.1/layout/grid/) as a powerful mobile-first flexbox grid to build layouts of all shapes and sizes
15 |
16 | * [Bootstrap 4 Responsive Breakpoints](https://getbootstrap.com/docs/4.1/layout/overview/#responsive-breakpoints) as a media queries to create sensible breakpoints
17 |
18 | * [Twig.js](https://github.com/twigjs/twig.js) as a templating engine
19 |
20 | * [Sass](http://sass-lang.com/) as a CSS preprocessor
21 |
22 | * [Autoprefixer](https://www.npmjs.org/package/gulp-autoprefixer) for parsing CSS and add vendor prefixes to rules by Can I Use
23 |
24 | * [Browsersync](https://www.browsersync.io/) for time-saving synchronised browser testing
25 |
26 | * [Github pages](https://www.npmjs.com/package/gulp-gh-pages) for publishing contents to Github pages
27 |
28 | * [Source Maps](https://www.npmjs.com/package/gulp-sourcemaps)
29 |
30 | ## Usage
31 |
32 | ### Requirements
33 | Make sure all dependencies have been installed before moving on:
34 |
35 | * [npm](https://www.npmjs.com/get-npm) or [yarn](https://yarnpkg.com/lang/en/)
36 | * [Node.js](https://nodejs.org/en/download/)
37 | * [Gulp](http://gulpjs.com/)
38 |
39 | ### Quick start: Installation
40 | Clone this repository and run
41 | - `npm install` or `yarn` to install dependencies
42 |
43 | This will take some time and will install all packages necessary to run Frontie and its tasks.
44 |
45 | ### Development
46 | - `gulp` to start the server (Browsersync session) and watch for changes
47 |
48 | Then visit http://localhost:3000/ *- or a new browser windows popped-up already -* to preview your new website. BrowserSync will automatically reload the CSS or refresh the whole page, when stylesheets, assets or content changes.
49 |
50 | **There are other tasks available including:**
51 |
52 | - `gulp watch` to watch without building /dist (production files) from scratch
53 | - `gulp build` to build a static version of the website inside the /dist folder
54 | - `gulp deploy` to publish contents from /dist folder to Github pages
55 |
56 | ## Structure
57 |
58 | ```
59 | |--dist # → Static version of the website ready to upload (never edit)
60 | |
61 | |--node_modules # → Node.js packages (never edit)
62 | |--gulpfile.js # → Gulpfile tasks
63 | |--package.json # → Node.js dependencies and scripts
64 | |--package-lock.json # → Node.js lock file (never edit)
65 | |--yarn.lock # → Yarn lock file (never edit)
66 | |
67 | |--src # → Site source files
68 | | |--img # → Site images
69 | | |--css # → Site stylesheets
70 | | |--js # → Site JS
71 | | | |--components # → Components JS (e.g. navbar)
72 | | | |--vendor # → Vendor JS - 3rd party libraries
73 | | | |--main.js # → Main (custom scripts) JS
74 | | |--templates # → Site templates
75 | | | |--components # → Components templates (e.g. navbar)
76 | | | |--layouts # → Base templates
77 | | | |--partials # → Partial templates
78 | | | |--components.twig # → The components page for demo purpose
79 | | | |--index.twig # → The index page
80 | ```
81 |
82 | ## Components
83 |
84 | There are also some default Frontie components ( with basic styling and functionality) included in the package.
85 | You can easily remove / comment them out in case you don't need them.
86 |
87 | * Navbar
88 | * Button
89 |
90 | ## Notes
91 |
92 | ### Why don't you include everything from Bootstrap 4?
93 |
94 | It's a really great front-end framework for many projects but in some cases it might be just too large and complex.
95 | I only took what I needed from it which is a grid system and responsive breakpoints.
96 | If you need more stuff then you can easily import required components or use a dedicated version [Frontie Bootstrap 4](https://github.com/tomaszbujnowicz/frontie-bootstrap4)
97 |
98 | ## Next Step?
99 |
100 | * Upgrade to use Gulp 4, Webpack and Babel or @std/esm
101 |
102 | ## Copyright and license
103 |
104 | Copyright 2018 Tomasz Bujnowicz under the [MIT license](http://opensource.org/licenses/MIT).
105 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Variables
3 | */
4 | var gulp = require('gulp'),
5 | autoprefixer = require('gulp-autoprefixer'),
6 | browserSync = require('browser-sync'),
7 | changed = require('gulp-changed'),
8 | concat = require('gulp-concat'),
9 | del = require('del'),
10 | foreach = require('gulp-foreach'),
11 | ghPages = require('gulp-gh-pages'),
12 | notify = require('gulp-notify'),
13 | plumber = require('gulp-plumber'),
14 | reload = browserSync.reload,
15 | runSequence = require('run-sequence'),
16 | sass = require('gulp-sass'),
17 | sassGlob = require('gulp-sass-glob'),
18 | sassLint = require('gulp-sass-lint'),
19 | sourcemaps = require('gulp-sourcemaps'),
20 | twig = require('gulp-twig'),
21 | uglify = require('gulp-uglify'),
22 | watch = require('gulp-watch');
23 |
24 | /**
25 | * Paths
26 | */
27 | var paths = {
28 | dist: 'dist/',
29 | src: 'src/',
30 | deploy: 'dist/**/*',
31 | html: 'dist/*.html',
32 | browserSync: './dist',
33 | sass: {
34 | inputAll: 'src/sass/**/*.scss',
35 | input: 'src/sass/main.scss',
36 | output: 'dist/css',
37 | lint: 'src/sass/**/*.s+(a|c)ss'
38 | },
39 | jsVendor: {
40 | input: 'src/js/vendor/**/*.js',
41 | output: 'dist/js'
42 | },
43 | jsComponents: {
44 | input: 'src/js/components/**/*.js',
45 | },
46 | js: {
47 | input: 'src/js/main.js',
48 | output: 'dist/js'
49 | },
50 | img: {
51 | input: 'src/img/**/*',
52 | output: 'dist/img'
53 | },
54 | twig: {
55 | src: 'src/templates/*.{twig,html}',
56 | watch: 'src/templates/**/*.{twig,html}'
57 | },
58 | misc: {
59 | xml: 'src/*.xml',
60 | txt: 'src/*.txt'
61 | }
62 | };
63 |
64 | /**
65 | * Catch stream errors
66 | */
67 | var onError = function (err) {
68 | notify.onError({
69 | title: "Gulp error in " + err.plugin,
70 | message: err.toString()
71 | })(err);
72 | };
73 |
74 | /**
75 | * Browser Sync
76 | */
77 | gulp.task('browser-sync', function() {
78 | browserSync.init(null, {
79 | files: [paths.html],
80 | server: {
81 | baseDir: paths.browserSync
82 | },
83 | notify: false
84 | });
85 | });
86 |
87 | /**
88 | * Clean dist
89 | */
90 | gulp.task('clean:dist', function() {
91 | return del.sync(paths.dist);
92 | })
93 |
94 | /**
95 | * CSS
96 | */
97 | gulp.task('css', function (done) {
98 | return gulp.src(paths.sass.input)
99 | .pipe(plumber({ errorHandler: onError }))
100 | .pipe(sourcemaps.init())
101 | .pipe(sassGlob())
102 | .pipe(sass({ outputStyle: 'compressed' }))
103 | .pipe(autoprefixer('last 2 versions'))
104 | .pipe(sourcemaps.write('./', {addComment: false}))
105 | .pipe(gulp.dest(paths.sass.output))
106 | .pipe(browserSync.reload({stream:true}))
107 | done();
108 | });
109 |
110 | /**
111 | * Sass Lint
112 | */
113 | gulp.task('sass-lint', function () {
114 | return gulp.src(paths.sass.lint)
115 | .pipe(sassLint())
116 | .pipe(sassLint.format())
117 | .pipe(sassLint.failOnError())
118 | });
119 |
120 | /**
121 | * JS Vendor
122 | */
123 | gulp.task('js:vendor', function (done) {
124 | return gulp.src(paths.jsVendor.input)
125 | .pipe(plumber({ errorHandler: onError }))
126 | .pipe(sourcemaps.init())
127 | .pipe(concat('vendor.js'))
128 | .pipe(uglify())
129 | .pipe(sourcemaps.write('./', {addComment: false}))
130 | .pipe(gulp.dest(paths.jsVendor.output))
131 | .pipe(browserSync.reload({stream:true}))
132 | done();
133 | });
134 |
135 | /**
136 | * JS Main
137 | */
138 | gulp.task('js:main', function (done) {
139 | return gulp.src([
140 | paths.js.input,
141 | paths.jsComponents.input
142 | ])
143 | .pipe(plumber({ errorHandler: onError }))
144 | .pipe(sourcemaps.init())
145 | .pipe(concat('main.min.js'))
146 | .pipe(uglify())
147 | .pipe(sourcemaps.write('./', {addComment: false}))
148 | .pipe(gulp.dest(paths.js.output))
149 | .pipe(browserSync.reload({stream:true}))
150 | done();
151 | });
152 |
153 | /**
154 | * Images
155 | */
156 | gulp.task('images', function (done) {
157 | return gulp.src([
158 | paths.img.input
159 | ], {
160 | 'dot': true // include hidden files
161 | })
162 | .pipe(changed(paths.img.output))
163 | .pipe(gulp.dest(paths.img.output))
164 | .pipe(browserSync.reload({stream:true}))
165 | done();
166 | });
167 |
168 | /**
169 | * Twig
170 | */
171 | gulp.task('twig', function (done) {
172 | return gulp.src(paths.twig.src)
173 | .pipe(plumber({
174 | errorHandler: function (error) {
175 | console.log(error.message);
176 | this.emit('end');
177 | }}))
178 | .pipe(foreach(function(stream,file){
179 | return stream
180 | .pipe(twig())
181 | }))
182 | .pipe(gulp.dest(paths.dist))
183 | done();
184 | });
185 |
186 | /**
187 | * Copy miscellaneous files
188 | */
189 | gulp.task('copy:misc', function (done) {
190 | return gulp.src([
191 | paths.misc.xml,
192 | paths.misc.txt
193 | ])
194 | .pipe(changed(paths.dist))
195 | .pipe(gulp.dest(paths.dist))
196 | .pipe(browserSync.reload({stream:true}))
197 | done();
198 | });
199 |
200 | /**
201 | * Task: Gulp Watch Sequence
202 | */
203 | gulp.task('watch-files', function () {
204 | watch(paths.img.input, function () {
205 | gulp.start('images');
206 | });
207 | watch(paths.sass.inputAll, function () {
208 | gulp.start('css');
209 | });
210 | watch(paths.js.input, function () {
211 | gulp.start('js:main');
212 | });
213 | watch(paths.jsComponents.input, function () {
214 | gulp.start('js:main');
215 | });
216 | watch(paths.jsVendor.input, function () {
217 | gulp.start('js:vendor');
218 | });
219 | watch(paths.twig.watch, function () {
220 | gulp.start('twig');
221 | });
222 | watch([paths.misc.xml, paths.misc.txt], function () {
223 | gulp.start('copy:misc');
224 | });
225 | });
226 |
227 | /**
228 | * Task: Gulp Default
229 | */
230 | gulp.task('default', function(done) {
231 | runSequence('build', [
232 | 'watch-files',
233 | 'browser-sync'
234 | ], done )
235 | });
236 |
237 | /**
238 | * Task: Gulp Build
239 | */
240 | gulp.task('build', function (done) {
241 | runSequence('clean:dist', [
242 | 'css',
243 | 'js:vendor',
244 | 'js:main',
245 | 'images',
246 | 'twig',
247 | 'copy:misc'
248 | ], done )
249 | })
250 |
251 | /**
252 | * Task: Gulp Watch
253 | */
254 | gulp.task('watch', function(done) {
255 | runSequence('watch-files', [
256 | 'browser-sync'
257 | ], done )
258 | });
259 |
260 | /**
261 | * Task: Gulp Deploy
262 | */
263 | gulp.task('deploy', function() {
264 | return gulp.src(paths.deploy)
265 | .pipe(ghPages());
266 | });
267 |
--------------------------------------------------------------------------------
/src/sass/vendor/_normalize.scss:
--------------------------------------------------------------------------------
1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in iOS.
9 | */
10 |
11 | html {
12 | line-height: 1.15; /* 1 */
13 | -webkit-text-size-adjust: 100%; /* 2 */
14 | }
15 |
16 | /* Sections
17 | ========================================================================== */
18 |
19 | /**
20 | * Remove the margin in all browsers.
21 | */
22 |
23 | body {
24 | margin: 0;
25 | }
26 |
27 | /**
28 | * Render the `main` element consistently in IE.
29 | */
30 |
31 | main {
32 | display: block;
33 | }
34 |
35 | /**
36 | * Correct the font size and margin on `h1` elements within `section` and
37 | * `article` contexts in Chrome, Firefox, and Safari.
38 | */
39 |
40 | h1 {
41 | font-size: 2em;
42 | margin: 0.67em 0;
43 | }
44 |
45 | /* Grouping content
46 | ========================================================================== */
47 |
48 | /**
49 | * 1. Add the correct box sizing in Firefox.
50 | * 2. Show the overflow in Edge and IE.
51 | */
52 |
53 | hr {
54 | box-sizing: content-box; /* 1 */
55 | height: 0; /* 1 */
56 | overflow: visible; /* 2 */
57 | }
58 |
59 | /**
60 | * 1. Correct the inheritance and scaling of font size in all browsers.
61 | * 2. Correct the odd `em` font sizing in all browsers.
62 | */
63 |
64 | pre {
65 | font-family: monospace, monospace; /* 1 */
66 | font-size: 1em; /* 2 */
67 | }
68 |
69 | /* Text-level semantics
70 | ========================================================================== */
71 |
72 | /**
73 | * Remove the gray background on active links in IE 10.
74 | */
75 |
76 | a {
77 | background-color: transparent;
78 | }
79 |
80 | /**
81 | * 1. Remove the bottom border in Chrome 57-
82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
83 | */
84 |
85 | abbr[title] {
86 | border-bottom: none; /* 1 */
87 | text-decoration: underline; /* 2 */
88 | text-decoration: underline dotted; /* 2 */
89 | }
90 |
91 | /**
92 | * Add the correct font weight in Chrome, Edge, and Safari.
93 | */
94 |
95 | b,
96 | strong {
97 | font-weight: bolder;
98 | }
99 |
100 | /**
101 | * 1. Correct the inheritance and scaling of font size in all browsers.
102 | * 2. Correct the odd `em` font sizing in all browsers.
103 | */
104 |
105 | code,
106 | kbd,
107 | samp {
108 | font-family: monospace, monospace; /* 1 */
109 | font-size: 1em; /* 2 */
110 | }
111 |
112 | /**
113 | * Add the correct font size in all browsers.
114 | */
115 |
116 | small {
117 | font-size: 80%;
118 | }
119 |
120 | /**
121 | * Prevent `sub` and `sup` elements from affecting the line height in
122 | * all browsers.
123 | */
124 |
125 | sub,
126 | sup {
127 | font-size: 75%;
128 | line-height: 0;
129 | position: relative;
130 | vertical-align: baseline;
131 | }
132 |
133 | sub {
134 | bottom: -0.25em;
135 | }
136 |
137 | sup {
138 | top: -0.5em;
139 | }
140 |
141 | /* Embedded content
142 | ========================================================================== */
143 |
144 | /**
145 | * Remove the border on images inside links in IE 10.
146 | */
147 |
148 | img {
149 | border-style: none;
150 | }
151 |
152 | /* Forms
153 | ========================================================================== */
154 |
155 | /**
156 | * 1. Change the font styles in all browsers.
157 | * 2. Remove the margin in Firefox and Safari.
158 | */
159 |
160 | button,
161 | input,
162 | optgroup,
163 | select,
164 | textarea {
165 | font-family: inherit; /* 1 */
166 | font-size: 100%; /* 1 */
167 | line-height: 1.15; /* 1 */
168 | margin: 0; /* 2 */
169 | }
170 |
171 | /**
172 | * Show the overflow in IE.
173 | * 1. Show the overflow in Edge.
174 | */
175 |
176 | button,
177 | input { /* 1 */
178 | overflow: visible;
179 | }
180 |
181 | /**
182 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
183 | * 1. Remove the inheritance of text transform in Firefox.
184 | */
185 |
186 | button,
187 | select { /* 1 */
188 | text-transform: none;
189 | }
190 |
191 | /**
192 | * Correct the inability to style clickable types in iOS and Safari.
193 | */
194 |
195 | button,
196 | [type="button"],
197 | [type="reset"],
198 | [type="submit"] {
199 | -webkit-appearance: button;
200 | }
201 |
202 | /**
203 | * Remove the inner border and padding in Firefox.
204 | */
205 |
206 | button::-moz-focus-inner,
207 | [type="button"]::-moz-focus-inner,
208 | [type="reset"]::-moz-focus-inner,
209 | [type="submit"]::-moz-focus-inner {
210 | border-style: none;
211 | padding: 0;
212 | }
213 |
214 | /**
215 | * Restore the focus styles unset by the previous rule.
216 | */
217 |
218 | button:-moz-focusring,
219 | [type="button"]:-moz-focusring,
220 | [type="reset"]:-moz-focusring,
221 | [type="submit"]:-moz-focusring {
222 | outline: 1px dotted ButtonText;
223 | }
224 |
225 | /**
226 | * Correct the padding in Firefox.
227 | */
228 |
229 | fieldset {
230 | padding: 0.35em 0.75em 0.625em;
231 | }
232 |
233 | /**
234 | * 1. Correct the text wrapping in Edge and IE.
235 | * 2. Correct the color inheritance from `fieldset` elements in IE.
236 | * 3. Remove the padding so developers are not caught out when they zero out
237 | * `fieldset` elements in all browsers.
238 | */
239 |
240 | legend {
241 | box-sizing: border-box; /* 1 */
242 | color: inherit; /* 2 */
243 | display: table; /* 1 */
244 | max-width: 100%; /* 1 */
245 | padding: 0; /* 3 */
246 | white-space: normal; /* 1 */
247 | }
248 |
249 | /**
250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
251 | */
252 |
253 | progress {
254 | vertical-align: baseline;
255 | }
256 |
257 | /**
258 | * Remove the default vertical scrollbar in IE 10+.
259 | */
260 |
261 | textarea {
262 | overflow: auto;
263 | }
264 |
265 | /**
266 | * 1. Add the correct box sizing in IE 10.
267 | * 2. Remove the padding in IE 10.
268 | */
269 |
270 | [type="checkbox"],
271 | [type="radio"] {
272 | box-sizing: border-box; /* 1 */
273 | padding: 0; /* 2 */
274 | }
275 |
276 | /**
277 | * Correct the cursor style of increment and decrement buttons in Chrome.
278 | */
279 |
280 | [type="number"]::-webkit-inner-spin-button,
281 | [type="number"]::-webkit-outer-spin-button {
282 | height: auto;
283 | }
284 |
285 | /**
286 | * 1. Correct the odd appearance in Chrome and Safari.
287 | * 2. Correct the outline style in Safari.
288 | */
289 |
290 | [type="search"] {
291 | -webkit-appearance: textfield; /* 1 */
292 | outline-offset: -2px; /* 2 */
293 | }
294 |
295 | /**
296 | * Remove the inner padding in Chrome and Safari on macOS.
297 | */
298 |
299 | [type="search"]::-webkit-search-decoration {
300 | -webkit-appearance: none;
301 | }
302 |
303 | /**
304 | * 1. Correct the inability to style clickable types in iOS and Safari.
305 | * 2. Change font properties to `inherit` in Safari.
306 | */
307 |
308 | ::-webkit-file-upload-button {
309 | -webkit-appearance: button; /* 1 */
310 | font: inherit; /* 2 */
311 | }
312 |
313 | /* Interactive
314 | ========================================================================== */
315 |
316 | /*
317 | * Add the correct display in Edge, IE 10+, and Firefox.
318 | */
319 |
320 | details {
321 | display: block;
322 | }
323 |
324 | /*
325 | * Add the correct display in all browsers.
326 | */
327 |
328 | summary {
329 | display: list-item;
330 | }
331 |
332 | /* Misc
333 | ========================================================================== */
334 |
335 | /**
336 | * Add the correct display in IE 10+.
337 | */
338 |
339 | template {
340 | display: none;
341 | }
342 |
343 | /**
344 | * Add the correct display in IE 10.
345 | */
346 |
347 | [hidden] {
348 | display: none;
349 | }
350 |
--------------------------------------------------------------------------------
/src/sass/base/_mixins.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Mixins
3 | */
4 |
5 | /**
6 | * Clearfix
7 | * Usage:
8 | @include clearfix;
9 | */
10 | @mixin clearfix() {
11 | &::after {
12 | display: block;
13 | clear: both;
14 | content: "";
15 | }
16 | }
17 |
18 | /**
19 | * Unstyled keeps list items block level, just removes default browser padding and list-style.
20 | * Usage:
21 | @include list-none;
22 | */
23 | @mixin list-none {
24 | list-style: none;
25 | padding-left: 0;
26 | }
27 |
28 | /**
29 | * Overlay
30 | * Usage
31 | @include overlay();
32 | */
33 | @mixin overlay() {
34 | position: absolute;
35 | top: 0;
36 | right: 0;
37 | bottom: 0;
38 | left: 0;
39 | }
40 |
41 | /**
42 | * Pseudo elements after / before
43 | * Usage
44 | @include pseudo;
45 | */
46 | @mixin pseudo($display: block, $position: absolute, $content: ''){
47 | content: $content;
48 | display: $display;
49 | position: $position;
50 | }
51 |
52 | /**
53 | * Set max width for an element and make it centered
54 | * Usage
55 | @include max-width(600px);
56 | */
57 | @mixin max-width($max-width) {
58 | max-width: $max-width;
59 | margin-right: auto;
60 | margin-left: auto;
61 | }
62 |
63 | /**
64 | * https://github.com/nicholasruggeri/px-to-rem-sass-mixin
65 | * Usage
66 | font-size: rem(20)
67 | margin: rem(40) rem(40);
68 | */
69 | @function strip-units($value) {
70 | @return ($value / ($value * 0 + 1));
71 | }
72 | @function rem($pxval) {
73 | @if not unitless($pxval) {
74 | $pxval: strip-units($pxval);
75 | }
76 | $base: 16px;
77 | @if not unitless($base) {
78 | $base: strip-units($base);
79 | }
80 | @return ($pxval / $base) * 1rem;
81 | }
82 |
83 | /**
84 | * Responsive font size for different media query breakpoints
85 | * Usage
86 | @include responsive-font-size(12px, 14px, 16px, 18px, 20px);
87 | @include responsive-font-size(xs, sm, md, lg, xl);
88 |
89 | * In case you want to omit the media query breakpoint please use ''
90 | e.g. @include responsive-font-size(1rem, '', '', 1.5rem, '', 2.5rem);
91 | */
92 | @mixin responsive-font-size($font-size-xs: null, $font-size-sm: null, $font-size-md: null, $font-size-lg: null, $font-size-xl: null) {
93 | @if ($font-size-xs != '') {
94 | font-size: $font-size-xs;
95 | }
96 | @if ($font-size-sm != '') {
97 | @include media-breakpoint-up(sm) {
98 | font-size: $font-size-sm;
99 | }
100 | }
101 | @if ($font-size-md != '') {
102 | @include media-breakpoint-up(md) {
103 | font-size: $font-size-md;
104 | }
105 | }
106 | @if ($font-size-lg != '') {
107 | @include media-breakpoint-up(lg) {
108 | font-size: $font-size-lg;
109 | }
110 | }
111 | @if ($font-size-xl != '') {
112 | @include media-breakpoint-up(xl) {
113 | font-size: $font-size-xl;
114 | }
115 | }
116 | }
117 |
118 | /**
119 | * Responsive spacing for different media query breakpoints
120 | * Usage
121 | @include responsive-space('mb', 10px, 20px, 30px, 40px, 50px);
122 | @include responsive-space('type, xs, sm, md, lg, xl);
123 |
124 | * In case you want to omit the media query breakpoint please use ''
125 | e.g. @include responsive-space('mb', 10px, '', '', 40px, 50px);
126 |
127 | Type:
128 |
129 | m : margin
130 | mt : margin-top
131 | mr : margin-right
132 | mb : margin-bottom
133 | ml : margin-left
134 | mx : (horizontal) margin-left and margin-right
135 | my : (vertical) margin-top and margin bottom
136 |
137 | p : padding
138 | pt : padding-top
139 | pr : padding-right
140 | pb : padding-bottom
141 | pl : padding-left
142 | px : (horizontal) padding-left and padding-right
143 | py : (vertical) padding-top and padding bottom
144 | */
145 | @mixin responsive-space($type: null, $space-xs: null, $space-sm: null, $space-md: null, $space-lg: null, $space-xl: null, $type_1: null, $type_2: null) {
146 | @if ($type == 'm') {
147 | $type: 'margin';
148 | }
149 | @if ($type == 'mt') {
150 | $type: 'margin-top';
151 | }
152 | @if ($type == 'mr') {
153 | $type: 'margin-right';
154 | }
155 | @if ($type == 'mb') {
156 | $type: 'margin-bottom';
157 | }
158 | @if ($type == 'ml') {
159 | $type: 'margin-left';
160 | }
161 | @if ($type == 'mx') {
162 | $type_1: 'margin-left';
163 | $type_2: 'margin-right';
164 | }
165 | @if ($type == 'my') {
166 | $type_1: 'margin-top';
167 | $type_2: 'margin-bottom';
168 | }
169 |
170 | @if ($type == 'p') {
171 | $type: 'padding';
172 | }
173 | @if ($type == 'pt') {
174 | $type: 'padding-top';
175 | }
176 | @if ($type == 'pr') {
177 | $type: 'padding-right';
178 | }
179 | @if ($type == 'pb') {
180 | $type: 'padding-bottom';
181 | }
182 | @if ($type == 'pl') {
183 | $type: 'padding-left';
184 | }
185 | @if ($type == 'px') {
186 | $type_1: 'padding-left';
187 | $type_2: 'padding-right';
188 | }
189 | @if ($type == 'py') {
190 | $type_1: 'padding-top';
191 | $type_2: 'padding-bottom';
192 | }
193 |
194 | @if ( ($type == 'mx') or ($type == 'my') or ($type == 'py') or ($type == 'px') ) {
195 | @if ($space-xs != '') {
196 | #{$type_1}: $space-xs;
197 | #{$type_2}: $space-xs;
198 | }
199 | @if ($space-sm != '') {
200 | @include media-breakpoint-up(sm) {
201 | #{$type_1}: $space-sm;
202 | #{$type_2}: $space-sm;
203 | }
204 | }
205 | @if ($space-md != '') {
206 | @include media-breakpoint-up(md) {
207 | #{$type_1}: $space-md;
208 | #{$type_2}: $space-md;
209 | }
210 | }
211 | @if ($space-lg != '') {
212 | @include media-breakpoint-up(lg) {
213 | #{$type_1}: $space-lg;
214 | #{$type_2}: $space-lg;
215 | }
216 | }
217 | @if ($space-xl != '') {
218 | @include media-breakpoint-up(xl) {
219 | #{$type_1}: $space-xl;
220 | #{$type_2}: $space-xl;
221 | }
222 | }
223 | } @else {
224 | @if ($space-xs != '') {
225 | #{$type}: $space-xs;
226 | }
227 | @if ($space-sm != '') {
228 | @include media-breakpoint-up(sm) {
229 | #{$type}: $space-sm;
230 | }
231 | }
232 | @if ($space-md != '') {
233 | @include media-breakpoint-up(md) {
234 | #{$type}: $space-md;
235 | }
236 | }
237 | @if ($space-lg != '') {
238 | @include media-breakpoint-up(lg) {
239 | #{$type}: $space-lg;
240 | }
241 | }
242 | @if ($space-xl != '') {
243 | @include media-breakpoint-up(xl) {
244 | #{$type}: $space-xl;
245 | }
246 | }
247 | }
248 | }
249 |
250 | /**
251 | * Responsive size for different media query breakpoints
252 | * Usage
253 | @include responsive-size('h', 10px, 20px, 30px, 40px, 50px);
254 | @include responsive-size('type, xs, sm, md, lg, xl);
255 |
256 | * In case you want to omit the media query breakpoint please use ''
257 | e.g. @include responsive-size('h', 10px, '', '', 40px, 50px);
258 |
259 | Type:
260 |
261 | h : height,
262 | minh : min-height,
263 | maxh : max-height,
264 | w : width,
265 | minw : min-width,
266 | maxw : max-width
267 | */
268 | @mixin responsive-size($type: null, $size-xs: null, $size-sm: null, $size-md: null, $size-lg: null, $size-xl: null) {
269 | @if ($type == 'h') {
270 | $type: 'height';
271 | }
272 | @if ($type == 'w') {
273 | $type: 'width';
274 | }
275 | @if ($type == 'minh') {
276 | $type: 'min-height';
277 | }
278 | @if ($type == 'minw') {
279 | $type: 'min-width';
280 | }
281 | @if ($type == 'maxh') {
282 | $type: 'max-height';
283 | }
284 | @if ($type == 'maxw') {
285 | $type: 'max-width';
286 | }
287 | @if ($size-xs != '') {
288 | #{$type}: $size-xs;
289 | }
290 | @if ($size-sm != '') {
291 | @include media-breakpoint-up(sm) {
292 | #{$type}: $size-sm;
293 | }
294 | }
295 | @if ($size-md != '') {
296 | @include media-breakpoint-up(md) {
297 | #{$type}: $size-md;
298 | }
299 | }
300 | @if ($size-lg != '') {
301 | @include media-breakpoint-up(lg) {
302 | #{$type}: $size-lg;
303 | }
304 | }
305 | @if ($size-xl != '') {
306 | @include media-breakpoint-up(xl) {
307 | #{$type}: $size-xl;
308 | }
309 | }
310 | }
311 |
--------------------------------------------------------------------------------