├── .browserslistrc ├── .gitignore ├── .npmignore ├── .editorconfig ├── src ├── library │ ├── _animations.scss │ ├── _variables.scss │ └── _mixins.scss ├── tabsy.scss └── index.html ├── package.json ├── LICENSE ├── dist ├── tabsy.css └── index.html ├── README.md └── Gruntfile.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | last 2 versions 2 | not dead -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,css,scss}] 11 | indent_style = tab -------------------------------------------------------------------------------- /src/library/_animations.scss: -------------------------------------------------------------------------------- 1 | @keyframes (showTab) { 2 | from { 3 | opacity: 0; 4 | transform: translateY(10px); 5 | } 6 | 7 | to { 8 | opacity: 1; 9 | transform: translateY(0); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/library/_variables.scss: -------------------------------------------------------------------------------- 1 | // Base Colors 2 | $tabActiveBgColor: #fff; 3 | $tabActiveTextColor: #5a5243; 4 | $tabNectiveBgColor: #5a5243; 5 | $tabNectiveTextColor: #F5F5F5; 6 | 7 | // Breakpoint 8 | $breakpoint: 768px; 9 | 10 | // Transition 11 | $transitionSpeed: 200ms; -------------------------------------------------------------------------------- /src/library/_mixins.scss: -------------------------------------------------------------------------------- 1 | // keyframes 2 | @mixin keyframes($animation-name) { 3 | 4 | @-webkit-keyframes #{$animation-name} { 5 | 6 | @content; 7 | 8 | } 9 | 10 | @keyframes #{$animation-name} { 11 | 12 | @content; 13 | 14 | } 15 | 16 | } 17 | 18 | // animation 19 | @mixin animation($args) { 20 | 21 | -webkit-animation: #{$args}; 22 | animation: #{$args}; 23 | 24 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tabsy-css", 3 | "title": "Tabsy CSS", 4 | "description": "Simple tabs toggler component written in pure CSS with no dependencies", 5 | "version": "1.0.1", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Robert Velickovski", 9 | "email": "roby@rvdizajn.com" 10 | }, 11 | "keywords": [ 12 | "tabs", 13 | "css", 14 | "scss", 15 | "sass", 16 | "simple", 17 | "toggle", 18 | "dependency-free", 19 | "lightweight" 20 | ], 21 | "homepage": "https://github.com/robiveli/tabsy-css", 22 | "devDependencies": { 23 | "autoprefixer": "^9.8.6", 24 | "grunt": "^1.0.1", 25 | "grunt-contrib-watch": "^1.0.0", 26 | "grunt-html-build": "^0.7.1", 27 | "grunt-postcss": "^0.9.0", 28 | "grunt-sass": "^4.0.0", 29 | "load-grunt-tasks": "^3.5.2", 30 | "postcss": "^8.5.6", 31 | "sass": "^1.89.2" 32 | }, 33 | "scripts": { 34 | "dev": "grunt watch", 35 | "build": "grunt build" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Robert Velickovski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dist/tabsy.css: -------------------------------------------------------------------------------- 1 | @keyframes (showTab) { 2 | from { 3 | opacity: 0; 4 | transform: translateY(10px); 5 | } 6 | to { 7 | opacity: 1; 8 | transform: translateY(0); 9 | } 10 | } 11 | .tabsy > button { 12 | width: 100%; 13 | font-family: inherit; 14 | font-size: 100%; 15 | margin: 0; 16 | outline: 0; 17 | border: 0; 18 | vertical-align: baseline; 19 | box-sizing: border-box; 20 | background: transparent; 21 | } 22 | .tabsy > .tabButton { 23 | display: block; 24 | margin-top: 1px; 25 | background: #5a5243; 26 | color: #F5F5F5; 27 | text-align: center; 28 | transition: all 200ms ease-in-out; 29 | } 30 | .tabsy > input { 31 | display: none; 32 | } 33 | .tabsy > input:checked + label + .tab { 34 | display: block; 35 | } 36 | @keyframes showTab {} 37 | .tabsy > .tab { 38 | background: #fff; 39 | display: none; 40 | } 41 | @media screen and (min-width: 768px) { 42 | .tabsy { 43 | display: flex; 44 | flex-wrap: wrap; 45 | } 46 | .tabsy > .tabButton { 47 | order: 1; 48 | align-items: flex-start; 49 | cursor: pointer; 50 | } 51 | .tabsy > input:checked + label { 52 | background: #fff; 53 | color: #5a5243; 54 | } 55 | .tabsy > .tab { 56 | order: 2; 57 | } 58 | } -------------------------------------------------------------------------------- /src/tabsy.scss: -------------------------------------------------------------------------------- 1 | // Library 2 | @use "library/variables" as *; 3 | @use "library/mixins" as *; 4 | @use "library/animations" as *; 5 | 6 | .tabsy { 7 | > button { 8 | width: 100%; 9 | font-family: inherit; 10 | font-size: 100%; 11 | margin: 0; 12 | outline: 0; 13 | border: 0; 14 | vertical-align: baseline; 15 | box-sizing: border-box; 16 | background: transparent; 17 | } 18 | 19 | > .tabButton { 20 | display: block; 21 | margin-top: 1px; 22 | background: $tabNectiveBgColor; 23 | color: $tabNectiveTextColor; 24 | text-align: center; 25 | transition: all $transitionSpeed ease-in-out; 26 | } 27 | 28 | > input { 29 | display: none; 30 | 31 | &:checked + label { 32 | & + .tab { 33 | display: block; 34 | 35 | > .content { 36 | @include keyframes(showTab); 37 | } 38 | } 39 | } 40 | } 41 | 42 | > .tab { 43 | background: $tabActiveBgColor; 44 | display: none; 45 | } 46 | 47 | @media screen and (min-width: $breakpoint) { 48 | display: flex; 49 | flex-wrap: wrap; 50 | 51 | > .tabButton { 52 | order: 1; 53 | align-items: flex-start; 54 | cursor: pointer; 55 | } 56 | 57 | > input { 58 | &:checked + label { 59 | background: $tabActiveBgColor; 60 | color: $tabActiveTextColor; 61 | } 62 | } 63 | 64 | > .tab { 65 | order: 2; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tabsy CSS 2 | 3 | ## Simple tabs toggler component written in pure CSS with no dependencies 4 | 5 | ### Install 6 | 7 | With npm: 8 | 9 | ```sh 10 | npm install tabsy-css 11 | ``` 12 | 13 | ### Usage 14 | 15 | Include css: 16 | 17 | ```sh 18 | 19 | ``` 20 | 21 | Initial required structure, place any content you want within the tabs: 22 | 23 | ```sh 24 |
25 | 26 | 27 |
28 |
29 | Content One 30 |
31 |
32 | 33 | 34 |
35 |
36 | Content Two 37 |
38 |
39 | 40 | 41 |
42 |
43 | Content Three 44 |
45 |
46 |
47 | ``` 48 | 49 | ### Demo 50 | 51 | Demo available [here](http://robiveli.github.io/tabsy-css/). 52 | 53 | ### Options 54 | 55 | Default css settings are placed in `library/_variables.scss`: 56 | 57 | ### Note 58 | 59 | Based on Flexbox feature. Where not supported simple fallback is applied. 60 | 61 | ### License 62 | 63 | Tabsy CSS is licensed under the [MIT license](http://opensource.org/licenses/MIT). 64 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | const sass = require("sass"); 2 | const autoprefixer = require("autoprefixer"); 3 | 4 | module.exports = function (grunt) { 5 | grunt.initConfig({ 6 | settings: { 7 | srcPath: "src/", 8 | distPath: "dist/", 9 | }, 10 | 11 | sass: { 12 | options: { 13 | implementation: sass, // Add this line 14 | }, 15 | app: { 16 | files: [ 17 | { 18 | expand: true, 19 | cwd: "<%= settings.srcPath %>", 20 | src: ["**/*.scss"], 21 | dest: "<%= settings.distPath %>", 22 | ext: ".css", 23 | }, 24 | ], 25 | options: { 26 | outputStyle: "compressed", 27 | sourceMap: false, 28 | precision: 5, 29 | }, 30 | }, 31 | }, 32 | 33 | postcss: { 34 | options: { 35 | processors: [autoprefixer()], 36 | }, 37 | dist: { 38 | src: "<%= settings.distPath %>*.css", 39 | }, 40 | }, 41 | 42 | htmlbuild: { 43 | build: { 44 | expand: true, 45 | cwd: "<%= settings.srcPath %>", 46 | src: "**/*.html", 47 | dest: "<%= settings.distPath %>", 48 | }, 49 | }, 50 | 51 | watch: { 52 | scss: { 53 | expand: true, 54 | files: ["<%= settings.srcPath %>sass/**/*.scss"], 55 | tasks: ["sass", "postcss"], 56 | options: { 57 | spawn: false, 58 | }, 59 | }, 60 | html: { 61 | files: ["<%= settings.srcPath %>*.html"], 62 | tasks: ["htmlbuild"], 63 | options: { 64 | spawn: false, 65 | }, 66 | }, 67 | }, 68 | }); 69 | 70 | require("load-grunt-tasks")(grunt); 71 | 72 | grunt.registerTask("default", ["watch"]); 73 | grunt.registerTask("build", ["sass", "postcss", "htmlbuild"]); 74 | }; 75 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tabsy - Simple tabs toggler component written in pure CSS with no 6 | dependencies 7 | 8 | 9 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 181 | 182 | 183 | 184 |
185 |

Tabsy [CSS]

186 |

187 | Simple and lightweight tabs toggler component written in pure 188 | CSS 189 |

190 | 191 |
192 | 193 | 194 | 195 |
196 |
197 |

Heading 1

198 |

199 | Lorem Ipsum is simply dummy text of the printing and 200 | typesetting industry. 201 |

202 |

203 | Lorem Ipsum has been the industry's standard dummy 204 | text ever since the 1500s, when an unknown printer 205 | took a galley of type and scrambled it to make a 206 | type specimen book. It has survived not only five 207 | centuries, but also the leap into electronic 208 | typesetting, remaining essentially unchanged. 209 |

210 |
211 |
212 | 213 | 214 | 215 | 216 |
217 |
218 |

Heading 2

219 |

220 | Lorem Ipsum has been the industry's standard dummy 221 | text ever since the 1500s, when an unknown printer 222 | took a galley of type and scrambled it to make a 223 | type specimen book. It has survived not only five 224 | centuries, but also the leap into electronic 225 | typesetting, remaining essentially unchanged. 226 |

227 |

228 | Lorem Ipsum has been the industry's standard dummy 229 | text ever since the 1500s, when an unknown printer 230 | took a galley of type and scrambled it to make a 231 | type specimen book. It has survived not only five 232 | centuries, but also the leap into electronic 233 | typesetting, remaining essentially unchanged. 234 |

235 |

236 | Lorem Ipsum has been the industry's standard dummy 237 | text ever since the 1500s, when an unknown printer 238 | took a galley of type and scrambled it to make a 239 | type specimen book. It has survived not only five 240 | centuries, but also the leap into electronic 241 | typesetting, remaining essentially unchanged. 242 |

243 |
244 |
245 | 246 | 247 | 248 | 249 |
250 |
251 |

Heading 3

252 |

253 | Lorem Ipsum has been the industry's standard dummy 254 | text ever since the 1500s, when an unknown printer 255 | took a galley of type and scrambled it to make a 256 | type specimen book. It has survived not only five 257 | centuries, but also the leap into electronic 258 | typesetting, remaining essentially unchanged. 259 |

260 |

261 | Lorem Ipsum has been the industry's standard dummy 262 | text ever since the 1500s, when an unknown printer 263 | took a galley of type and scrambled it to make a 264 | type specimen book. It has survived not only five 265 | centuries, but also the leap into electronic 266 | typesetting, remaining essentially unchanged. Lorem 267 | Ipsum has been the industry's standard dummy text 268 | ever since the 1500s, when an unknown printer took a 269 | galley of type and scrambled it to make a type 270 | specimen book. It has survived not only five 271 | centuries, but also the leap into electronic 272 | typesetting, remaining essentially unchanged. Lorem 273 | Ipsum has been the industry's standard dummy text 274 | ever since the 1500s, when an unknown printer took a 275 | galley of type and scrambled it to make a type 276 | specimen book. It has survived not only five 277 | centuries, but also the leap into electronic 278 | typesetting, remaining essentially unchanged. 279 |

280 |
281 |
282 |
283 |
284 | 285 | 286 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tabsy - Simple tabs toggler component written in pure CSS with no 6 | dependencies 7 | 8 | 9 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 181 | 182 | 183 | 184 |
185 |

Tabsy [CSS]

186 |

187 | Simple and lightweight tabs toggler component written in pure 188 | CSS 189 |

190 | 191 |
192 | 193 | 194 | 195 |
196 |
197 |

Heading 1

198 |

199 | Lorem Ipsum is simply dummy text of the printing and 200 | typesetting industry. 201 |

202 |

203 | Lorem Ipsum has been the industry's standard dummy 204 | text ever since the 1500s, when an unknown printer 205 | took a galley of type and scrambled it to make a 206 | type specimen book. It has survived not only five 207 | centuries, but also the leap into electronic 208 | typesetting, remaining essentially unchanged. 209 |

210 |
211 |
212 | 213 | 214 | 215 | 216 |
217 |
218 |

Heading 2

219 |

220 | Lorem Ipsum has been the industry's standard dummy 221 | text ever since the 1500s, when an unknown printer 222 | took a galley of type and scrambled it to make a 223 | type specimen book. It has survived not only five 224 | centuries, but also the leap into electronic 225 | typesetting, remaining essentially unchanged. 226 |

227 |

228 | Lorem Ipsum has been the industry's standard dummy 229 | text ever since the 1500s, when an unknown printer 230 | took a galley of type and scrambled it to make a 231 | type specimen book. It has survived not only five 232 | centuries, but also the leap into electronic 233 | typesetting, remaining essentially unchanged. 234 |

235 |

236 | Lorem Ipsum has been the industry's standard dummy 237 | text ever since the 1500s, when an unknown printer 238 | took a galley of type and scrambled it to make a 239 | type specimen book. It has survived not only five 240 | centuries, but also the leap into electronic 241 | typesetting, remaining essentially unchanged. 242 |

243 |
244 |
245 | 246 | 247 | 248 | 249 |
250 |
251 |

Heading 3

252 |

253 | Lorem Ipsum has been the industry's standard dummy 254 | text ever since the 1500s, when an unknown printer 255 | took a galley of type and scrambled it to make a 256 | type specimen book. It has survived not only five 257 | centuries, but also the leap into electronic 258 | typesetting, remaining essentially unchanged. 259 |

260 |

261 | Lorem Ipsum has been the industry's standard dummy 262 | text ever since the 1500s, when an unknown printer 263 | took a galley of type and scrambled it to make a 264 | type specimen book. It has survived not only five 265 | centuries, but also the leap into electronic 266 | typesetting, remaining essentially unchanged. Lorem 267 | Ipsum has been the industry's standard dummy text 268 | ever since the 1500s, when an unknown printer took a 269 | galley of type and scrambled it to make a type 270 | specimen book. It has survived not only five 271 | centuries, but also the leap into electronic 272 | typesetting, remaining essentially unchanged. Lorem 273 | Ipsum has been the industry's standard dummy text 274 | ever since the 1500s, when an unknown printer took a 275 | galley of type and scrambled it to make a type 276 | specimen book. It has survived not only five 277 | centuries, but also the leap into electronic 278 | typesetting, remaining essentially unchanged. 279 |

280 |
281 |
282 |
283 |
284 | 285 | 286 | --------------------------------------------------------------------------------