New design

This commit is contained in:
Miek Gieben
2017-07-24 15:47:09 +00:00
parent d6410e36b2
commit 2f7c5e4f5e
181 changed files with 17798 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
all:
hugo -d /opt/www/new.coredns.io
.PHONY: clean
clean:
rm -rf /opt/www/new.coredns.io/*
.PHONY: test
test:
hugo server
+41
View File
@@ -0,0 +1,41 @@
# coredns.io
Purpose:
1. What is CoreDNS?
1. How to use it?
1. How to get involved and get help.
The website is created with HUGO, you'll need to download and install that if you want to locally
work on the website. For creating new content it is not needed.
We have three types of pages.
* Home - `themes/coredns/layouts/index.html`
* Blog/News/Documentation - `content/blog/*` (depends on params, see `archetypes`)
* Middleware - `content/middleware/*` and `content/exmiddleware/*`
Any blog post you'll tag with 'documentation' will also become visible on the "Documentation"
link on the website.
Releases should be tagged with 'release = "number" and `data/coredns.toml` should be updated
with the number.
`data/subtext.toml` controls the buttons for "Docs", "Middleware" and "External Middleware".
Create:
* new release: `hugo new -k release blog/coredns-<number>.md`
* new blog: `hugo new -k blog blog/coredns-<number>.md`
* new blog that will also be documentation: `hugo new -k doc blog/coredns-<number>.md`
## Colors
Dark: #280071 (40, 0, 113)
Middle: #5F259F (95, 37, 159)
Light: #8246AF (130, 70, 175)
## Popup
See the top-level (i.e. not in the themes directory) layout/partials/popup.html for adjusting the
text.
+8
View File
@@ -0,0 +1,8 @@
+++
title = ""
description = ""
tags = [""]
draft = false
date = "{{ .Date }}"
author = "joe"
+++
+6
View File
@@ -0,0 +1,6 @@
---
title: "{{ replace .TranslationBaseName "-" " " | title }}"
date: {{ .Date }}
draft: true
---
+8
View File
@@ -0,0 +1,8 @@
+++
title = ""
description = ""
tags = ["Documentation"]
draft = false
date = "{{ .Date }}"
author = "joe"
+++
+9
View File
@@ -0,0 +1,9 @@
+++
title = ""
description = ""
tags = [""]
draft = false
release = "001"
date = "{{ .Date }}"
author = "joe"
+++
+83
View File
@@ -0,0 +1,83 @@
#!/bin/bash
# Copy the <middleware>/README.md to middleware/<mddleware>.md, add
# some Hugo meta data end let Hugo render it.
weight=1
tags="middleware"
function header() {
local middleware=$1
local title=$2
local description=$3
echo "+++"
echo "title = \"$title\""
echo "description = \"$description\""
echo "weight = $weight"
echo "tags = [ " \"$tags\" "," \"$middleware\" "]"
echo "categories = [ \"middleware\" ]"
echo "date = \"$(date --iso-8601=seconds)\""
echo "+++"
}
function parse() {
local file="$1"
local middleware=$(basename $(dirname $file))
local state="title"
local description=""
local rest=""
while IFS= read -r line; do
if [[ $state == "title" ]]; then
title=${line#\# }
state="skip"
continue
fi
if [[ $state == "skip" ]]; then
[[ -z "$line" ]] && continue
state="description"
fi
if [[ $state == "description" ]]; then
if [[ -z "$line" ]]; then
state="rest"
continue
fi
description+="$line "
fi
if [[ $state == "rest" ]]; then
# stupid shell to-readd newline
rest+="$line
"
fi
done < $file
header $middleware "$title" "$description"
echo
echo "$rest"
}
if [[ -z "$1" ]]; then
echo $0: Need containing directory of CoreDNS middleware
exit 1
fi
content="../content/middleware"
if [[ ! -e "$content" ]]; then
echo $0: Need to be run from the site\'s bin directory
exit 1
fi
for dir in "$1"/*; do
file=$dir/README.md
if [[ ! -e $file ]]; then continue; fi
middleware=$(basename $(dirname $file))
echo $middleware.md >&2
echo $file >&2
parse $file > $content/$middleware.md
weight=$((weight + 1))
done
+59
View File
@@ -0,0 +1,59 @@
baseurl = "https://new.coredns.io/" # CHANGE WHEN DONE TODO(miek)
languageCode = "en-us"
title = "CoreDNS: DNS and Service Discovery"
copyright = "CoreDNS - All Rights Reserved"
theme = "coredns"
[permalinks]
blog = "/:year/:month/:day/:title/"
page = "/:title/"
[params]
popup = "" # enable with non empty string to show banner on home page
logo = "/images/CoreDNS_Colour_Icon.png"
twitter = "https://twitter.com/corednsio"
github = "https://github.com/coredns/coredns"
email = "info@coredns.io"
[params.authors.miek]
name = "Miek Gieben"
location = "London"
email = "miek@miek.nl"
twitter = "https://twitter.com/miekg"
github = "https://github.com/miekg"
[params.authors.john]
name = "John Belamaric"
location = "Washington DC"
email = "jbelamaric@infoblox.com"
twitter = "https://twitter.com/johnbelamaric"
github = "https://github.com/johnbelamaric"
[params.authors.chris]
name = "Chris O'Haver"
location = "Annapolis, MD"
email = "cohaver@infoblox.com"
twitter = "https://twitter.com/chrisohaver"
github = "https://github.com/chrisohaver"
[[menu.main]]
name = "Middleware"
weight = -200
url = "/middleware/"
[[menu.main]]
name = "External Middleware"
weight = -190
url = "/exmiddleware/"
external = ""
[[menu.main]]
name = "Blog"
weight = -180
url = "/blog/"
[[menu.main]]
name = "Docs"
weight = -160
url = "/tags/documentation/"
[[menu.main]]
name = "Community"
weight = -120
url = "/community/"
View File
+34
View File
@@ -0,0 +1,34 @@
+++
date = "2017-07-23T21:28:13Z"
description = "How to add a link to external middleware?"
tags = ["Middleware", "External", "Add"]
title = "Add External Middleware"
author = "miek"
+++
If you want to have your external middleware listed here send an email to the coredns-discuss email
list with the details or create [a pull request](https;//github.com/coredns/coredns.io).
In that email or pull request you'll need to add a file to `content/blog/exmiddleware/` that looks
like this:
~~~ txt
+++
title = "<middleware name>"
description = "*<middleware name>* is a ..."
weight = 10
tags = [ "middleware" , "<middleware name>" ]
categories = [ "middleware", "external" ]
date = "2017-07-22T12:37:19+01:00"
repo = "link-to-your-repo"
home = "link-to-your-homepage"
+++
The *<middleware name>* middleware is a ...
<rest of your README.md>
~~~
See [example.md for an example]
(https://github.com/coredns/new.coredns.io/blob/master/content/exmiddleware/example.md) on how to do
this.
+32
View File
@@ -0,0 +1,32 @@
+++
date = "2017-03-02T18:00:00Z"
description = "CoreDNS is now a Cloud Native Computing Foundation project."
tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS"]
title = "Why CNCF for CoreDNS?"
author = "john"
+++
CoreDNS has been accepted into the [Cloud Native Computing Foundation](https://cncf.io) as an
inception project! We figure some of you may be wondering why we proposed CoreDNS as a CNCF
project, so we wrote this blog entry.
Our goal is to make CoreDNS *the* cloud-native DNS server and service discovery solution. The
CNCF as an organization is focused on the advancement of cloud-native architectures. So, to us,
this is an excellent match. Service discovery is a key component of the [CNCF cloud-native landscape](https://raw.githubusercontent.com/cncf/landscape/master/landscape/CloudNativeLandscape_v0.9.3.jpg), and this is
a role in which CoreDNS excels.
We hope this added visibility will attract more users and contributors to grow the project. And we
will be active in promoting CoreDNS, like in the up coming
[CloudNative/KubeCon](http://events.linuxfoundation.org/events/cloudnativecon-and-kubecon-europe).
CNCF provides a lot of support - evidence of which you can already see in our new logo, which was
designed by the team at the Linux Foundation (of which CNCF is a part). As a CNCF project, we will
have space at CloudNativeCon/KubeCon and other events to interact with users and get feedback on
how the community is using CoreDNS. Additionally, we gain access to deep experience and wide ranging use
cases of the CNCF end user community. This helps inform the future development of CoreDNS, ensuring
that we move in directions that solve meaningful problems in cloud-native architectures.
We are also planning to take advantage of the [CNCF cluster](https://www.cncf.io/cluster), which will
allow us to really push the scale limits of CoreDNS when operating against large Kubernetes clusters
or other high-scale environments. We need that kind of battle-testing to ensure CoreDNS becomes the
best option for cloud-native DNS and service discovery.
+61
View File
@@ -0,0 +1,61 @@
+++
date = "2016-09-18T11:40:37+01:00"
description = "CoreDNS-001 Release Notes"
release = "001"
tags = ["Release", "001", "Notes"]
title = "CoreDNS-001 Release"
author = "miek"
+++
CoreDNS-001 has been [released](https://github.com/coredns/coredns/releases). This is the first
release! It provides a complete DNS server, that also does DNSSEC and is useful for service
discovery in cloud setups.
# What is CoreDNS?
[CoreDNS](https://coredns.io) is a DNS server that started its life as a fork of the [Caddy
web(!)server](https://caddyserver.com).
It chains [middleware](https://github.com/coredns/coredns/tree/master/middleware),
where each middleware implements some DNS feature. CoreDNS is a complete replacement
(with more features, and maybe less bugs) for [SkyDNS](https://github.com/skynetservices/skydns).
It is also useful as a normal DNS server, featuring DNSSEC, on-the-fly signing and zone transfers.
# What is New
CoreDNS is now a (the first!) server type plugin in Caddy - this means we can leverage a lot of code
from Caddy without having to fork (and maintain) it all. By doing so we were able to remove 9000
lines of code from CoreDNS.
The core (ghe!) of CoreDNS is now in a good shape. Future work will focus on making the
middleware better, e.g. the proxy implementation is slow and needs to be
[faster](https://github.com/coredns/coredns/issues/184).
## New Middlewares
* There is now a [specific
middleware](https://github.com/coredns/coredns/tree/master/middleware/kubernetes) to deal with [Kubernetes](https://kubernetes.io).
* The *bind* [middleware](https://github.com/coredns/coredns/tree/master/middleware/bind) allows you to bind to a specific IP address, instead of using the wildcard
address.
* A *whoami* [middleware](https://github.com/coredns/coredns/tree/master/middleware/whoami) reports
back your address and port.
* All other middlewares are reworked to fit in the new plugin framework from Caddy version 0.9 (and
up).
The *whoami* middleware is also used when CoreDNS starts up and can't find a Corefile.
# Contributors
The following people helped with getting this release done:
Cricket Liu, elcore, Félix Cantournet, Ilya Dmitrichenko, Joe Blow, Lee, Matt Layher,
Michael Richmond, Miek Gieben, pixelbender, Yong Tang.
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) and start coding!
# Documentation and Help
The forum on <https://forum.caddyserver.com> has section for
[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers.
Or use [Twitter](https://twitter.com/corednsio).
+108
View File
@@ -0,0 +1,108 @@
+++
date = "2016-10-19T19:09:32Z"
description = "CoreDNS-002 Release Notes"
release = "002"
tags = ["Release", "002", "Notes"]
title = "CoreDNS-002 Release"
author = "miek"
+++
CoreDNS-002 has been [released](https://github.com/coredns/coredns/releases)!
CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature.
## What is New
* `-port` was renamed to `-dns.port` to avoid clashing with Caddy's `-port` (which was renamed to
`http.port`).
* Lumberjack logger was removed, this means no built in log rotation; use an external tool for that.
* Brushed up GoDoc for all packages.
* Brushed up all READMEs to be more standard and look like manual page.
* Golint-ed and go vet-ed the code - these can now (somewhat) useful tools before submitting PRs.
* Add more tests and show test coverage on submitting/PRs.
* Various Corefile parsing bugs fixed, better syntax error detection.
## Middleware improvements:
* middleware/root: a root middleware, same usage as in [Caddy](https://caddyserver.com/docs/root).
See middleware/root/README.md for its use in CoreDNS.
This makes stanzas like this shorter:
~~~ txt
.:53 {
file /etc/coredns/zones/db.example.net example.net
file /etc/coredns/zones/db.example.org example.org
file /etc/coredns/zones/db.example.com example.com
}
~~~
Can be written as:
~~~ txt
.:53 {
root /etc/coredns/zones
file db.example.net example.net
file db.example.org example.org
file db.example.com example.com
}
~~~
* middleware/auto: similar to the *file* middleware, but automatically picks up new zones.
The following Corefile will load all zones found under `/etc/coredns/org` and be authoritative
for `.org.`:
~~~ txt
.:53 {
auto org {
directory /etc/coredns/org
}
}
~~~
* middleware/file: handle wildcards better.
* middleware/kubernetes: TLS support for kubernetes and other improvements.
* middleware/cache: use an LRU cache to make it memory bounded. Added more option to have more
control on what is cached and for how long. The cache stanza was extended:
~~~ txt
cache {
success CAPACITY [TTL]
denial CAPACITY [TTL]
}
~~~
See middleware/cache/README.md for more details.
* middleware/dnssec: replaced go-cache with golang-lru in dnssec. Also adds a `cache_capacity`.
option in dnssec middleware so that the capacity of the LRU cache could be specified in the config
file.
* middleware/logging: allow a response classs to be specified on log on responses matching the name *and*
the response class. For instance only log denials for example.com:
~~~ txt
log example.com stdout {
class denial
}
~~~
* middleware/proxy: performance improvements.
# Contributors
The following people helped with getting this release done:
Chris O'Haver,
Manuel de Brito Fontes,
Miek Gieben,
Shawn Smith,
Silas Baronda,
Yong Tang,
Zhipeng Jiang.
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/)
and start coding!
# Documentation and Help
The forum on <https://forum.caddyserver.com> has section for
[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers.
Use [Twitter](https://twitter.com/corednsio), or file an issue.
+54
View File
@@ -0,0 +1,54 @@
+++
date = "2016-11-11T16:38:32Z"
description = "CoreDNS-003 Release Notes"
release = "003"
tags = ["Release", "003", "Notes"]
title = "CoreDNS-003 Release"
author = "miek"
+++
CoreDNS-003 has been [released](https://github.com/coredns/coredns/releases)!
CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature.
# What is New
## Core
Refused queries are properly logged and exported if metrics are enabled.
## Middleware improvements
* *proxy*: allow `/etc/resolv.conf` to be used in the configuration.
* *metrics*: add tests and normalize some of the metrics. Removed the AXFR size metrics.
* *cache*: Added size and capacity of the cache (for both `denial` and `success` cache types).
Don't cache meta data records and zone transfers.
* *dnssec*: metrics were unused, hooked them up: export size and capacity of the signature cache.
* *loadbalance*: balance MX records as well.
* *auto*: numerous bugfixes.
* *file*: fix data race in reload process and also reload a zone when it is `mv`ed (newly created) into place.
Also rewrite the zone lookup algorithm and be more standards compliant, esp. in the area of DNSSEC, wildcards and empty-non-terminals; handle secure delegations.
* *kubernetes*: vender the k8s dependency and updates to be compatible with Kubernetes 1.4 and 1.5.
Multiple cleanups and fixes. Kubernetes services can now be resolved.
# Contributors
The following people helped with getting this release done:
Ben Kochie,
Chris O'Haver,
John Belamaric,
Jonathan Dickinson,
Manuel Alejandro de Brito Fontes,
Michael Grosser,
Miek Gieben,
Yong Tang.
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/)
and start coding!
# Documentation and Help
The forum on <https://forum.caddyserver.com> has section for
[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers.
Use [Twitter](https://twitter.com/corednsio), or file an issue.
+49
View File
@@ -0,0 +1,49 @@
+++
date = "2017-01-01T10:30:31Z"
description = "CoreDNS-004 Release Notes"
release = "004"
tags = ["Release", "004", "Notes"]
title = "CoreDNS-004 Release"
author = "miek"
+++
CoreDNS-004 has been [released](https://github.com/coredns/coredns/releases/tag/v004)!
CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature.
# What is New
## Core
We are now also releasing an ARM build that can run on Raspberry Pi.
## Middleware improvements
* *file|auto*: resolve external CNAME when an upstream (new option) is specified.
* *file|auto*: allow port numbers for transfer from/to to be specified.
* *file|auto*: include zone's NSset in positive responses.
* *auto*: close files and don't leak file descriptors.
* *httpproxy*: new middleware that proxies to <https://dns.google.com> and resolves your requests over an encrypted connection. This middleware will probably be morphed into proxy at some point in the feature. Consider it experimental for the time being.
* *metrics*: `reponse_size_bytes` and `request_size_bytes` export the actual length of the packet, not the advertised bufsize.
* *log*: `{size}` is now the length in bytes of the request, `{rsize}` for the reply. Default logging is changed to show both.
# Contributors
The following people helped with getting this release done:
Chris O'Haver,
Dmytro Kislov,
John Belamaric,
Mark Nevill,
Michael Grosser,
Miek Gieben,
Yong Tang.
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/)
and start coding!
# Documentation and Help
The forum on <https://forum.caddyserver.com> has section for
[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers.
Use [Twitter](https://twitter.com/corednsio), or file an issue.
+69
View File
@@ -0,0 +1,69 @@
+++
date = "2017-02-09T18:50:31Z"
description = "CoreDNS-005 Release Notes"
tags = ["Release", "005", "Notes"]
release = "005"
title = "CoreDNS-005 Release"
author = "miek"
+++
CoreDNS-005 has been [released](https://github.com/coredns/coredns/releases/tag/v005)!
CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature.
# What is New
# Core
A way to configure (external) middleware was added. Edit `middleware.cfg` and do a `go gen && go
build` and your middleware has been added. This allows for out-of-tree middleware to be easily
added. Documentation can be found in
[middleware.cfg](https://github.com/coredns/coredns/blob/master/middleware.cfg).
## Middleware improvements
### New
* *erratic*: a new middleware that can drop queries, limited in the current functionality, but useful for testing.
* *trace*: a new middleware that implements OpenTracing-based tracing using Zipkin.
### Improvements/changes
* *proxy*: fix a bug when a connection hangs and never gets release (#467)
* *proxy*: Fold *httpproxy* into it, which is now a normal proxy with a special `protocol`. For
Monitoring an extra label was added: `proxy_proto` that shows the protocol used (`dns` or `https_google`).
See the [proxy README.md](https://github.com/coredns/coredns/blob/master/middleware/proxy/README.md) for details.
* *httpproxy*: removed because functionality is moved to *proxy*.
* *kubernetes*: Now implements the full
[Kubernetes DNS Specification](https://github.com/kubernetes/dns/blob/master/docs/specification.md),
including regular and headless services, endpoint hostnames, A, SRV, and PTR records.
* *kubernetes*: Implements the `pod` type for requests in both a Kube-DNS compatible mode
(`insecure`) and a mode which validates that the IP in question belongs to a pod in the specified
namespace (`verified`)
* *kubernetes*: Simplified the configuration of reverse zones. Instead of listing the zones in the
zone list, you can just add a list of CIDRs using the `cidrs` option.
* *rewrite*: allow rewriting more bits of the incoming packet. This required some backward
*incompatible* changes, e.g. a new **FIELD** keyword is now required. See the
[rewrite README.md](https://github.com/coredns/coredns/blob/master/middleware/rewrite/README.md) for details.
# Contributors
The following people helped with getting this release done:
Bob Wasniak,
Chris O'Haver,
devnev,
Dmytro Kislov,
John Belamaric,
Miek Gieben,
Yong Tang.
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/)
and start coding!
# Documentation and Help
The forum on <https://forum.caddyserver.com> has section for
[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers.
Use [Twitter](https://twitter.com/corednsio), or file an issue.
+60
View File
@@ -0,0 +1,60 @@
+++
date = "2017-02-22T21:26:11Z"
description = "CoreDNS-006 Release Notes"
tags = ["Release", "006", "Notes"]
release = "006"
title = "CoreDNS-006 Release"
author = "miek"
+++
CoreDNS-006 has been [released](https://github.com/coredns/coredns/releases/tag/v006)!
CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature.
# What is New
# Core
Move CoreDNS to <https://github.com/coredns/coredns> together with several other repos. This will be
the new home for CoreDNS development.
Fixed:
* Fix hot-reloading. This would fail with `[ERROR] SIGUSR1: listen tcp :53: bind: address already in
use`.
* Allow removal of core middleware, see comments in
[middleware.cfg](https://github.com/miekg/coredns/blob/master/middleware.cfg).
## Middleware improvements
### New
* *reverse* middleware: allows CoreDNS to respond dynamicly to an PTR request and the related
A/AAAA request.
### Improvements/changes
* *proxy* a new `protocol`: `grpc`: speak DNS over gRPC. Server side impl. resides [in this out of
tree middleware](https://github.com/coredns/grpc).
* *file* additional section processing for MX and SRV queries.
* *prometheus* fix hot reloading
* *trace* various improvements
# Contributors
The following people helped with getting this release done:
John Belamaric,
Miek Gieben,
Richard Hillmann,
Yong Tang,
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/)
and start coding!
# Documentation and Help
The forum on <https://forum.caddyserver.com> has section for
[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers.
Use [Twitter](https://twitter.com/corednsio), or file an issue.
+76
View File
@@ -0,0 +1,76 @@
+++
date = "2017-05-03T19:26:11Z"
description = "CoreDNS-007 Release Notes"
release = "007"
tags = ["Release", "007", "Notes"]
title = "CoreDNS-007 Release"
author = "miek"
+++
CoreDNS-007 has been [released](https://github.com/coredns/coredns/releases/tag/v007)!
CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature.
# News
CoreDNS is accepted as an inception project by the [CNCF](https://cncf.io)! Which means a lot to us.
See [this blog post](https://blog.coredns.io/2017/03/02/why-cncf-for-coredns/) on why we wanted/did this.
Because of this we moved repos: <https://github.com/coredns> is the main overarching repo. There is
an automatic redirect in place from the old repo.
And... We have a new logo! We're also discussion a website redesign for <https://coredns.io> and
this blog.
Back to the release.
# Core
* `ServeDNS` is extended to take a context. This allows (for instance) tracing to start at an earlier entrypoint.
* gRPC and TLS are made first class citizens. See [the zone
specification](https://github.com/coredns/coredns/blob/master/README.md#zone-specification) on how
to use it. TL;DR using `grpc://` makes the server talk gRPC. The `tls` directive is used to
specify TLS certifcates.
* Zipkin tracing can be enabled for all middleware.
# Middleware
* *rewrite* now allows you to add or modify EDNS0 local or NSID options. The framework is in place to add additional EDNS0 types in the future.
* *etcd* when no upstreams are defined won't default to using 8.8.8.8, 8.8.4.4; it just does not resolve external names in that case.
* *erratic* now can also delay queries and send queries with Truncated set.
* *metrics* will happily start as many (different) listeners as you want (if you really need that).
* *startup* and *shutdown* allow for command to be run during startup or shutdown. These directly use the code from Caddy, see [Caddy's docs](https://caddyserver.com/docs/startup).
* *kubernetes* now implements a `fallthrough` option to pass queries that would result in NXDOMAIN
to the next middleware, even if the query is in the cluster domain. This enables custom DNS
entries in the cluster domain (as long as they do not overlap with a normal Kubernetes record). To
facilitate this the middleware ordering is also altered to put *kubernetes* in the chain before
other backends.
* *cache* will no longer cache RRSIGs that will expire while cached.
# Contributors
The following people helped with getting this release done:
Chris Aniszczyk,
Chris O'Haver,
Christoph Görn,
Dominic,
John Belamaric,
Jonathan Boulle,
Michael,
Michael S. Fischer,
Miek Gieben,
Yong Tang,
Yue Ko.
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/)
and start coding!
## Community
You find CoreDNS's community in the following places:
- Mailing list/group: <coredns-discuss@googlegroups.com>
- Slack: #coredns on <https://slack.cncf.io>
- Twitter: [@corednsio](https://twitter.com/corednsio)
- Github: <https://github.com/coredns/coredns>
+73
View File
@@ -0,0 +1,73 @@
+++
date = "2017-06-14T22:52:11Z"
description = "CoreDNS-008 Release Notes"
release = "008"
tags = ["Release", "008", "Notes"]
title = "CoreDNS-008 Release"
author = "john"
+++
CoreDNS-008 has been [released](https://github.com/coredns/coredns/releases/tag/v008)!
CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature.
Release v008 has a lot of content, with new middleware and major features added to existing middleware.
Please note there is an *incompatible* change to the `log` directive - it now only logs to `stdout` and so
only allows `stdout` as the file name (which of course may be omitted).
# Core
* `-log` flag was changed into a boolean as all logging will be written to standard output.
# Middleware
## New
* *hosts* allows CoreDNS to read a `/etc/hosts` styled file and generate responses from that.
* *debug* can disable the `panic/recover` that is enabled by default. Mostly useful for testing/non-prod use cases to generate stack traces.
## Updates
* *chaos* now returns the correct `version.bind` `TXT` record.
* *kubernetes*
* Now returns a proper NS record for the cluster domain
* Supports `ExternalName` services, which was an oversight in the 1.0.0 version of the [Kubernetes dns spec](https://github.com/kubernetes/dns/blob/master/docs/specification.md)
* Now supports federation records
* Has had some other bug fixes.
* *file*
* Now supports DNAME [RFC 6672](https://tools.ietf.org/html/rfc6672)
* Refuse to load a zone without a SOA record.
* *file, auto* don't reload a zone when the SOA's serial hasn't changed.
* *secondary* now behaves properly if queried before the zone has been transferred
* *log, errors* output everything to *stdout* and let `journald` or `docker` (or whatever) that care of further handling. This is backwards **incompatible** change wrt to the Corefile: `log query.log` will return an error.
* *cache* got a new cache implementation to be more scalable and a new `prefetch` option for fetching records before the TTL expires.
* *proxy* does not use `singleinflight` anymore, removing a potential bottleneck on the single mutex in that implementation; it now forwards *all* queries it get to the upstream nameserver.
# Contributors
The following people helped with getting this release done:
Chris Aniszczyk,
Chris O'Haver,
cricketliu,
Eric Yan,
John Belamaric,
Jonas Östanbäck,
Manuel Alejandro de Brito Fontes,
Miek Gieben,
Pat Moroney,
Yong Tang
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/)
and start coding!
## Community
You find CoreDNS's community in the following places:
- Mailing list/group: <coredns-discuss@googlegroups.com>
- Slack: #coredns on <https://slack.cncf.io>
- Twitter: [@corednsio](https://twitter.com/corednsio)
- Github: <https://github.com/coredns/coredns>
+54
View File
@@ -0,0 +1,54 @@
+++
date = "2017-07-13T22:52:11Z"
release = "009"
description = "CoreDNS-009 Release Notes"
tags = ["Release", "009", "Notes"]
title = "CoreDNS-009 Release"
author = "miek"
+++
CoreDNS-009 has been [released](https://github.com/coredns/coredns/releases/tag/v009)!
CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature.
Release v009 is mostly a bugfix release, with a few new features in the middleware.
# Core
No changes.
# Middleware
* *secondary*: fix functionality and improve matching of notify queries.
* *cache*: fix data race.
* *proxy*: async healthchecks.
* *reverse*: new option `wildcard` that also catches all subdomains of a template.
* *kubernetes*: experimental new option `autopath` that optimizes the search path and ndots
combinatorial explosion, so clients with a large search path and high ndots will get a reply on
the first query.
# Contributors
The following people helped with getting this release done:
Athir Nuaimi,
Chris O'Haver,
ghostflame,
jremond,
Mia Boulay,
Miek Gieben,
Ning Xie,
Roman Mazur,
Yong Tang.
If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/)
and start coding!
## Community
You find CoreDNS's community in the following places:
- Mailing list/group: <coredns-discuss@googlegroups.com>
- Slack: #coredns on <https://slack.cncf.io>
- Twitter: [@corednsio](https://twitter.com/corednsio)
- Github: <https://github.com/coredns/coredns>
+21
View File
@@ -0,0 +1,21 @@
+++
date = "2016-09-29T06:18:40Z"
description = "CoreDNS can now be downloaded from Caddy's download page"
tags = ["Caddy", "Bugs", "Questions"]
title = "CoreDNS and Caddy"
author = "miek"
+++
[Caddy 0.9.3](https://forum.caddyserver.com/t/caddy-0-9-3-released/725) is released. On it's
[download page](https://caddyserver.com/download) you can now select the "DNS plugin" to be added
to Caddy! This is really nice and a culmination of all the work that has been put in to make this
happen.
Note that if you select this option you get a binary that is *both* a DNS and webserver, during
startup you can select between the two with `-type=dns|http` flag.
The CoreDNS developers will still provide their own (DNS only) binaries over [at
github](https://github.com/coredns/coredns/releases).
Note that we *also* have a CoreDNS category on the [Caddy
forum](https://forum.caddyserver.com/c/coredns) where you can ask questions. Bugs and feature
requests are probably better directed to our [github](https://github.com/coredns/coredns).
+23
View File
@@ -0,0 +1,23 @@
+++
date = "2017-02-23T18:12:12Z"
title = "History of CoreDNS in four posts"
tags = ["CoreDNS","History","Caddy", "Documentation"]
description = "How CoreDNS Came Into Existence"
author = "miek"
+++
> Yes, at some point CoreDNS was actually a forked webserver doing DNS.
This blog posts detail some of the early history of CoreDNS.
Pondering if I should create someting ala Caddy, but then for DNS. I didn't have a name,
so it was "Caddy DNS" (or Daddy as some point): <https://miek.nl/2016/March/10/caddy-dns/>.
This idea was good enough that I actually tried it out, resulting in the first queries answered
by "Caddy DNS": <https://miek.nl/2016/March/14/first-light/>.
Started to believe this "Caddy DNS" might actually be a thing I would work on:
<https://miek.nl/2016/March/17/caddy-dns-update/>
Officially announcing CoreDNS: <https://miek.nl/2016/March/18/announcing-coredns/> and dropping
the name "Caddy DNS".
+185
View File
@@ -0,0 +1,185 @@
+++
date = "2016-12-19T08:00:24Z"
description = "A introduction into writing middleware for CoreDNS"
tags = ["middleware", "coredns", "plugins", "documentation"]
title = "Writing Middleware for CoreDNS"
author = "miek"
+++
As CoreDNS uses Caddy for setting up and using middleware, the process of writing middleware is
remarkably [similar](https://github.com/mholt/caddy/wiki/Writing-a-Plugin:-Directives). This post
slightly reworks (and simplifies in some cases) those pages.
A new middleware adds new functionality to CoreDNS, i.e. *caching*, *metrics* and basic *zone* file
serving are all middlewares.
If you want to write a new middleware and want it to be included by default, i.e. merged in the code
base please open an [issue](https://github.com/coredns/coredns/issues) first to discuss initial design
and other things that may come up.
## How to Register a CoreDNS Middleware
[Caddy](https://caddyserver.com) supports different type of plugins, CoreDNS, for instance,
registers itself as a Caddy server type plugin. CoreDNS currently supports one type of plugins;
a *middleware*.
Start a new Go package with an init function. Then register your middleware:
```go
import "github.com/mholt/caddy"
func init() {
caddy.RegisterPlugin("foo", caddy.Plugin{
ServerType: "dns",
Action: setup,
})
}
```
Every middleware must have a name, `foo`, in this case. The *ServerType* must be `dns`. The *Action*
speficied here is to say it will call a function called `setup` whenever the *directive* `foo` is
encountered in the Corefile.
### The Setup Function
The *Action* field of the `caddy.Plugin` struct is what makes a directive plugin unique. This is the
function to run when CoreDNS is parsing and executing the Corefile.
The action is simply a function that takes a caddy.Controller and returns an error:
(We use [middleware.Error](https://godoc.org/github.com/coredns/coredns/middleware#Error) to prefix
returned error with `middleware/foo: ` to improve error reporting).
``` go
func setup(c *caddy.Controller) error {
if err != nil {
return middleware.Error("foo", err)
}
return nil
}
```
It is the responsibility of the setup function to parse the directive's tokens and configure itself.
The [Controller struct](https://godoc.org/github.com/mholt/caddy#Controller)
makes this quite easy. If we expect a line in the Corefile such as:
```
foo gizmo
```
We can get the value of the first argument ("foobar") like so:
```go
for c.Next() { // Skip the directive name.
if !c.NextArg() { // Expect at least one value.
return c.ArgErr() // Otherwise it's an error.
}
value := c.Val() // Use the value.
}
```
You parse the tokens present for your directive by iterating over `c.Next()` which is true as long
as there are more tokens to parse. Since a directive may appear multiple times, you must iterate
over `c.Next()` to get all the appearances of your directive and consume the first token (which is the
directive name).
### Adding to CoreDNS
To plug your middleware into CoreDNS, import it. This is done in
[core/coredns.go](https://github.com/coredns/coredns/blob/master/core/coredns.go):
```go
import _ "your/plugin/package/path/here"
```
This makes CoreDNS compile your plugin, but it is still not available, so the second step is
to add it to [directives.go](https://github.com/coredns/coredns/blob/master/core/dnsserver/directives.go):
Add the name (`foo`) of your middleware at the end of the file in the `directives` string slice.
Note the ordering is important, because this is determines how the plugins are chained together.
## How DNS Middleware Works in CoreDNS
Check out the [godoc for the middleware
package](http://godoc.org/github.com/coredns/coredns/middleware). The most important type is
[middleware.Handler](https://godoc.org/github.com/coredns/coredns/middleware#Handler).
A `Handler` is a function that handles a DNS request. CoreDNS will do all the bookkeeping of setting
up an DNS server for you, but you need to implement these two types.
### Writing a Handler
`middleware.Handler` is an interface similar to `http.Handler` except that it deals with DNS and the
`ServeDNS` method returns `(int, error)`. The `int` is the DNS rcode, and the `error` is one that
should be handled and/or logged. Read the
[middleware.md](https://github.com/coredns/coredns/blob/master/middleware.md) doc for more details
about these return values.
Handlers are usually a struct with at least one field, the next Handler in the chain:
```go
type MyHandler struct {
Next middleware.Handler
}
```
To implement the `middleware.Handler` interface, we write a method called `ServeDNS`.
This method is the actual handler function, and, unless it fully handles the request by itself, it
should call the next handler in the chain:
```go
func (h MyHandler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
return h.Next.ServeDNS(ctx, w, r)
}
```
The interface also needs a method `func Name() string`, this is mainly used to see if an middleware
is active, i.e. the *auto* middleware used this to detect if *metrics* are active and if so, adds
updates the zone info.
```go
func (h MyHandler) Name() string { return "foo" }
```
That's all there is to it.
## How to Add the Handler to CoreDNS
So, back in your setup function. You've just parsed the tokens and set up your middleware handler
with all the proper configuration:
```go
func setup(c *caddy.Controller) error {
for c.Next() {
// Get configuration.
}
// Now what?
}
```
To chain in your new handler, get the config for the current site from the dnsserver package.
Then wrap your handler in a middleware function:
```go
cfg := dnsserver.GetConfig(c)
mid := func(next middleware.Handler) middleware.Handler {
return MyHandler{Next: next}
}
cfg.AddMiddleware(mid)
```
And you're done! Of course, in this example, we simply allocated a `MyHandler` with no special
configuration. It doesn't really matter as long as you chain in the `next` handler properly!
## Examples
Simple examples of middleware that can be found in CoreDNS are:
* [root](https://godoc.org/github.com/coredns/coredns/middleware/root); does not register itself as
a middleware. It simply performs some setup.
* [chaos](https://godoc.org/github.com/coredns/coredns/middleware/chaos); a DNS middleware that
responds to `CH txt version.bind` requests.
**Don't forget: the best documentation is the [godoc](https://godoc.org/github.com/coredns/coredns)
and the [code](https://github.com/coredns/coredns) itself!**
+65
View File
@@ -0,0 +1,65 @@
+++
date = "2016-10-13T08:50:13Z"
description = "Which middleware will handle a query?"
tags = ["Corefile", "Query", "Routing", "Documentation"]
title = "Query Routing"
author = "miek"
+++
Quiz time, in the following Corefile:
~~~ txt
. {
proxy . 8.8.8.8:53
file db.example.com
}
~~~
Will a query for `www.google.com` be handled by the *proxy* or the *file* middleware? Answer below.
What does this Corefile actually say? It specifies that queries for root (`.`) and *everything*
below it (so for all domain names) we should enter this stanza.
Next *all* queries should be forwarded to 8.8.8.8:53.
Then because the *file* middleware **does not** specify what zones should be answered from the
`db.example.com` file, the toplevel one applies, which is root (`.`)
So we are left with a situation where both middlewares will be called for the same names (which can
be perfectly valid for middleware that calls other chained-in middleware).
But *proxy* **will not** call *file* because the query will be answered and done with after
the middleware exists - the same is true for the opposite direction.
To look what into what happens here we have to look the [directives
ordering](https://github.com/coredns/coredns/blob/master/core/dnsserver/directives.go#L75):
~~~
...
"dnssec",
"file",
"secondary",
"etcd",
"kubernetes",
"proxy",
"whoami"
...
~~~
And we see that *file* is first and *proxy* comes somewhat later. This means that in the example
above *all* queries are routed to the *file* middleware. It will happily answer those with SERVFAIL,
because it probably can't find `www.google.com` in a file that will mostly have `*.example.com`
names in it.
In order to fix this, we should either have to separate stanza or specify the origin(s) for the
*file* middleware:
~~~ txt
. {
proxy . 8.8.8.8:53
file db.example.com example.com
}
~~~
To preempt a feature request: Yes, it would be nice of CoreDNS can detect and warn about this (it
does not do this now).
+102
View File
@@ -0,0 +1,102 @@
+++
date = "2017-07-23T21:28:13Z"
description = "How does the Corefile work?"
tags = ["Corefile", "Documentation"]
title = "Corefile Explained"
author = "miek"
+++
The `Corefile` is CoreDNS's configuration file. It defines:
* What servers listen on what ports.
* For which zone each server is authoritative.
* What middleware is loaded in a server.
To explain more, let take a look at this "Corefile":
~~~ txt
ZONE:[PORT] {
[MIDDLEWARE]...
}
~~~
* **ZONE** defines the zone this server. The optional **PORT** defaults to 53, if not given (or
whatever the `-dns.port` flag has as a value.
* **MIDDLEWARE** defines the middleware we want to load. This is optional as well, but as server
with no middleware will just return SERVFAIL for all queries.
So this is a minimum Corefile:
~~~ txt
. { }
~~~
That defines a server to listen on port 53 and make it authoritative for the root zone *and*
everything below. Let's define another server that is authoritative for `.` (root zone) and load
that:
~~~ txt
. { }
. { }
~~~
This will make CoreDNS exit with an error:
~~~
2017/07/23 20:39:10 cannot serve dns://.:53 - zone already defined for dns://.:53
~~~
Why? Because we already defined a server *on the same port* for this zone. If we change the port
number on the second server and thereby creating *another* server, it is OK:
~~~ txt
. { }
.:54 { }
~~~
When defining a new zone, you either create a new server, or add it to an existing one - but you can
redefine the middleware for it. Here we define *one* server that handles two zones; that potentially
chain different middleware:
~~~ txt
example.org {
whoami
}
org {
whoami
}
~~~
Note that most specific zone wins when a query comes in, so any `example.org` queries are going
through the middleware defined for `example.org` above. The rest is handled by `.`.
## Default Corefile
When CoreDNS starts up and can't find a Corefile, it will load a default one, defined as
~~~ txt
. {
whoami
}
~~~
## Non Default Protocols
Listening on TLS and for gRPC? Use:
~~~ txt
tls://example.org grpc://example.org {
# ...
}
~~~
Specifying ports works in the same way, here when listening for gRPC packets.
~~~ txt
grpc://example.org:1443 {
# ...
}
~~~
## Also See
The Corefile is parsed like a [Caddyfile](https://caddyserver.com/docs/caddyfile).
+165
View File
@@ -0,0 +1,165 @@
+++
date = "2017-05-08T20:01:00Z"
description = "Creating custom DNS entries inside or outside the cluster domain using CoreDNS"
tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Custom", "DNS", "Documentation"]
title = "Custom DNS Entries For Kubernetes"
author = "john"
+++
As described in our [previous post](https://blog.coredns.io/2017/03/01/coredns-for-kubernetes-service-discovery-take-2/),
CoreDNS can be used in place of Kube-DNS for service discovery in Kubernetes clusters. Because of the flexible architecture
of CoreDNS, this can enable some interesting use cases. In this blog, we'll show how to solve a common problem - creating
custom DNS entries for your services.
There are a couple of different possiblities here:
* [Making an alias](https://github.com/kubernetes/kubernetes/issues/39792) for an external name
* [Dynamically adding services to another domain](https://github.com/kubernetes/dns/issues/55), without running another server
* Adding an arbitrary entry inside the cluster domain
CoreDNS can solve all of these use cases. Let's start with the first one, which is pretty common. In this situation, you
want to be able to use the same name for a given service, whether you are accessing it inside or outside the cluster. This
is helpful, for example, when using TLS certificates that are bound to that name.
Suppose we have a service, `foo.default.svc.cluster.local` that is available to outside clients as `foo.example.com`.
That is, when looked up outside the cluster, `foo.example.com` will resolve to the load balancer VIP - the external
IP address for the service. Inside the cluster, it will resolve to the same thing, and so using this name internally
will cause traffic to hairpin - travel out of the cluster and then back in via the external IP. Instead, we want it
to resolve to the internal ClusterIP, avoiding the hairpin.
To do this in CoreDNS, we make use of the `rewrite` middleware. This middleware can modify a query before it is sent
down the chain to whatever backend is going to answer it. Recall the `Corefile` (CoreDNS configuration file) we
used in the last blog:
~~~ txt
.:53 {
errors
log stdout
health
kubernetes cluster.local {
cidrs 10.0.0.0/24
}
proxy . /etc/resolv.conf
cache 30
}
~~~
To get the behavior we want, we just need to add a rewrite rule mapping `foo.example.com` to `foo.default.svc.cluster.local`:
~~~ txt
.:53 {
errors
log stdout
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local {
cidrs 10.0.0.0/24
}
proxy . /etc/resolv.conf
cache 30
}
~~~
Once we add that to the `ConfigMap` via `kubectl edit` or `kubectl apply`, we have to let CoreDNS know that the `Corefile`
has changed. You can send it a `SIGUSR1` to tell it to reload graceful - that is, without loss of service:
~~~ txt
$ kubectl exec -n kube-system coredns-980047985-g2748 -- kill -SIGUSR1 1
~~~
Running our test pod, we can see this works:
~~~ txt
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.default.svc.cluster.local has address 10.0.0.72
/ # host bar.example.com
Host bar.example.com not found: 3(NXDOMAIN)
/ #
~~~
That's all there is to solving the first problem.
The second problem is just as easy. Here, we just want to be able to serve DNS entries out of a different zone
than the cluster domain. Since CoreDNS is a general-purpose DNS server, there are many other ways
to serve up zones than just the `kubernetes` middleware. For simplicity, we'll use the `file` middleware along
with another `ConfigMap` entry to satisfy this use case. However, you could use the `etcd` middleware to store services
directly within an etcd instance, or the `auto` middleware to manage a set of zones (very nice when used along
with [git-sync](https://github.com/kubernetes/git-sync)).
To create the new zone, we need to modify the `coredns.yaml` we have been using to create an additional file
in the pod. To do this we have to edit the `ConfigMap` by adding a `file` line to the `Corefile`, and also
by adding another key, `example.db`, for the zone file:
~~~ yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log stdout
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local {
cidrs 10.0.0.0/24
}
file /etc/coredns/example.db example.org
proxy . /etc/resolv.conf
cache 30
}
example.db: |
; example.org test file
example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600
example.org. IN NS b.iana-servers.net.
example.org. IN NS a.iana-servers.net.
example.org. IN A 127.0.0.1
a.b.c.w.example.org. IN TXT "Not a wildcard"
cname.example.org. IN CNAME www.example.net.
service.example.org. IN SRV 8080 10 10 example.org.
~~~
and we also need to edit the `volumes` section of the `Pod` template spec:
~~~ yaml
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
- key: example.db
path: example.db
~~~
Once we apply this using `kubectl apply -f`, a new CoreDNS pod will be built, because of the new file
in the volume. Later changes to the file won't require a new pod, just a graceful restart like we did before.
Let's take a look:
~~~ txt
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.default.svc.cluster.local has address 10.0.0.72
/ # host example.org
example.org has address 127.0.0.1
/ #
~~~
Perfect! We can now edit that `ConfigMap` and send `SIGUSR1` any time we want to add entries to `example.org`. Of course,
as mentioned earlier, we could also use the `etcd` backend and avoid the hassle of modifying the `ConfigMap` and
sending the signal.
This brings us to the last problem. That one can be solved using the new support for `fallthrough` in the `kubernetes`
middleware. This functionality has been added in the recently released version 007 of CoreDNS - we'll come back with
another blog soon show how to use it.
+252
View File
@@ -0,0 +1,252 @@
+++
date = "2017-03-01T20:23:48Z"
description = "How to add middleware to CoreDNS; a tutorial"
tags = ["Middleware", "Howto", "Tutorial", "Documentation"]
title = "How to Add Middleware to CoreDNS"
author = "miek"
+++
CoreDNS is a DNS server that chains middleware. Middleware is defined as a method `ServeDNS()` that
gets a request and either responds to the client or passes it on to the next middleware. If none of
the middleware handle the request a default response of SERVFAIL is returned.
This blog post details how to add middleware to CoreDNS. We're using the example of the *whoami*
middleware which is a CoreDNS middleware and loaded by default if nothing is specified.
> Note all the code examples here are in Go because CoreDNS is written in the Go language.
First question should be: "What should my middleware do?". In the case of the *whoami* middleware
its purpose is to echo back the client's IP (IPv4 or IPv6), the transport used ("tcp" or "udp") and
the request port number.
Next question is: "What is the name of this new middleware?" Try to find a short, descriptive name
for this. In this case, we already had a (good) name: *whoami*.
## Middleware
A middleware consists of a number of parts:
1. The registration of the middleware
2. The setup function that parses the *whoami* directive and
possible options from the Corefile
3. The `ServeDNS()` and `Name()` methods
After we've defined the parts, we can:
4. Hook it up
5. Use it
# 1. Registration
Typically a middleware has a file called `setup.go` that handles the registration.
In there, the `init` function should look like:
~~~ go
func init() {
caddy.RegisterPlugin("whoami", caddy.Plugin{
ServerType: "dns",
Action: setupWhoami,
})
}
~~~
First you see that we're using `caddy.RegisterPlugin` which makes perfectly sense, because
CoreDNS uses the [Caddy](https://caddyserver.com) server framework. The first argument is the name
of the directive as used in the Corefile.
The `ServerType` is "dns" because CoreDNS is a DNS server; Caddy supports HTTP servers as well. The
`Action` is the name of the setup function that takes care of the parsing of the Corefile. Its job
is to return a type that implements the `middleware.Handler` interface.
So whenever the Corefile parser sees "whoami", `setupWhoami` is called.
# 2. Setup function
Because the *whoami* directive does not allow for any options, the setup function is relatively
simple:
~~~ go
func setupWhoami(c *caddy.Controller) error {
c.Next() // 'whoami'
if c.NextArg() {
return middleware.Error("whoami", c.ArgErr())
}
dnsserver.GetConfig(c).AddMiddleware(func(next middleware.Handler) middleware.Handler {
return Whoami{}
})
return nil
}
~~~
We use the `*caddy.Controller` to receive tokens from the Corefile and act upon them. Here we only
check if there is nothing specified after the token `whoami`. If you need to do more there are
`c.Val()`, `c.Args()` and [friends](https://godoc.org/github.com/mholt/caddy/caddyfile#Dispenser).
The full `setup.go` for *whoami* is [here](https://github.com/miekg/coredns/blob/master/middleware/whoami/setup.go).
Note that you should test the parsing as well, see
[setup_test.go](https://github.com/miekg/coredns/blob/master/middleware/whoami/setup_test.go).
# 3. ServeDNS() and Name()
Let's start with the trivial `Name()` method which is used (mainly) to see if the metrics
middleware is loaded. CoreDNS does by this by name. The method just returns the string `whoami`.
~~~ go
// Name implements the Handler interface.
func (wh Whoami) Name() string { return "whoami" }
~~~
Next, the meat of the whole thing, the `ServeDNS` method. We will look at this method line by line.
~~~
// ServeDNS implements the middleware.Handler interface.
func (wh Whoami) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
state := request.Request{W: w, Req: r}
~~~
As seen the function gets a couple of parameters of which `w` is the client side: writing to `w`
returns a response to the client. As you will see below all interesting properties of the client
connection can be retrieved from the
[dns.ResponseWriter](https://godoc.org/github.com/miekg/dns#ResponseWriter). `r` is the incoming
query. The `ServeDNS` method returns an integer and/or an error. The values the integer can take are
the DNS RCODEs, dns.RcodeServerFailure, dns.RcodeNotImplemented, dns.RcodeSuccess, etc..
A successful return value indicates the middleware has written to the client.
`request.Request` is a helper struct that abstracts and caches some client-side properties, like
EDNS0 records and the DNSSEC OK bit.
Next we setup the reply message:
~~~ go
a := &dns.Msg{}
a.SetReply(r)
a.Compress = true
a.Authoritative = true
~~~
We create a new message and copy the relevant bits from the incoming reply to the one we're planning
to return. We fiddle with some message bits and turn on message compression.
Then we are going to inspect the incoming message via the `state` helper struct to see what we
should return.
~~~ go
ip := state.IP()
var rr dns.RR
switch state.Family() {
case 1:
rr = &dns.A{}
rr.(*dns.A).Hdr = dns.RR_Header{Name: state.QName(),
Rrtype: dns.TypeA, Class: state.QClass()}
rr.(*dns.A).A = net.ParseIP(ip).To4()
case 2:
rr = &dns.AAAA{}
rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: state.QName(),
Rrtype: dns.TypeAAAA, Class: state.QClass()}
rr.(*dns.AAAA).AAAA = net.ParseIP(ip)
}
~~~
`IP()` returns the IP address of the client. `Family()` returns the IP version used. Depending on the
family we either create a A or AAAA record with the client's address. Note we don't specify a TTL
meaning it will be zero; indicating these records should not be cached.
Next we want to encode the client's source port and transport protocol used.
~~~go
srv := &dns.SRV{}
srv.Hdr = dns.RR_Header{Name: "_" + state.Proto() + "." + state.QName(),
Rrtype: dns.TypeSRV, Class: state.QClass()}
port, _ := strconv.Atoi(state.Port())
srv.Port = uint16(port)
srv.Target = "."
~~~
SRV records are ideal for that. The domain names are either prefixed with `_tcp` or `_udp`, and the
SRV record's port number re-used to echo back the clients's port number, meaning we create
something like this: `_tcp.example.org. 0 IN SRV 0 0 <portNr>`.
In the last bit of this method we create the full message and send it:
~~~go
a.Extra = []dns.RR{rr, srv}
state.SizeAndDo(a)
w.WriteMsg(a)
return 0, nil
~~~
First we add the two created resource records (`rr` and `srv`) to the additional section of the
answer message: `a.Extra`.
Then we call `state.SizeOnDo(a)` which will set the correct EDNS0 record on the message and handle
setting the truncation bit). Then,
finally, we call the `WriteMsg` method on `w` which writes the message back to the client.
We indicate a successful (even though it might have failed - we didn't check the return value of
`WriteMsg`) write by returning 0 and `nil`.
# 4. Hooking it up
Next we need to tell CoreDNS to compile and use this new middleware. Adding a middleware was
recently simplified and only consists of editing `middleware.cfg` and adding the line:
~~~
210:whoami:whoami
~~~
The initial number is used for sorting the middleware (more on that below), then the name of the
plugin as used in the registration and then the package inside the CoreDNS middleware directory.
Each middleware has a place in the list of all other ones. For instance the caching
or the metrics middleware needs to come early, so that it can "see" the query and
response and do cachy or metricsy things with it. A *whoami* middleware is not that special and can
be placed relatively late in the list (hence the high number).
Now do a `make` (or `go gen && go build`) to get a `coredns` binary that can be used with our shiny new middleware.
This binary should include `dns.whoami` when called with `-plugins`.
# 5. Using it
Write a Corefile:
~~~ txt
. {
whoami
}
~~~
In words this says: be authoritative for the root `.` and below, meaning all possible queries will
hit this stanza. And for each request call *whoami*.
Start CoreDNS with: `coredns -conf Corefile -dns.port 1053`. Couple of notes here. CoreDNS
will look for a Corefile in the current directory so the `-conf Corefile` is only given here for
completeness. The `-dns.port` will start CoreDNS on port 1053, so we don't need to run as root.
CoreDNS will output the following:
~~~ txt
.:1053
2017/02/19 17:44:31 [INFO] CoreDNS-005
CoreDNS-005
~~~
The `.:1053` indicates it has parsed our Corefile and is listening on port 1053 for queries for
the root `.` zone and below.
So, lets send it a query with `dig`:
~~~ sh
% dig +nocmd @localhost mx example.org -p1053 +noall +additional
example.org. 0 IN A 127.0.0.1
_udp.example.org. 0 IN SRV 0 0 58359 .
~~~
Beautiful. It is working. Checking the response, this request was sent with IPv4 over UDP
from port 58359.
Let's try using TCP:
~~~ sh
% dig +nocmd @localhost a example.org -p1053 +noall +additional +tcp
example.org. 0 IN A 127.0.0.1
_tcp.example.org. 0 IN SRV 0 0 33435 .
~~~
Yes, it correctly sees we've used TCP this time (and of course a different port).
There are already a lot of different middleware in CoreDNS. New, exciting ones, are always welcome. So if you
have an idea open an issue on the tracker.
This is an updated version of the [previous
blog](https://blog.coredns.io/2016/12/19/writing-middleware-for-coredns/) about writing CoreDNS
middleware.
+56
View File
@@ -0,0 +1,56 @@
+++
date = "2016-11-26T17:22:44Z"
description = "Using Google's dns.google.com with CoreDNS"
tags = ["Encryption", "DNS", "Google", "Documentation"]
title = "DNS over HTTPS"
author = "miek"
+++
Since almost a year Google has a DNS service that can be queried over HTTPS:
<https://dns.google.com>. This means your queries are encrypted and can only be seen by you (and
Google(!)). Seeing all the press about the
[UK's snooper's charter](https://www.theguardian.com/technology/askjack/2016/nov/24/how-can-i-protect-myself-from-government-snoopers)
I though I should implement this as a middleware in CoreDNS.
I'm (obviously) going to use this myself; which is perfect as it protects me and it allows me to
dog food CoreDNS as a DNS proxy in my home network.
A note worthy other implementation is "dingo": <https://github.com/pforemski/dingo>.
Also note that this a *different* protocol than "DNS over TLS" which has similar goals and is being
standardized by the IETF.
> Currently you'll need to compile CoreDNS from source to play with this or wait until CoreDNS-004
> is released.
The configuration on the CoreDNS side is pretty straight forward. The following Corefile is all
you'll need:
~~~ txt
. {
httpproxy . dns.google.com
cache
log stdout
errors stdout
}
~~~
Next start CoreDNS, and query it.
~~~ sh
% ./coredns
.:53
2016/11/26 17:11:07 [INFO] CoreDNS-003
CoreDNS-003
::1 - [26/Nov/2016:17:13:10 +0000] "MX IN miek.nl. udp false 4096" NOERROR 246 149.791162ms
::1 - [26/Nov/2016:17:13:11 +0000] "MX IN miek.nl. udp false 4096" NOERROR 170 156.432µs
~~~
The only unencrypted DNS used is from your laptop/phone/computer to CoreDNS, the rest is encrypted.
By default, `dns.google.com` will be re-resolved every 30 seconds using 8.8.8.8 and 8.8.4.4 (you can
override these defaults). This is the only query not encrypted, but this will probably lead to
a very boring browser history.
Next, *I* need to configure a Raspberry Pi and install CoreDNS on it. And as with all CoreDNS
developements [feedback is welcome](https://github.com/coredns/coredns/issues).
@@ -0,0 +1,241 @@
+++
date = "2017-03-01T20:33:08Z"
description = "CoreDNS is now fully compliant with the Kubernetes DNS Service Discovery Specification"
tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Documentation"]
title = "CoreDNS for Kubernetes Service Discovery, Take 2"
author = "john"
+++
A couple months ago we published a blog post on [how to use CoreDNS instead of
kube-dns](https://community.infoblox.com/t5/Community-Blog/CoreDNS-for-Kubernetes-Service-Discovery/ba-p/8187)
in Kubernetes. Since then, we have made a lot of progress. We worked with the
community to define a specification for [Kubernetes DNS-Based Service Discovery]
(https://github.com/kubernetes/dns/blob/master/docs/specification.md), enabling us to ensure
compatibility across the existing Kube-DNS implementation
and our new one in CoreDNS. Version 1.0.0 of this specification mostly follows
the current behavior of Kube-DNS. Versions 005 and higher of CoreDNS implement the full
specification and more.
At the time of that blog, the CoreDNS Kubernetes middleware only supported
serving `A` records with the cluster IP of an ordinary service. Now it includes:
* `A`, `SRV`, and `PTR` records for regular and headless services
* `A` records for named endpoints that are part of a service (i.e., records for
'pets')
* `A` records for pods (optional) as described in the spec
* `TXT` record for discovering the DNS schema version in use
The pod `A` record support is not needed in all clusters, and is disabled by
default. Additionally, CoreDNS support for this use case goes beyond the
standard behavior you'll find in Kube-DNS. In Kube-DNS, these records do not
reflect the state of the cluster. Any query to `w-x-y-z.namespace.pod.cluster.local`
will return an `A` record with `w.x.y.z`, even if that IP does not belong to
specified namespace or even to the cluster address space. The original idea
behind this was to enable the use of wildcard SSL certificates for domains like
`*.namespace.pod.cluster.local`. CoreDNS can duplicate this behavior with the
configuration option `pods insecure`. We deem it "insecure" because this lack of
validation breaks the identity guarantee of the wildcard certificate.
The CoreDNS integration offers the option `pods verified`, which will verify
that the IP address `w.x.y.z` returned is in fact the IP of a pod in the
specified namespace. This prevents the spoofing of a DNS name in the namespace.
It does however, potentially increase the memory footprint of the CoreDNS instances
substantially, since now it needs to watch all pods, not just service endpoints.
Ok, enough intro - let's see how to deploy this. Like in the previous blog, we
use a ConfigMap and a Deployment. To make it even easier, we have created a little
[utility script](https://github.com/coredns/deployment/blob/master/kubernetes/deploy.sh) and
[deployment manifest template](https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed)
that you can use to deploy. To use it, simply put them both in the same directory
and then run the `deploy.sh` script, passing it the CIDR for your services. This will
generate the ConfigMap with the necessary Corefile. It will also lookup the cluster IP
of the existing kube-dns service. For example, running
$ ./deploy.sh 10.3.0.0/24 cluster.local
with `kubectl` pointing to a cluster that has kube-dns service with cluster IP 10.3.0.10
results in the manifest file below.[^1]
[^1]: *Important:* If you are using Google Container Engine, there are additional processes that will not allow you to replace the kube-dns deployment (or replication controller). If you try to apply the above, it will successfully alter the Service but will soon kill your CoreDNS deployment and restart the Kube DNS replication controller. Since the service is updated, you actually will lose DNS in your cluster, as the service selector for the service no longer points to the pods created by the Kube DNS replication controller. There is probably a way around this but I haven't had a chance to find the fix yet.
~~~yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log stdout
health
kubernetes cluster.local {
cidrs 10.3.0.0/24
}
proxy . /etc/resolv.conf
cache 30
}
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: coredns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "CoreDNS"
spec:
replicas: 1
selector:
matchLabels:
k8s-app: coredns
template:
metadata:
labels:
k8s-app: coredns
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
spec:
containers:
- name: coredns
image: coredns/coredns:latest
imagePullPolicy: Always
args: [ "-conf", "/etc/coredns/Corefile" ]
volumeMounts:
- name: config-volume
mountPath: /etc/coredns
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
dnsPolicy: Default
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
---
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: coredns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "CoreDNS"
spec:
selector:
k8s-app: coredns
clusterIP: 10.3.0.10
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
~~~
Let's take a closer look at that Corefile. It's really very similar to the one in the
previous blog post.
~~~txt
.:53 {
errors
log stdout
health
kubernetes cluster.local {
cidrs 10.3.0.0/24
}
proxy . /etc/resolv.conf
cache 30
}
~~~
The one difference though, is the `cidrs 10.3.0.0/24` directive. This tells the
Kubernetes middleware that it is responsible for serving `PTR` requests for the reverse
zone `0.3.10.in-addr.arpa.`. In other words, this is what allows reverse DNS
resolution of services. Let's give that a try:
~~~txt
$ ./deploy.sh 10.3.0.0/24 | kubectl apply -f -
configmap "coredns" created
deployment "coredns" created
service "kube-dns" configured
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
Waiting for pod default/dnstools to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
/ # host kubernetes
kubernetes.default.svc.cluster.local has address 10.3.0.1
/ # host kube-dns.kube-system
kube-dns.kube-system.svc.cluster.local has address 10.3.0.10
/ # host 10.3.0.1
1.0.3.10.in-addr.arpa domain name pointer kubernetes.default.svc.cluster.local.
/ # host 10.3.0.10
10.0.3.10.in-addr.arpa domain name pointer kube-dns.kube-system.svc.cluster.local.
/ #
~~~
Great, so it's working. Now, let's take a look at our CoreDNS logs:
~~~txt
$ kubectl get --namespace kube-system pods
NAME READY STATUS RESTARTS AGE
coredns-3558181428-0zhnh 1/1 Running 0 2m
coredns-3558181428-xri9i 1/1 Running 0 2m
heapster-v1.2.0-4088228293-a8gkc 2/2 Running 0 126d
kube-apiserver-10.222.243.77 1/1 Running 2 126d
kube-controller-manager-10.222.243.77 1/1 Running 2 126d
kube-proxy-10.222.243.77 1/1 Running 2 126d
kube-proxy-10.222.243.78 1/1 Running 0 126d
kube-scheduler-10.222.243.77 1/1 Running 2 126d
kubernetes-dashboard-v1.4.1-gi2xr 1/1 Running 0 24d
tiller-deploy-3299276078-e8phb 1/1 Running 0 24d
$ kubectl logs --namespace kube-system coredns-3558181428-0zhnh
2017/02/23 14:48:29 [INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed.
.:53
2017/02/23 14:48:29 [INFO] CoreDNS-005
CoreDNS-005
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "AAAA IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 107 544.128µs
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "MX IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 107 7.576897ms
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "A IN kube-dns.kube-system.default.svc.cluster.local. udp 64 false 512" NXDOMAIN 117 471.176µs
23/Feb/2017:14:49:52 +0000 [ERROR 0 kube-dns.kube-system.default.svc.cluster.local. A] no items found
10.2.6.127 - [23/Feb/2017:14:50:00 +0000] "PTR IN 10.0.3.10.in-addr.arpa. udp 40 false 512" NOERROR 92 752.956µs
$ kubectl logs --namespace kube-system coredns-3558181428-xri9i
2017/02/23 14:48:29 [INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed.
.:53
2017/02/23 14:48:29 [INFO] CoreDNS-005
CoreDNS-005
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 70 1.10732ms
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "A IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 72 409.74µs
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "AAAA IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 109 210.817µs
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "MX IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 109 796.703µs
10.2.6.127 - [23/Feb/2017:14:49:56 +0000] "PTR IN 1.0.3.10.in-addr.arpa. udp 39 false 512" NOERROR 89 694.649µs
$
~~~
Here, we can see that the queries were load-balanced across the two CoreDNS replicas. In production, it's a good idea
to disable the logging of all the queries, as logging slows down the query dramatically (often by an order of magnitude).
To do that, simply remove the `log stdout` line from the Corefile.
That's all there is to it. Please feel free to submit any problems, questions, or feature ideas as issues on the
[CoreDNS GitHub](https://github.com/coredns/coredns).
@@ -0,0 +1,24 @@
+++
date = "2016-11-08T07:33:08Z"
description = "Using CoreDNS for service discovery in Kubernetes"
tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Documentation"]
title = "CoreDNS for Kubernetes Service Discovery"
author = "miek"
+++
[Infoblox](https://www.infoblox.com/)'s John Belamaric has published a
blog post on
[how to use CoreDNS instead of
kube-dns](https://community.infoblox.com/t5/Community-Blog/CoreDNS-for-Kubernetes-Service-Discovery/ba-p/8187)
in Kubernetes.
A little excerpt:
> Kubernetes includes a DNS server, Kube-DNS, for use in service discovery. This DNS server utilizes
> the libraries from SkyDNS to serve DNS requests for Kubernetes pods and services. The author of
> SkyDNS2, Miek Gieben, has a new DNS server, CoreDNS, that is built with a more modular, extensible
> framework. Infoblox has been working with Miek to adapt this DNS server as an alternative to
> Kube-DNS.
Read more on their
[site](https://community.infoblox.com/t5/Community-Blog/CoreDNS-for-Kubernetes-Service-Discovery/ba-p/8187).
+67
View File
@@ -0,0 +1,67 @@
+++
date = "2017-04-28T12:30:00Z"
description = "Getting CoreDNS to work with Minikube"
tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Minikube", "DNS", "Documentation"]
title = "CoreDNS for Minikube"
author = "john"
+++
In our [previous post](https://blog.coredns.io/2017/03/01/coredns-for-kubernetes-service-discovery-take-2/),
we showed how CoreDNS can be used in place of Kube-DNS for service discovery in Kubernetes clusters.
In that blog, there is a footnote about issues trying to replace Kube-DNS when using Google Container Engine (GKE).
As it so happens, there is a similar issue with [minikube](https://github.com/kubernetes/minikube), which is a local
Kubernetes environment that is very useful for developers (see our
[DEV-README.md](https://github.com/coredns/coredns/blob/master/middleware/kubernetes/DEV-README.md) for more).
When you try to replace Kube-DNS, you will find that shortly after you modify its service to point to CoreDNS, your
changes will be reverted. This is because Minikube has an _addon manager_ that periodically verifies the configuration
state of any installed addons, and Kube-DNS is one of those addons.
Luckily, this is really easy to solve for Minikube. The `minikube` command allows you to modify the installed
plugins for Minikube. So, we simply need to disable the `kube-dns` addon before running our `kubectl apply -f`
that is described in the previous blog:
~~~ txt
$ minikube addons list
- dashboard: enabled
- default-storageclass: enabled
- kube-dns: enabled
- heapster: disabled
- ingress: disabled
- registry-creds: disabled
- addon-manager: enabled
$ minikube addons disable kube-dns
kube-dns was successfully disabled
$ minikube addons list
- heapster: disabled
- ingress: disabled
- registry-creds: disabled
- addon-manager: enabled
- dashboard: enabled
- default-storageclass: enabled
- kube-dns: disabled
~~~
Now we can apply the `coredns.yaml`, and also delete the `kube-dns` `ReplicationController` which
will not be automatically deleted by disabling the addon.
~~~ txt
$ kubectl apply -f coredns.yaml
serviceaccount "coredns" configured
clusterrole "system:coredns" configured
clusterrolebinding "system:coredns" configured
configmap "coredns" configured
deployment "coredns" configured
service "kube-dns" configured
$ kubectl get -n kube-system pods
NAME READY STATUS RESTARTS AGE
coredns-980047985-g2748 1/1 Running 1 36m
kube-addon-manager-minikube 1/1 Running 0 9d
kube-dns-v20-qzvr2 3/3 Running 0 1m
kubernetes-dashboard-ks1jp 1/1 Running 0 9d
$ kubectl delete -n kube-system rc kube-dns-v20
replicationcontroller "kube-dns-v20" deleted
$
~~~
And there we have it, CoreDNS is up and running and won't be overwritten by the addon manager.
+194
View File
@@ -0,0 +1,194 @@
+++
date = "2017-06-08T20:01:00Z"
description = "And how it applies to Kubernetes custom DNS entries inside the cluster domain"
tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Custom", "DNS", "middleware", "Documentation"]
title = "How Queries Are Processed in CoreDNS"
author = "john"
+++
In the [last post](https://blog.coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/), we described three different use
cases for custom DNS entries in Kubernetes:
* [Making an alias](https://github.com/kubernetes/kubernetes/issues/39792) for an external name
* [Dynamically adding services to another domain](https://github.com/kubernetes/dns/issues/55), without running another server
* Adding an arbitrary entry inside the cluster domain
In that post we covered the first two. In this post, we'll show you how to use the `fallthrough` option of the `kubernetes`
middleware to satisfy the third case.
To understand how this works, we first need to look at how CoreDNS processes requests. This was previously
addressed in [Query Routing](https://blog.coredns.io/2016/10/13/query-routing/), but we'll go into a bit
more detail here.
We all know that CoreDNS chains middleware. But what exactly does that mean? To find out, we'll dissect a
Corefile and see how that translates into CoreDNS internals, and discuss how a query
is routed through these internals.
Consider this Corefile:
~~~ txt
coredns.io:5300 {
file /etc/coredns/zones/coredns.io.db
}
example.io:53 {
errors
log
file /etc/coredns/zones/example.io.db
}
example.net:53 {
file /etc/coredns/zones/example.net.db
}
.:53 {
errors
log stdout
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local {
cidrs 10.0.0.0/24
}
file /etc/coredns/example.db example.org
proxy . /etc/resolv.conf
cache 30
}
~~~
Notice here that there are two different ports: 5300 and 53. Internally, each of these ports will
result in a [`dnsserver.Server`](https://github.com/coredns/coredns/blob/master/core/dnsserver/server.go).
Even though there are four _server blocks_ (stanzas), we only get two actual servers. CoreDNS will gather up all of the
server blocks associated with the same port and combine them in to the same `dnsserver.Server`. The server will
multiplex the queries on the port, passing them to the different _middleware chains_ depending upon the zone. It chooses
the most specific matching server block for the zone. If no server block matches, `SERVFAIL` is returned. This is shown
visually in the diagram below.
![Query Processing](/images/query-processing.png)
So, any specific query will go through exactly one middleware chain. The ordering of the middleware is dictated
*at build time*, by the [`middleware.cfg`](https://github.com/coredns/coredns/blob/master/middleware.cfg) file,
although there is some [discussion](https://github.com/coredns/coredns/issues/632) about making this modifiable
at runtime. This is why even though `cache` appears at the end of the server block, it is not the end of the
middleware chain.
Notice in the `.:53` server block, we define the `health` middleware, but it doesn't appear in the diagram. This is
because there are a few different types of middleware. "Normal" middleware perform request handling, and appear in the
middleware chain. However, there are a few middleware that just modify the configuration of the server or server block.
Since they don't have any request-time logic, they are not inserted in the middleware chain. Some middleware that work
this way are the `health`, `tls`, `startup`, `shutdown`, and `root` middleware.
You can divide the middleware that do perform request-time processing into two groups: middleware that
_manipulate_ the request in some way, and _backend_ middleware. Backend middleware provide different sources
of zone and record data. The `etcd`, `file`, and `kubernetes` middleware are all examples of backends.
Middleware that manipulate the request but are not backends - that is, they are not a source of zone data - generally
will pass the query to the next middleware after performing their logic. For example, the `rewrite` middleware makes
a change to the request, and then passes it on. When the result is returned from the later middleware, it reverts the
question section to the original (so that clients don't complain), but keeps the response and passes it back to the client.
Any given backend is usually the final word for its zone - it either returns a result, or it returns NXDOMAIN for the
query. However, occasionally this is not the desired behavior, so some of the middleware support a `fallthrough` option.
When `fallthrough` is enabled, instead of returning NXDOMAIN when a record is not found, the middleware will pass the
request down the chain. A backend further down the chain then has the opportunity to handle the request.
Coming back to our original discussion of the three use cases in Kubernetes, we can now understand how we can use
`fallthrough` to meet the third use case. Remember the initial Corefile from [that blog](https://blog.coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/):
~~~ txt
.:53 {
errors
log stdout
health
kubernetes cluster.local {
cidrs 10.0.0.0/24
}
proxy . /etc/resolv.conf
cache 30
}
~~~
This handles the standard in-cluster DNS service discovery. The third use case is to add an arbitrary entry to the existing
cluster domain. To do this, we define another backend for handling the `cluster.local` zone, and configure the `fallthrough`
option in the `kubernetes` middleware. For very dynamic entries, we could use the `etcd` middleware. But for demonstration
purposes it's simpler to use the `file` middleware, so that is what we will do.
Since `kubernetes` comes before `file` in [`middleware.cfg`](https://github.com/coredns/coredns/blob/master/middleware.cfg),
using `fallthrough` in `kubernetes` will result in `file` handling any queries that `kubernetes` does not. This means that we
need to have a zone file as part of our ConfigMap, just like we did to handle the second use case in the previous blog. In this case, though, instead of being configured with a different zone (`example.org` in the other blog), the `file` middleware is
configured to use the `cluster.local` domain:
~~~ yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log stdout
health
kubernetes cluster.local {
cidrs 10.0.0.0/24
fallthrough
}
file /etc/coredns/cluster.db cluster.local
proxy . /etc/resolv.conf
cache 30
}
cluster.db: |
cluster.local. IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 2015082541 7200 3600 1209600 3600
something.cluster.local. IN A 10.0.0.1
otherthing.cluster.local. IN CNAME google.com.
~~~
Remember to add the `cluster.db` file to the `config-volume` for the pod template:
~~~ yaml
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
- key: cluster.db
path: cluster.db
~~~
and finally to signal CoreDNS to gracefully reload (each pod running):
~~~ txt
$ kubectl -n coredns exec coredns-461002909-7mp96 -- kill -SIGUSR1 1
~~~
Now let's try out our new DNS records.
~~~ txt
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host kubernetes
kubernetes.default.svc.cluster.local has address 10.0.0.1
/ # host something
something.cluster.local has address 10.0.0.1
/ # host otherthign
Host otherthign not found: 3(NXDOMAIN)
/ # host otherthing
otherthing.cluster.local is an alias for google.com.
google.com has IPv6 address 2607:f8b0:4005:805::200e
google.com mail is handled by 30 alt2.aspmx.l.google.com.
google.com mail is handled by 50 alt4.aspmx.l.google.com.
google.com mail is handled by 40 alt3.aspmx.l.google.com.
google.com mail is handled by 20 alt1.aspmx.l.google.com.
google.com mail is handled by 10 aspmx.l.google.com.
/ #
~~~
We can see if we put in an incorrect name, we still get NXDOMAIN as you would expect. However, a correct name will
resolve to the record from our zone file. So, we now have a way to create custom entries in the cluster domain.
In the standard CoreDNS release, the `kubernetes` middleware comes before `file` and `etcd`. This means that it gets the
first chance to handle the query. You can rebuild CoreDNS to change that ordering if you wish - take a look at
Miek's post on [How to Add Middleware to CoreDNS](https://blog.coredns.io/2017/03/01/how-to-add-middleware-to-coredns/)
if you want to see how that's done.
+120
View File
@@ -0,0 +1,120 @@
+++
date = "2017-07-24T07:37:13Z"
description = "Quick Start Guide"
tags = ["Quick", "Start", "Documentation"]
title = "Quick Start"
author = "miek"
+++
First get CoreDNS, either
* *Download the latest* release from [github](https://github.com/coredns/coredns/releases), unpack
it. You should now have a "coredns" executable.
* *Compile from git* by getting the source code from [github](https://github.com/coredns/coredns).
Change directory to `coredns` and:
* `go get` - to get a few dependencies, the other ones are vendored
* `go build`
You should now have a "coredns" executable.
If you want to use CoreDNS in Kubernetes, please check [this post about SD with the *kuberneters*
middleware](/2017/03/01/coredns-for-kubernetes-service-discovery-take-2/).
The remainder of this quick start will focus and two different use cases
1. Using CoreDNS to serve zone files. Optionally signing the zones as well.
2. Using CoreDNS as a forwarding proxy.
## Serving from files
When serving from zone files you will want to use the *file* middleware. Let's start with the zone
`example.org.` and zonefile we want to serve from:
Create a file names `/etc/coredns/zones/example.org` with the following content:
~~~ dns
$ORIGIN example.org.
@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. (
2017042745 ; serial
7200 ; refresh (2 hours)
3600 ; retry (1 hour)
1209600 ; expire (2 weeks)
3600 ; minimum (1 hour)
)
3600 IN NS a.iana-servers.net.
3600 IN NS b.iana-servers.net.
www IN A 127.0.0.1
IN AAAA ::1
~~~
Create a Corefile, `/etc/coredns/Corefile`, with:
~~~ txt
example.org {
file /etc/coredns/zones/example.org
prometheus # enable metrics
errors stdout # show errors
log stdout # show query logs
}
~~~
Note: you can put the last 3 directives in another file say "/etc/coredns/zone-default" and use
an `import`: `import /etc/coredns/zone-default`.
Start CoreDNS on a non-standard port to check if everything is correct: `coredns -conf Corefile
-dns.port 1053` and send it a query with [dig](https://en.wikipedia.org/wiki/Dig_(command)):
~~~
% dig -p 1053 @localhost AAAA www.example.org +noall +answer
www.example.org. 3600 IN AAAA ::1
~~~
As we've enabled logging the query should be show up there as well:
~~~ txt
::1 - [24/Jul/2017:10:10:44 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 121 133.449µs
~~~
From here you can enable CoreDNS to run on port 53 and have it start from systemd (when on Linux),
see [the deployment repo](https://github.com/coredns/deployment) for example scripts.
Or read more about the *file* middleware on [this website](/middleware/file/).
## CoreDNS as proxy
Another way of running CoreDNS is as a proxy, for instance sending DNS request to Google using
HTTPS. Create a Corefile with:
~~~ txt
. {
proxy . 8.8.8.8:53 {
protocol https_google
}
prometheus
errors stdout
log stdout
}
~~~
Start CoreDNS, just like above and send it a few queries. CoreDNS should logs those, in this case:
~~~
::1 - [24/Jul/2017:10:44:15 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 76 83.396955ms
::1 - [24/Jul/2017:10:44:17 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 76 14.030914ms
::1 - [24/Jul/2017:10:44:19 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 76 13.286384ms
~~~
If you look at the time each query took, we measure those in "ms", so it's quite slow. Let's add
caching, but enable the *caching* middleware. Just add the word "cache" to the Corefile and reload
CoreDNS: `kill -SIGUSR1 <pid_of_coredns>`. And query again:
~~~
::1 - [24/Jul/2017:11:33:54 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 76 43.469743ms
::1 - [24/Jul/2017:11:33:55 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 73 133.073µs
~~~
133 µs. That sounds better.
Read more about the [*cache*](/middleware/cache) and [*proxy*](/middleware/proxy) middleware on
this website. And find all other documentation [here](/tags/documentation).
+24
View File
@@ -0,0 +1,24 @@
+++
date = "2017-07-23T22:00:00Z"
description = "When should middleware be external?"
tags = ["Middleware", "External", "Out-of-Tree"]
title = "When Should Middleware be External?"
author = "miek"
+++
The `middleware.md` in the CoreDNS source tree has some pointers on what a middleware for CoreDNS
should have as minimum requirements. It basically boils down to: documentation, tests and working.
It is easier to list when a middleware can be *included* in CoreDNS than to say it should stay
external, so we will do the first:
* First, the middleware should be useful for *other* people. "Useful" is a subjective term, but the
middleware needs to fill a niche that appeals to more than one person.
* It should be sufficiently different from other middleware to warrant inclusion.
* Current internet standards need be supported: IPv4 and IPv6, so A and AAAA records should be
handled (if your middleware is in the business of dealing with address records that is).
* It must have tests.
* It must have a README.md for documentation.
Middleware for CoreDNS can live out-of-tree, `middleware.cfg` defaults to CoreDNS' repo but other
repos work just as well, so it is pretty easy to use your middleware even though it is out-of-tree.
+35
View File
@@ -0,0 +1,35 @@
+++
title = "Community"
+++
**Mailing list**: [coredns-discuss@googlegroups.com](coredns-discuss@googlegroups.com) - discussion
around CoreDNS usage, community support and developer discussion.
**Slack**: #coredns on https://slack.cncf.io
**Twitter**: [@corednsio](https://twitter.com/corednsio).
**Issue tracker**: Use the [GitHub issue tracker](https://github.com/coredns/coredns/issues)
to file bugs and features request. If you need support, please send your questions to the
coredns-discuss mailing list rather than filing a GitHub issue.
*Please do not ask individual project members for support. Use the channels above instead, where the
whole community can help you and benefit from the solutions provided.*
# Contributing
We welcome community contributions! Please see the `CONTRIBUTING.md` file in the CoreDNS
repository for instructions on how to submit changes. If you are planning on making more elaborate
or controversial changes, please discuss them on the mailing list or on
[Github](https://github.com/coredns/coredns/issues/new)
before sending a pull request.
# Project Governance
CoreDNS is an independent open-source project and not controlled by any single company.
To emphasize this and clarify our governance structure, we joined the [Cloud Native Computing
Foundation](https://cncf.io) in 2017.
<a href="https://cncf.io/"><img src="/images/cncf-logo.png"></a>
# Code of Conduct
To make CoreDNS a welcoming and harassment-free experience for everyone, we follow the [CNCF Code
of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md)
+25
View File
@@ -0,0 +1,25 @@
+++
title = "example"
description = "*example* is a non-existent external middleware."
weight = 1000 # put it at the end
tags = [ "middleware" , "example" ]
categories = [ "middleware", "external" ]
date = "2017-07-22T12:37:19+01:00"
repo = "github.com/miekg/example"
home = "github.com/miekg/example"
+++
The *example* middleware is an example for an external middleware README.md. This middleware does
not actually exist.
## Syntax
~~~
example
~~~
## Examples
~~~
example
~~~
+41
View File
@@ -0,0 +1,41 @@
+++
title = "import"
description = "*import* allows you to use configuration from another file. It gets replaced with the contents of that file."
weight = 10
tags = [ "middleware" , "import" ]
categories = [ "middleware", "external" ]
date = "2017-07-22T12:37:19+01:00"
repo = "https://github.com/mholt/caddy"
home = "https://caddyserver.com/docs/import"
+++
This is a unique directive in that *import* can appear outside of a server block. In other words, it
can appear at the top of a Corefile where an address would normally be. Like other directives,
however, it cannot be used inside of other directives.
Note that the the import path is relative to the Corefile, not the current working directory.
## Syntax
~~~
import PATTERN
~~~
* **PATTERN** is the file or glob pattern (`*`) to include. Its contents will replace this line, as
if that file's contents appeared here to begin with. This value is relative to the file's
location. It is an error if a specific file cannot be found, but an empty glob pattern is not an
error.
## Examples
Import a shared configuration:
~~~
import config/common.conf
~~~
Imports any files found in the zones directory:
~~~
import ../zones/*
~~~
+39
View File
@@ -0,0 +1,39 @@
+++
title = "shutdown"
description = "*shutdown* executes a command when the server exits."
weight = 10
tags = [ "middleware" , "shutdown" ]
categories = [ "middleware", "external" ]
date = "2017-07-22T12:37:19+01:00"
repo = "https://github.com/mholt/caddy"
home = "https://caddyserver.com/docs/shutdown"
+++
This is useful for performing cleanup or stopping a background process. (Also see
[startup](/exmiddleware/startup).)
Each command that is executed at shutdown is blocking. The output and error of the command go to
stdout and stderr, respectively. There is no stdin.
Note that shutdown commands will not execute if CoreDNS is force-terminated, for example, by using
a "Force Quit" feature provided by your operating system. However, a typical SIGINT (Ctrl+C) will
allow the shutdown commands to execute.
Even if this directive is shared by more than one host, the command will only execute once per
appearance in the Corefile.
## Syntax
~~~
shutdown COMMAND
~~~
* **COMMAND** is the command to execute; it may be followed by arguments.
## Examples
Stop command when the server quits:
~~~
shutdown /etc/init.d/command stop
~~~
+41
View File
@@ -0,0 +1,41 @@
+++
title = "startup"
description = "*startup* executes a command when the server begins."
weight = 10
tags = [ "middleware" , "startup" ]
categories = [ "middleware", "external" ]
date = "2017-07-22T12:37:19+01:00"
repo = "https://github.com/mholt/caddy"
home = "https://caddyserver.com/docs/startup"
+++
This is useful for preparing to serve a zone by running a script or starting a background process.
(Also see [shutdown](/exmiddleware/shutdown).)
Each command that is executed at startup is blocking, unless you suffix the command with a space and
`&`, which will cause the command to be run in the background. The output and error of the command go
to stdout and stderr, respectively. There is no stdin.
A command will only be executed once for each time it appears in the Corefile.
## Syntax
~~~
startup COMMAND
~~~
* **COMMAND** is the command to execute; it may be followed by arguments.
## Examples
Start command before the server starts listening:
~~~
startup /etc/init.d/command start
~~~
On windows, you might need to use quotes when the command path contains spaces:
~~~
startup "\"C:\Program Files\command.exe\" -b 127.0.0.1:9123" &
~~~
+72
View File
@@ -0,0 +1,72 @@
+++
title = "auto"
description = "*auto* enables serving zone data from an RFC 1035-style master file which is automatically picked up from disk. "
weight = 1
tags = [ "middleware" , "auto" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The *auto* middleware is used for an "old-style" DNS server. It serves from a preloaded file that exists
on disk. If the zone file contains signatures (i.e. is signed, i.e. DNSSEC) correct DNSSEC answers
are returned. Only NSEC is supported! If you use this setup *you* are responsible for resigning the
zonefile. New zones or changed zone are automatically picked up from disk.
## Syntax
~~~
auto [ZONES...] {
directory DIR [REGEXP ORIGIN_TEMPLATE [TIMEOUT]]
no_reload
upstream ADDRESS...
}
~~~
**ZONES** zones it should be authoritative for. If empty, the zones from the configuration block
are used.
* `directory` loads zones from the speficied **DIR**. If a file name matches **REGEXP** it will be
used to extract the origin. **ORIGIN_TEMPLATE** will be used as a template for the origin. Strings
like `{<number>}` are replaced with the respective matches in the file name, i.e. `{1}` is the
first match, `{2}` is the second, etc.. The default is: `db\.(.*) {1}` e.g. from a file with the
name `db.example.com`, the extracted origin will be `example.com`. **TIMEOUT** specifies how often
CoreDNS should scan the directory, the default is every 60 seconds. This value is in seconds.
The minimum value is 1 second.
* `no_reload` by default CoreDNS will reload a zone from disk whenever it detects a change to the
file. This option disables that behavior.
* `upstream` defines upstream resolvers to be used resolve external names found (think CNAMEs)
pointing to external names.
All directives from the *file* middleware are supported. Note that *auto* will load all zones found,
even though the directive might only receive queries for a specific zone. I.e:
~~~
auto example.org {
directory /etc/coredns/zones
}
~~~
Will happily pick up a zone for `example.COM`, except it will never be queried, because the *auto*
directive only is authoritative for `example.ORG`.
## Examples
Load `org` domains from `/etc/coredns/zones/org` and allow transfers to the internet, but send
notifies to 10.240.1.1
~~~
auto org {
directory /etc/coredns/zones/org
transfer to *
transfer to 10.240.1.1
}
~~~
Load `org` domains from `/etc/coredns/zones/org` and looks for file names as `www.db.example.org`,
where `example.org` is the origin. Scan every 45 seconds.
~~~
auto org {
directory /etc/coredns/zones/org www\.db\.(.*) {1} 45
}
~~~
+28
View File
@@ -0,0 +1,28 @@
+++
title = "bind"
description = "*bind* overrides the host to which the server should bind. "
weight = 2
tags = [ "middleware" , "bind" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
Normally, the listener binds to the wildcard host. However, you may force the listener to bind to
another IP instead. This directive accepts only an address, not a port.
## Syntax
~~~ txt
bind ADDRESS
~~~
**ADDRESS** is the IP address to bind to.
## Examples
To make your socket accessible only to that machine, bind to IP 127.0.0.1 (localhost):
~~~ txt
bind 127.0.0.1
~~~
+74
View File
@@ -0,0 +1,74 @@
+++
title = "cache"
description = "*cache* enables a frontend cache. It will cache all records except zone transfers and metadata records. "
weight = 3
tags = [ "middleware" , "cache" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
~~~ txt
cache [TTL] [ZONES...]
~~~
* **TTL** max TTL in seconds. If not specified, the maximum TTL will be used which is 3600 for
noerror responses and 1800 for denial of existence ones.
Setting a TTL of 300 *cache 300* would cache the record up to 300 seconds.
* **ZONES** zones it should cache for. If empty, the zones from the configuration block are used.
Each element in the cache is cached according to its TTL (with **TTL** as the max).
For the negative cache, the SOA's MinTTL value is used. A cache can contain up to 10,000 items by
default. A TTL of zero is not allowed.
If you want more control:
~~~ txt
cache [TTL] [ZONES...] {
success CAPACITY [TTL]
denial CAPACITY [TTL]
prefetch AMOUNT [[DURATION] [PERCENTAGE%]]
}
~~~
* **TTL** and **ZONES** as above.
* `success`, override the settings for caching successful responses, **CAPACITY** indicates the maximum
number of packets we cache before we start evicting (*randomly*). **TTL** overrides the cache maximum TTL.
* `denial`, override the settings for caching denial of existence responses, **CAPACITY** indicates the maximum
number of packets we cache before we start evicting (LRU). **TTL** overrides the cache maximum TTL.
There is a third category (`error`) but those responses are never cached.
* `prefetch`, will prefetch popular items when they are about to be expunged from the cache.
Popular means **AMOUNT** queries have been seen no gaps of **DURATION** or more between them.
**DURATION** defaults to 1m. Prefetching will happen when the TTL drops below **PERCENTAGE**,
which defaults to `10%`. Values should be in the range `[10%, 90%]`. Note the percent sign is
mandatory. **PERCENTAGE** is treated as an `int`.
The minimum TTL allowed on resource records is 5 seconds.
## Metrics
If monitoring is enabled (via the *prometheus* directive) then the following metrics are exported:
* coredns_cache_size{type} - Total elements in the cache by cache type.
* coredns_cache_capacity{type} - Total capacity of the cache by cache type.
* coredns_cache_hits_total{type} - Counter of cache hits by cache type.
* coredns_cache_misses_total - Counter of cache misses.
Cache types are either "denial" or "success".
## Examples
Enable caching for all zones, but cap everything to a TTL of 10 seconds:
~~~
cache 10
~~~
Proxy to Google Public DNS and only cache responses for example.org (or below).
~~~
proxy . 8.8.8.8:53
cache example.org
~~~
+30
View File
@@ -0,0 +1,30 @@
+++
title = "chaos"
description = "The *chaos* middleware allows CoreDNS to respond to TXT queries in the CH class. "
weight = 4
tags = [ "middleware" , "chaos" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
This is useful for retrieving version or author information from the server.
## Syntax
~~~
chaos [VERSION] [AUTHORS...]
~~~
* **VERSION** is the version to return. Defaults to `CoreDNS-<version>`, if not set.
* **AUTHORS** is what authors to return. No default.
Note that you have to make sure that this middleware will get actual queries for the
following zones: `version.bind`, `version.server`, `authors.bind`, `hostname.bind` and
`id.server`.
## Examples
~~~
chaos CoreDNS-001 "Miek Gieben" miek@miek.nl
~~~
+26
View File
@@ -0,0 +1,26 @@
+++
title = "debug"
description = "*debug* disables the automatic recovery upon a CoreDNS crash so that you'll get a nice stack trace. "
weight = 5
tags = [ "middleware" , "debug" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
Note that the *errors* middleware (if loaded) will also set a `recover` negating this setting.
The main use of *debug* is to help testing.
## Syntax
~~~ txt
debug
~~~
## Examples
Disable CoreDNS' ability to recover from crashes:
~~~ txt
debug
~~~
+55
View File
@@ -0,0 +1,55 @@
+++
title = "dnssec"
description = "*dnssec* enables on-the-fly DNSSEC signing of served data. "
weight = 6
tags = [ "middleware" , "dnssec" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
~~~
dnssec [ZONES...]
~~~
* **ZONES** zones that should be signed. If empty, the zones from the configuration block
are used.
If keys are not specified (see below), a key is generated and used for all signing operations. The
DNSSEC signing will treat this key a CSK (common signing key), forgoing the ZSK/KSK split. All
signing operations are done online. Authenticated denial of existence is implemented with NSEC black
lies. Using ECDSA as an algorithm is preferred as this leads to smaller signatures (compared to
RSA). NSEC3 is *not* supported.
A single signing key can be specified by using the `key` directive.
NOTE: Key generation has not been implemented yet.
TODO(miek): think about key rollovers, and how to do them automatically.
~~~
dnssec [ZONES... ] {
key file KEY...
cache_capacity CAPACITY
}
~~~
* `key file` indicates that key file(s) should be read from disk. When multiple keys are specified, RRsets
will be signed with all keys. Generating a key can be done with `dnssec-keygen`: `dnssec-keygen -a
ECDSAP256SHA256 <zonename>`. A key created for zone *A* can be safely used for zone *B*.
* `cache_capacity` indicates the capacity of the LRU cache. The dnssec middleware uses LRU cache to manage
objects and the default capacity is 10000.
## Metrics
If monitoring is enabled (via the *prometheus* directive) then the following metrics are exported:
* coredns_dnssec_cache_size{type} - total elements in the cache, type is "signature".
* coredns_dnssec_cache_capacity{type} - total capacity of the cache, type is "signature".
* coredns_dnssec_cache_hits_total - Counter of cache hits.
* coredns_dnssec_cache_misses_total - Counter of cache misses.
## Examples
+78
View File
@@ -0,0 +1,78 @@
+++
title = "erratic"
description = "*erratic* is a middleware useful for testing client behavior. It returns a static response to all queries, but the responses can be delayed, dropped or truncated. "
weight = 7
tags = [ "middleware" , "erratic" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The *erratic* middleware will respond to every A or AAAA query. For any other type it will return
a SERVFAIL response. The reply for A will return 192.0.2.53 (see RFC 5737), for AAAA it returns
2001:DB8::53 (see RFC 3849).
## Syntax
~~~ txt
erratic {
drop [AMOUNT]
truncate [AMOUNT]
delay [AMOUNT [DURATION]]
}
~~~
* `drop`: drop 1 per **AMOUNT** of queries, the default is 2.
* `truncate`: truncate 1 per **AMOUNT** of queries, the default is 2.
* `delay`: delay 1 per **AMOUNT** of queries for **DURATION**, the default for **AMOUNT** is 2 and
the default for **DURATION** is 100ms.
## Examples
~~~ txt
.:53 {
erratic {
drop 3
}
}
~~~
Or even shorter if the defaults suits you. Note this only drops queries, it does not delay them.
~~~ txt
. {
erratic
}
~~~
Delay 1 in 3 queries for 50ms
~~~ txt
. {
erratic {
delay 3 50ms
}
}
~~~
Delay 1 in 3 and truncate 1 in 5.
~~~ txt
. {
erratic {
delay 3 5ms
truncate 5
}
}
~~~
Drop every second query.
~~~ txt
. {
erratic {
drop 2
truncate 2
}
}
~~~
+33
View File
@@ -0,0 +1,33 @@
+++
title = "errors"
description = "*errors* enables error logging. "
weight = 8
tags = [ "middleware" , "errors" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
Any errors encountered during the query processing will be printed on standard output.
## Syntax
~~~
errors [FILE]
~~~
* **FILE** is the log file to create (or append to). The *only* valid name for **FILE** is *stdout*
## Examples
Log errors to *stdout*.
~~~
errors
~~~
Log errors to *stdout*.
~~~
errors stdout
~~~
+155
View File
@@ -0,0 +1,155 @@
+++
title = "etcd"
description = "*etcd* enables reading zone data from an etcd instance. The data in etcd has to be encoded as a [message](https://github.com/skynetservices/skydns/blob/2fcff74cdc9f9a7dd64189a447ef27ac354b725f/msg/service.go#L26) like [SkyDNS](https://github.com/skynetservices/skydns). It should also work just like SkyDNS. "
weight = 9
tags = [ "middleware" , "etcd" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The etcd middleware makes extensive use of the proxy middleware to forward and query other servers
in the network.
## Syntax
~~~
etcd [ZONES...]
~~~
* **ZONES** zones etcd should be authoritative for.
The path will default to `/skydns` the local etcd proxy (http://localhost:2379).
If no zones are specified the block's zone will be used as the zone.
If you want to `round robin` A and AAAA responses look at the `loadbalance` middleware.
~~~
etcd [ZONES...] {
stubzones
path PATH
endpoint ENDPOINT...
upstream ADDRESS...
tls CERT KEY CACERt
debug
}
~~~
* `stubzones` enables the stub zones feature. The stubzone is *only* done in the etcd tree located
under the *first* zone specified.
* **PATH** the path inside etcd. Defaults to "/skydns".
* **ENDPOINT** the etcd endpoints. Defaults to "http://localhost:2397".
* `upstream` upstream resolvers to be used resolve external names found in etcd (think CNAMEs)
pointing to external names. If you want CoreDNS to act as a proxy for clients, you'll need to add
the proxy middleware. **ADDRESS** can be an IP address, and IP:port or a string pointing to a file
that is structured as /etc/resolv.conf.
* `tls` followed by:
* no arguments, if the server certificate is signed by a system-installed CA and no client cert is needed
* a single argument that is the CA PEM file, if the server cert is not signed by a system CA and no client cert is needed
* two arguments - path to cert PEM file, the path to private key PEM file - if the server certificate is signed by a system-installed CA and a client certificate is needed
* three arguments - path to cert PEM file, path to client private key PEM file, path to CA PEM file - if the server certificate is not signed by a system-installed CA and client certificate is needed
* `debug` allows for debug queries. Prefix the name with `o-o.debug.` to retrieve extra information in the
additional section of the reply in the form of TXT records.
## Examples
This is the default SkyDNS setup, with everying specified in full:
~~~
.:53 {
etcd skydns.local {
stubzones
path /skydns
endpoint http://localhost:2379
upstream 8.8.8.8:53 8.8.4.4:53
}
prometheus
cache 160 skydns.local
loadbalance
proxy . 8.8.8.8:53 8.8.4.4:53
}
~~~
Or a setup where we use `/etc/resolv.conf` as the basis for the proxy and the upstream
when resolving external pointing CNAMEs.
~~~
.:53 {
etcd skydns.local {
path /skydns
upstream /etc/resolv.conf
}
cache 160 skydns.local
proxy . /etc/resolv.conf
}
~~~
### Reverse zones
Reverse zones are supported. You need to make CoreDNS aware of the fact that you are also
authoritative for the reverse. For instance if you want to add the reverse for 10.0.0.0/24, you'll
need to add the zone `0.0.10.in-addr.arpa` to the list of zones. (The fun starts with IPv6 reverse zones
in the ip6.arpa domain.) Showing a snippet of a Corefile:
~~~
etcd skydns.local 0.0.10.in-addr.arpa {
stubzones
...
~~~
Next you'll need to populate the zone with reverse records, here we add a reverse for
10.0.0.127 pointing to reverse.skydns.local.
~~~
% curl -XPUT http://127.0.0.1:4001/v2/keys/skydns/arpa/in-addr/10/0/0/127 \
-d value='{"host":"reverse.skydns.local."}'
~~~
Querying with dig:
~~~
% dig @localhost -x 10.0.0.127 +short
reverse.atoom.net.
~~~
Or with *debug* queries enabled:
~~~
% dig @localhost -p 1053 o-o.debug.127.0.0.10.in-addr.arpa. PTR
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;o-o.debug.127.0.0.10.in-addr.arpa. IN PTR
;; ANSWER SECTION:
127.0.0.10.in-addr.arpa. 300 IN PTR reverse.atoom.net.
;; ADDITIONAL SECTION:
127.0.0.10.in-addr.arpa. 300 CH TXT "reverse.atoom.net.:0(10,0,,false)[0,]"
~~~
## Debug queries
When debug queries are enabled CoreDNS will return errors and etcd records encountered during the resolution
process in the response. The general form looks like this:
skydns.test.skydns.dom.a. 0 CH TXT "127.0.0.1:0(10,0,,false)[0,]"
This shows the complete key as the owername, the rdata of the TXT record has:
`host:port(priority,weight,txt content,mail)[targetstrip,group]`.
Errors when communicating with an upstream will be returned as: `host:0(0,0,error message,false)[0,]`.
An example:
www.example.org. 0 CH TXT "www.example.org.:0(0,0, IN A: unreachable backend,false)[0,]"
Signalling that an A record for www.example.org. was sought, but it failed with that error.
Any errors seen doing parsing will show up like this:
. 0 CH TXT "/skydns/local/skydns/r/a: invalid character '.' after object key:value pair"
which shows `a.r.skydns.local.` has a json encoding problem.
+60
View File
@@ -0,0 +1,60 @@
+++
title = "file"
description = "*file* enables serving zone data from an RFC 1035-style master file. "
weight = 10
tags = [ "middleware" , "file" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The file middleware is used for an "old-style" DNS server. It serves from a preloaded file that exists
on disk. If the zone file contains signatures (i.e. is signed, i.e. DNSSEC) correct DNSSEC answers
are returned. Only NSEC is supported! If you use this setup *you* are responsible for resigning the
zonefile.
## Syntax
~~~
file DBFILE [ZONES...]
~~~
* **DBFILE** the database file to read and parse. If the path is relative the path from the *root*
directive will be prepended to it.
* **ZONES** zones it should be authoritative for. If empty, the zones from the configuration block
are used.
If you want to round robin A and AAAA responses look at the *loadbalance* middleware.
TSIG key configuration is TODO; directive format for transfer will probably be extended with
TSIG key information, something like `transfer out [ADDRESS...] key [NAME[:ALG]] [BASE64]`
~~~
file DBFILE [ZONES... ] {
transfer to ADDRESS...
no_reload
upstream ADDRESS...
}
~~~
* `transfer` enables zone transfers. It may be specified multiples times. `To` or `from` signals
the direction. **ADDRESS** must be denoted in CIDR notation (127.0.0.1/32 etc.) or just as plain
addresses. The special wildcard `*` means: the entire internet (only valid for 'transfer to').
When an address is specified a notify message will be send whenever the zone is reloaded.
* `no_reload` by default CoreDNS will reload a zone from disk whenever it detects a change to the
file. This option disables that behavior.
* `upstream` defines upstream resolvers to be used resolve external names found (think CNAMEs)
pointing to external names. This is only really useful when CoreDNS is configured as a proxy, for
normal authoritative serving you don't need *or* want to use this.
## Examples
Load the `example.org` zone from `example.org.signed` and allow transfers to the internet, but send
notifies to 10.240.1.1
~~~
file example.org.signed example.org {
transfer to *
transfer to 10.240.1.1
}
~~~
+26
View File
@@ -0,0 +1,26 @@
+++
title = "health"
description = "This module enables a simple health check endpoint. By default it will listen on port 8080. "
weight = 11
tags = [ "middleware" , "health" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
~~~
health [ADDRESS]
~~~
Optionally takes an address; the default is `:8080`. The health path is fixed to `/health`. It
will just return "OK" when CoreDNS is healthy, which currently mean: it is up and running.
This middleware only needs to be enabled once.
## Examples
~~~
health localhost:8091
~~~
+51
View File
@@ -0,0 +1,51 @@
+++
title = "hosts"
description = "*hosts* enables serving zone data from a `/etc/hosts` style file. "
weight = 12
tags = [ "middleware" , "hosts" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The hosts middleware is useful for serving zones from a /etc/hosts file. It serves from a preloaded
file that exists on disk. It checks the file for changes and updates the zones accordingly. This
middleware only supports A, AAAA, and PTR records. The hosts middleware can be used with readily
available hosts files that block access to advertising servers.
## Syntax
~~~
hosts [FILE [ZONES...]] {
fallthrough
}
~~~
* **FILE** the hosts file to read and parse. If the path is relative the path from the *root*
directive will be prepended to it. Defaults to /etc/hosts if omitted
* **ZONES** zones it should be authoritative for. If empty, the zones from the configuration block
are used.
* `fallthrough` If zone matches and no record can be generated, pass request to the next middleware.
## Examples
Load `/etc/hosts` file.
~~~
hosts
~~~
Load `example.hosts` file in the current directory.
~~~
hosts example.hosts
~~~
Load example.hosts file and only serve example.org and example.net from it and fall through to the
next middleware if query doesn't match.
~~~
hosts example.hosts example.org example.net {
fallthrough
}
~~~
+273
View File
@@ -0,0 +1,273 @@
+++
title = "kubernetes"
description = "The *kubernetes* middleware enables the reading zone data from a Kubernetes cluster. It implements the [Kubernetes DNS-Based Service Discovery Specification](https://github.com/kubernetes/dns/blob/master/docs/specification.md). "
weight = 13
tags = [ "middleware" , "kubernetes" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
CoreDNS running the kubernetes middleware can be used as a replacement of kube-dns in a kubernetes cluster. See the [deployment](https://github.com/coredns/deployment) repository for details on [how to deploy CoreDNS in Kubernetes](https://github.com/coredns/deployment/tree/master/kubernetes).
## Syntax
```
kubernetes ZONE [ZONE...] [{
[resyncperiod DURATION]
[endpoint URL
[tls CERT-FILE KEY-FILE CACERT-FILE]]
[namespaces NAMESPACE [NAMESPACE...]]
[labels EXPRESSION]
[pods POD-MODE]
[cidrs CIDR [CIDR...]]
[upstream ADDRESS [ADDRESS...]]
[federation NAME DOMAIN]
[autopath [NDOTS [RESPONSE [RESOLV-CONF]]]
[fallthrough]
}]
```
* `resyncperiod` **DURATION**
The Kubernetes data API resynchronization period. Default is 5m. Example values: 60s, 5m, 1h
Example:
```
kubernetes cluster.local. {
resyncperiod 15m
}
```
* `endpoint` **URL**
Use **URL** for a remote k8s API endpoint. If omitted, it will connect to k8s in-cluster using the cluster service account.
Example:
```
kubernetes cluster.local. {
endpoint http://k8s-endpoint:8080
}
```
* `tls` **CERT-FILE KEY-FILE CACERT-FILE**
The TLS cert, key and the CA cert file names for remote k8s connection. This option is ignored if connecting in-cluster (i.e. endpoint is not
specified).
Example:
```
kubernetes cluster.local. {
endpoint https://k8s-endpoint:8443
tls cert key cacert
}
```
* `namespaces` **NAMESPACE [NAMESPACE...]**
Only expose the k8s namespaces listed. If this option is omitted all namespaces are exposed
Example:
```
kubernetes cluster.local. {
namespaces demo default
}
```
* `labels` **EXPRESSION**
Only expose the records for Kubernetes objects that match this label selector. The label selector syntax is described in the [Kubernetes User Guide - Labels](http://kubernetes.io/docs/user-guide/labels/).
Example:
The following example only exposes objects labeled as "application=nginx" in the "staging" or "qa" environments.
```
kubernetes cluster.local. {
labels environment in (staging, qa),application=nginx
}
```
* `pods` **POD-MODE**
Set the mode for handling IP-based pod A records, e.g. `1-2-3-4.ns.pod.cluster.local. in A 1.2.3.4`. This option is provided to facilitate use of SSL certs when connecting directly to pods.
Valid values for **POD-MODE**:
* `disabled`: Default. Do not process pod requests, always returning `NXDOMAIN`
* `insecure`: Always return an A record with IP from request (without checking k8s). This option is is vulnerable to abuse if used maliciously in conjunction with wildcard SSL certs. This option is provided for backward compatibility with kube-dns.
* `verified`: Return an A record if there exists a pod in same namespace with matching IP. This option requires substantially more memory than in insecure mode, since it will maintain a watch on all pods.
Example:
```
kubernetes cluster.local. {
pods verified
}
```
* `cidrs` **CIDR [CIDR...]**
Expose cidr ranges to reverse lookups. Include any number of space delimited cidrs, and/or multiple cidrs options on separate lines. The Kubernetes middleware will respond to PTR requests for ip addresses that fall within these ranges.
Example:
```
kubernetes cluster.local. {
cidrs 10.0.0.0/24 10.0.10.0/25
}
```
* `upstream` **ADDRESS [ADDRESS...]**
Defines upstream resolvers used for resolving services that point to external hosts (External Services). **ADDRESS** can be an ip, an ip:port, or a path to a file structured like resolv.conf.
Example:
```
kubernetes cluster.local. {
upstream 12.34.56.78:5053
}
```
* `federation` **NAME DOMAIN**
Defines federation membership. One line for each federation membership. Each line consists of the name of the federation, and the domain.
Example:
```
kubernetes cluster.local. {
federation myfed foo.example.com
}
```
* `autopath` **[NDOTS [RESPONSE [RESOLV-CONF]]**
Enables server side search path lookups for pods. When enabled, the kubernetes middleware will identify search path queries from pods and perform the remaining lookups in the path on the pod's behalf. The search path used mimics the resolv.conf search path deployed to pods by the "cluster-first" dns-policy. E.g.
```
search ns1.svc.cluster.local svc.cluster.local cluster.local foo.com
```
If no domains in the path produce an answer, a lookup on the bare question will be attempted.
A successful response will contain a question section with the original question, and an answer section containing the record for the question that actually had an answer. This means that the question and answer will not match. To avoid potential client confusion, a dynamically generated CNAME entry is added to join the two. For example:
```
# host -v -t a google.com
Trying "google.com.default.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50957
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;google.com.default.svc.cluster.local. IN A
;; ANSWER SECTION:
google.com.default.svc.cluster.local. 175 IN CNAME google.com.
google.com. 175 IN A 216.58.194.206
```
**Fully Qualified Queries:** There is a known limitation of the autopath feature involving fully qualified queries. When the kubernetes middleware receives a query from a client, it cannot tell the difference between a query that was fully qualified by the user, and one that was expanded by the first search path on the client side.
This means that the kubernetes middleware with autopath enabled will perform a server-side path search for the query `google.com.default.svc.cluster.local.` as if the client had queried just `google.com`. In other words, a query for `google.com.default.svc.cluster.local.` will produce the IP address for `google.com` as seen below.
```
# host -t a google.com
google.com has address 216.58.194.206
google.com.default.svc.cluster.local is an alias for google.com.
# host -t a google.com.default.svc.cluster.local.
google.com has address 216.58.194.206
google.com.default.svc.cluster.local is an alias for google.com.
```
**NDOTS** (default: `0`) This provides an adjustable threshold to prevent server side lookups from triggering. If the number of dots before the first search domain is less than this number, then the search path will not executed on the server side. When autopath is enabled with default settings, the search path is always conducted when the query is in the first search domain `<pod-namespace>.svc.<zone>.`.
**RESPONSE** (default: `NOERROR`) This option causes the kubernetes middleware to return the given response instead of NXDOMAIN when the all searches in the path produce no results. Valid values: `NXDOMAIN`, `SERVFAIL` or `NOERROR`. Setting this to `SERVFAIL` or `NOERROR` should prevent the client from fruitlessly continuing the client side searches in the path after the server already checked them.
**RESOLV-CONF** (default: `/etc/resolv.conf`) If specified, the kubernetes middleware uses this file to get the host's search domains. The kubernetes middleware performs a lookup on these domains if the in-cluster search domains in the path fail to produce an answer. If not specified, the values will be read from the local resolv.conf file (i.e the resolv.conf file in the pod containing CoreDNS). In practice, this option should only need to be used if running CoreDNS outside of the cluster and the search path in /etc/resolv.conf does not match the cluster's "default" dns-policiy.
Enabling autopath requires more memory, since it needs to maintain a watch on all pods. If autopath and `pods verified` mode are both enabled, they will share the same watch. Enabling both options should have an equivalent memory impact of just one.
Example:
```
kubernetes cluster.local. {
autopath 0 NXDOMAIN /etc/resolv.conf
}
```
* `fallthrough`
If a query for a record in the cluster zone results in NXDOMAIN, normally that is what the response will be. However, if you specify this option, the query will instead be passed on down the middleware chain, which can include another middleware to handle the query.
## Examples
**Example 1:** This is a minimal configuration with no options other than zone. It will handle all queries in the `cluster.local` zone and connect to Kubernetes in-cluster, but it will not provide PTR records for services, or A records for pods.
kubernetes cluster.local
**Example 2:** Handle all queries in the `cluster.local` zone. Connect to Kubernetes in-cluster. Handle all `PTR` requests in the `10.0.0.0/16` cidr block. Verify the existence of pods when answering pod requests. Resolve upstream records against `10.102.3.10`. Enable the autopath feature.
kubernetes cluster.local {
cidrs 10.0.0.0/16
pods verified
upstream 10.102.3.10:53
autopath
}
**Selective Exposure Example:** Handle all queries in the `cluster.local` zone. Connect to Kubernetes in-cluster. Only expose objects in the test and staging namespaces. Handle all `PTR` requests that fall between `10.0.0.100` and `10.0.0.255` (expressed as CIDR blocks in the example below). Resolve upstream records using the servers configured in `/etc/resolv.conf`.
kubernetes cluster.local {
namespaces test staging
cidrs 10.0.0.100/30 10.0.0.104/29
cidrs 10.0.0.112/28 10.0.0.128/25
upstream /etc/resolv.conf
}
**Federation Example:** Handle all queries in the `cluster.local` zone. Connect to Kubernetes in-cluster. Handle federated service requests in the `prod` and `stage` federations. Handle all `PTR` requests in the `10.0.0.0/24` cidr block. Resolve upstream records using the servers configured in `/etc/resolv.conf`.
kubernetes cluster.local {
federation prod prod.feddomain.com
federation stage stage.feddomain.com
cidrs 10.0.0.0/24
upstream /etc/resolv.conf
}
**Out-Of-Cluster Example:** Handle all queries in the `cluster.local` zone. Connect to Kubernetes from outside the cluster. Handle all `PTR` requests in the `10.0.0.0/24` cidr block. Verify the existence of pods when answering pod requests. Resolve upstream records against `10.102.3.10`. Enable the autopath feature, using the `cluster.conf` file instead of `/etc/resolv.conf`.
kubernetes cluster.local {
endpoint https://k8s-endpoint:8443
tls cert key cacert
cidrs 10.0.0.0/24
pods verified
upstream 10.102.3.10:53
autopath 0 NOERROR cluster.conf
}
## Wildcards
Some query labels accept a wildcard value to match any value. If a label is a valid wildcard (\*, or the word "any"), then that label will match all values. The labels that accept wildcards are:
* _service_ in an `A` record request: _service_.namespace.svc.zone.
* e.g. `*.ns.svc.myzone.local`
* _namespace_ in an `A` record request: service._namespace_.svc.zone.
* e.g. `nginx.*.svc.myzone.local`
* _port and/or protocol_ in an `SRV` request: __port_.__protocol_.service.namespace.svc.zone.
* e.g. `_http.*.service.ns.svc.`
* multiple wild cards are allowed in a single query.
* e.g. `A` Request `*.*.svc.zone.` or `SRV` request `*.*.*.*.svc.zone.`
+23
View File
@@ -0,0 +1,23 @@
+++
title = "loadbalance"
description = "*loadbalance* acts as a round-robin DNS loadbalancer by randomizing the order of A and AAAA records in the answer. See [Wikipedia](https://en.wikipedia.org/wiki/Round-robin_DNS) about the pros and cons on this setup. It will take care to sort any CNAMEs before any address records, because some stub resolver implementations (like glibc) are particular about that. "
weight = 14
tags = [ "middleware" , "loadbalance" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
~~~
loadbalance [POLICY]
~~~
* **POLICY** is how to balance, the default is "round_robin"
## Examples
~~~
loadbalance round_robin
~~~
+106
View File
@@ -0,0 +1,106 @@
+++
title = "log"
description = "*log* enables query logging to standard output. "
weight = 15
tags = [ "middleware" , "log" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
~~~ txt
log
~~~
* With no arguments, a query log entry is written to *stdout* in the common log format for all requests
~~~ txt
log FILE
~~~
* **FILE** is the log file to create (or append to). The *only* valid name for **FILE** is *stdout*.
~~~ txt
log [NAME] FILE [FORMAT]
~~~
* `NAME` is the name to match in order to be logged
* `FILE` is the log file (again only *stdout* is allowed here).
* `FORMAT` is the log format to use (default is Common Log Format)
You can further specify the class of responses that get logged:
~~~ txt
log [NAME] FILE [FORMAT] {
class [success|denial|error|all]
}
~~~
Here `success` `denial` and `error` denotes the class of responses that should be logged. The
classes have the following meaning:
* `success`: successful response
* `denial`: either NXDOMAIN or NODATA (name exists, type does not)
* `error`: SERVFAIL, NOTIMP, REFUSED, etc. Anything that indicates the remote server is not willing to
resolve the request.
* `all`: the default - nothing is specified.
If no class is specified, it defaults to *all*.
## Log File
The "log file" can only be *stdout*. CoreDNS expects another service to pick up this output and deal
with it, i.e. journald when using systemd or Docker's logging capabilities.
## Log Format
You can specify a custom log format with any placeholder values. Log supports both request and
response placeholders.
The following place holders are supported:
* `{type}`: qtype of the request.
* `{name}`: qname of the request.
* `{class}`: qclass of the request.
* `{proto}`: protocol used (tcp or udp).
* `{when}`: time of the query.
* `{remote}`: client's IP address.
* `{size}`: request size in bytes.
* `{port}`: client's port.
* `{duration}`: response duration.
* `{>bufsize}`: the EDNS0 buffer size advertised.
* `{>do}`: is the EDNS0 DO (DNSSEC OK) bit set.
* `{>id}`: query ID
* `{>opcode}`: query OPCODE.
* `{rcode}`: response RCODE.
* `{rsize}`: response size.
The default Common Log Format is:
~~~ txt
`{remote} - [{when}] "{type} {class} {name} {proto} {size} {>do} {>bufsize}" {rcode} {rsize} {duration}`
~~~
## Examples
Log all requests to stdout
~~~
log stdout
~~~
Custom log format, for all zones (`.`)
~~~
log . stdout "{proto} Request: {name} {type} {>id}"
~~~
Only log denials for example.org (and below to a file)
~~~
log example.org stdout {
class denial
}
~~~
+59
View File
@@ -0,0 +1,59 @@
+++
title = "prometheus"
description = "This module enables prometheus metrics for CoreDNS. "
weight = 16
tags = [ "middleware" , "metrics" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The default location for the metrics is `localhost:9153`. The metrics path is fixed to `/metrics`.
The following metrics are exported:
* coredns_dns_request_count_total{zone, proto, family}
* coredns_dns_request_duration_milliseconds{zone}
* coredns_dns_request_size_bytes{zone, proto}
* coredns_dns_request_do_count_total{zone}
* coredns_dns_request_type_count_total{zone, type}
* coredns_dns_response_size_bytes{zone, proto}
* coredns_dns_response_rcode_count_total{zone, rcode}
Each counter has a label `zone` which is the zonename used for the request/response.
Extra labels used are:
* `proto` which holds the transport of the response ("udp" or "tcp")
* The address family (`family`) of the transport (1 = IP (IP version 4), 2 = IP6 (IP version 6)).
* `type` which holds the query type. It holds most common types (A, AAAA, MX, SOA, CNAME, PTR, TXT,
NS, SRV, DS, DNSKEY, RRSIG, NSEC, NSEC3, IXFR, AXFR and ANY) and "other" which lumps together all
other types.
* The `response_rcode_count_total` has an extra label `rcode` which holds the rcode of the response.
If monitoring is enabled, queries that do not enter the middleware chain are exported under the fake
name "dropped" (without a closing dot - this is never a valid domain name).
## Syntax
~~~
prometheus [ADDRESS]
~~~
For each zone that you want to see metrics for.
It optionally takes an address to which the metrics are exported; the default
is `localhost:9153`. The metrics path is fixed to `/metrics`.
## Examples
Use an alternative address:
~~~
prometheus localhost:9253
~~~
# Bugs
When reloading, we keep the handler running, meaning that any changes to the handler's address
aren't picked up. You'll need to restart CoreDNS for that to happen.
+47
View File
@@ -0,0 +1,47 @@
+++
title = "pprof"
description = "*pprof* publishes runtime profiling data at endpoints under /debug/pprof. "
weight = 17
tags = [ "middleware" , "pprof" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
You can visit `/debug/pprof` on your site for an index of the available endpoints. By default it
will listen on localhost:6053.
> This is a debugging tool. Certain requests (such as collecting execution traces) can be slow. If
> you use pprof on a live site, consider restricting access or enabling it only temporarily.
For more information, please see [Go's pprof
documentation](https://golang.org/pkg/net/http/pprof/) and read
[Profiling Go Programs](https://blog.golang.org/profiling-go-programs).
## Syntax
~~~
pprof [ADDRESS]
~~~
If not specified, ADDRESS defaults to localhost:6053.
## Examples
Enable pprof endpoints:
~~~
pprof
~~~
Listen on an alternate address:
~~~
pprof 10.9.8.7:6060
~~~
Listen on an all addresses on port 6060:
~~~
pprof :6060
~~~
+181
View File
@@ -0,0 +1,181 @@
+++
title = "proxy"
description = "*proxy* facilitates both a basic reverse proxy and a robust load balancer. "
weight = 18
tags = [ "middleware" , "proxy" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The proxy has support for multiple backends. The load balancing features include multiple policies,
health checks, and failovers. If all hosts fail their health check the proxy middleware will fail
back to randomly selecting a target and sending packets to it.
## Syntax
In its most basic form, a simple reverse proxy uses this syntax:
~~~
proxy FROM TO
~~~
* **FROM** is the base domain to match for the request to be proxied.
* **TO** is the destination endpoint to proxy to.
However, advanced features including load balancing can be utilized with an expanded syntax:
~~~
proxy FROM TO... {
policy random|least_conn|round_robin
fail_timeout DURATION
max_fails INTEGER
health_check PATH:PORT [DURATION]
except IGNORED_NAMES...
spray
protocol [dns [force_tcp]|https_google [bootstrap ADDRESS...]|grpc [insecure|CA-PEM|KEY-PEM CERT-PEM|KEY-PEM CERT-PEM CA-PEM]]
}
~~~
* **FROM** is the name to match for the request to be proxied.
* **TO** is the destination endpoint to proxy to. At least one is required, but multiple may be
specified. **TO** may be an IP:Port pair, or may reference a file in resolv.conf format
* `policy` is the load balancing policy to use; applies only with multiple backends. May be one of
random, least_conn, or round_robin. Default is random.
* `fail_timeout` specifies how long to consider a backend as down after it has failed. While it is
down, requests will not be routed to that backend. A backend is "down" if CoreDNS fails to
communicate with it. The default value is 10 seconds ("10s").
* `max_fails` is the number of failures within fail_timeout that are needed before considering
a backend to be down. If 0, the backend will never be marked as down. Default is 1.
* `health_check` will check path (on port) on each backend. If a backend returns a status code of
200-399, then that backend is marked healthy for double the healthcheck duration. If it doesn't,
it is marked as unhealthy and no requests are routed to it. If this option is not provided then
health checks are disabled. The default duration is 30 seconds ("30s").
* **IGNORED_NAMES** in `except` is a space-separated list of domains to exclude from proxying.
Requests that match none of these names will be passed through.
* `spray` when all backends are unhealthy, randomly pick one to send the traffic to. (This is
a failsafe.)
* `protocol` specifies what protocol to use to speak to an upstream, `dns` (the default) is plain
old DNS, and `https_google` uses `https://dns.google.com` and speaks a JSON DNS dialect. Note when
using this **TO** will be ignored. The `grpc` option will talk to a server that has implemented
the [DnsService](https://github.com/coredns/coredns/pb/dns.proto).
An out-of-tree middleware that implements the server side of this can be found at
[here](https://github.com/infobloxopen/coredns-grpc).
## Policies
There are three load-balancing policies available:
* `random` (default) - Randomly select a backend
* `least_conn` - Select the backend with the fewest active connections
* `round_robin` - Select the backend in round-robin fashion
All polices implement randomly spraying packets to backend hosts when *no healthy* hosts are
available. This is to preeempt the case where the healthchecking (as a mechanism) fails.
## Upstream Protocols
Currently `protocol` supports `dns` (i.e., standard DNS over UDP/TCP) and `https_google` (JSON
payload over HTTPS). Note that with `https_google` the entire transport is encrypted. Only *you* and
*Google* can see your DNS activity.
* `dns`: uses the standard DNS exchange. You can pass `force_tcp` to make sure that the proxied connection is performed
over TCP, regardless of the inbound request's protocol.
* `https_google`: bootstrap **ADDRESS...** is used to (re-)resolve `dns.google.com` to an address to
connect to. This happens every 300s. If not specified the default is used: 8.8.8.8:53/8.8.4.4:53.
Note that **TO** is *ignored* when `https_google` is used, as its upstream is defined as
`dns.google.com`.
Debug queries are enabled by default and currently there is no way to turn them off. When CoreDNS
receives a debug query (i.e. the name is prefixed with `o-o.debug.`) a TXT record with Comment
from `dns.google.com` is added. Note this is not always set.
* `grpc`: options are used to control how the TLS connection is made to the gRPC server.
* None - No client authentication is used, and the system CAs are used to verify the server certificate.
* `insecure` - TLS is not used, the connection is made in plaintext (not good in production).
* CA-PEM - No client authentication is used, and the file CA-PEM is used to verify the server certificate.
* KEY-PEM CERT-PEM - Client authentication is used with the specified key/cert pair. The server
certificate is verified with the system CAs.
* KEY-PEM CERT-PEM CA-PEM - Client authentication is used with the specified key/cert pair. The
server certificate is verified using the CA-PEM file.
An out-of-tree middleware that implements the server side of this can be found at
[here](https://github.com/infobloxopen/coredns-grpc).
## Metrics
If monitoring is enabled (via the *prometheus* directive) then the following metric is exported:
* coredns_proxy_request_count_total{proto, proxy_proto, from}
Where `proxy_proto` is the protocol used (`dns`, `grpc`, or `https_google`) and `from` is **FROM**
specified in the config, `proto` is the protocol used by the incoming query ("tcp" or "udp").
## Examples
Proxy all requests within example.org. to a backend system:
~~~
proxy example.org localhost:9005
~~~
Load-balance all requests between three backends (using random policy):
~~~
proxy . dns1.local:53 dns2.local:1053 dns3.local
~~~
Same as above, but round-robin style:
~~~
proxy . dns1.local:53 dns2.local:1053 dns3.local {
policy round_robin
}
~~~
With health checks and proxy headers to pass hostname, IP, and scheme upstream:
~~~
proxy . dns1.local:53 dns2.local:53 dns3.local:53 {
policy round_robin
health_check /health:8080
}
~~~
Proxy everything except requests to miek.nl or example.org
~~~
proxy . backend:1234 {
except miek.nl example.org
}
~~~
Proxy everything except example.org using the host resolv.conf nameservers:
~~~
proxy . /etc/resolv.conf {
except miek.nl example.org
}
~~~
Proxy all requests within example.org to Google's dns.google.com.
~~~
proxy example.org 1.2.3.4:53 {
protocol https_google
}
~~~
Proxy everything with HTTPS to `dns.google.com`, except `example.org`. Then have another proxy in
another stanza that uses plain DNS to resolve names under `example.org`.
~~~
. {
proxy . 1.2.3.4:53 {
except example.org
protocol https_google
}
}
example.org {
proxy . 8.8.8.8:53
}
~~~
+92
View File
@@ -0,0 +1,92 @@
+++
title = "reverse"
description = "The *reverse* middleware allows CoreDNS to respond dynamically to a PTR request and the related A/AAAA request. "
weight = 19
tags = [ "middleware" , "reverse" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
~~~
reverse NETWORK... {
hostname TEMPLATE
[ttl TTL]
[fallthrough]
[wildcard]
~~~
* **NETWORK** one or more CIDR formatted networks to respond on.
* `hostname` injects the IP and zone to a template for the hostname. Defaults to "ip-{IP}.{zone[1]}". See below for template.
* `ttl` defaults to 60
* `fallthrough` if zone matches and no record can be generated, pass request to the next middleware.
* `wildcard` allows matches to catch all subdomains as well.
### Template Syntax
The template for the hostname is used for generating the PTR for a reverse lookup and matching the
forward lookup back to an IP.
#### `{ip}`
The `{ip}` symbol is **required** to make reverse work.
For IPv4 lookups the IP is directly extracted
With IPv6 lookups the ":" is removed, and any zero ranged are expanded, e.g.,
"ffff::ffff" results in "ffff000000000000000000000000ffff"
#### `{zone[i]}`
The `{zone[i]}` symbol is **optional** and can be replaced by a fixed (zone) string.
The zone will be matched by the zones listed in *this* configuration stanza.
`i` needs to be replaced with the index of the configured listener zones, starting with 1.
## Examples
~~~ txt
arpa compute.internal {
# proxy unmatched requests
proxy . 8.8.8.8
# answer requests for IPs in this network
# PTR 1.0.32.10.in-addr.arpa. 3600 ip-10.0.32.1.compute.internal.
# A ip-10.0.32.1.compute.internal. 3600 10.0.32.1
# v6 is also possible
# PTR 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.d.f.ip6.arpa. 3600 ip-fd010000000000000000000000000001.compute.internal.
# AAAA ip-fd010000000000000000000000000001.compute.internal. 3600 fd01::1
reverse 10.32.0.0/16 fd01::/16 {
# template of the ip injection to hostname, zone resolved to compute.internal.
hostname ip-{ip}.{zone[2]}
ttl 3600
# Forward unanswered or unmatched requests to proxy
# without this flag, requesting A/AAAA records on compute.internal. will end here.
fallthrough
}
}
~~~
~~~ txt
32.10.in-addr.arpa.arpa arpa.company.org {
reverse 10.32.0.0/16 {
# template of the ip injection to hostname, zone resolved to arpa.company.org.
hostname "ip-{ip}.v4.{zone[2]}"
ttl 3600
# fallthrough is not required, v4.arpa.company.org. will be only answered here
}
# cidr closer to the ip wins, so we can overwrite the "default"
reverse 10.32.2.0/24 {
# its also possible to set fix domain suffix
hostname ip-{ip}.fix.arpa.company.org.
ttl 3600
}
}
~~~
+66
View File
@@ -0,0 +1,66 @@
+++
title = "rewrite"
description = "*rewrite* performs internal message rewriting. "
weight = 20
tags = [ "middleware" , "rewrite" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
Rewrites are invisible to the client. There are simple rewrites (fast) and complex rewrites
(slower), but they're powerful enough to accommodate most dynamic back-end applications.
## Syntax
~~~
rewrite FIELD FROM TO
~~~
* **FIELD** is (`type`, `class`, `name`, ...)
* **FROM** is the exact name of type to match
* **TO** is the destination name or type to rewrite to
When the FIELD is `type` and FROM is (`A`, `MX`, etc.), the type of the message will be rewritten;
e.g., to rewrite ANY queries to HINFO, use `rewrite type ANY HINFO`.
When the FIELD is `class` and FROM is (`IN`, `CH`, or `HS`) the class of the message will be
rewritten; e.g., to rewrite CH queries to IN use `rewrite class CH IN`.
When the FIELD is `name` the query name in the message is rewritten; this
needs to be a full match of the name, e.g., `rewrite name miek.nl example.org`.
When the FIELD is `edns0` an EDNS0 option can be appended to the request as described below.
If you specify multiple rules and an incoming query matches on multiple (simple) rules, only
the first rewrite is applied.
## EDNS0 Options
Using FIELD edns0, you can set, append, or replace specific EDNS0 options on the request.
* `replace` will modify any matching (what that means may vary based on EDNS0 type) option with the specified option
* `append` will add the option regardless of what options already exist
* `set` will modify a matching option or add one if none is found
Currently supported are `EDNS0_LOCAL` and `EDNS0_NSID`.
### `EDNS0_LOCAL`
This has two fields, code and data. A match is defined as having the same code. Data may be a string, or if
it starts with `0x` it will be treated as hex. Example:
~~~
rewrite edns0 local set 0xffee 0x61626364
~~~
rewrites the first local option with code 0xffee, setting the data to "abcd". Equivalent:
~~~
rewrite edns0 local set 0xffee abcd
~~~
### `EDNS0_NSID`
This has no fields; it will add an NSID option with an empty string for the NSID. If the option already exists
and the action is `replace` or `set`, then the NSID in the option will be set to the empty string.
+28
View File
@@ -0,0 +1,28 @@
+++
title = "root"
description = "*root* simply specifies the root of where CoreDNS finds (e.g.) zone files. "
weight = 21
tags = [ "middleware" , "root" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The default root is the current working directory of CoreDNS. A relative root path is relative to
the current working directory.
## Syntax
~~~ txt
root PATH
~~~
**PATH** is the directory to set as CoreDNS' root.
## Examples
Serve zone data (when the *file* middleware is used) from `/etc/coredns/zones`:
~~~ txt
root /etc/coredns/zones
~~~
+44
View File
@@ -0,0 +1,44 @@
+++
title = "secondary"
description = "*secondary* enables serving a zone retrieved from a primary server. "
weight = 22
tags = [ "middleware" , "secondary" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
~~~
secondary [ZONES...]
~~~
* **ZONES** zones it should be authoritative for. If empty, the zones from the configuration block
are used. Note that without a remote address to *get* the zone from, the above is not that useful.
A working syntax would be:
~~~
secondary [zones...] {
transfer from ADDRESS
transfer to ADDRESS
upstream ADDRESS...
}
~~~
* `transfer from` specifies from which address to fetch the zone. It can be specified multiple times;
if one does not work, another will be tried.
* `transfer to` can be enabled to allow this secondary zone to be transferred again.
* `upstream` defines upstream resolvers to be used resolve external names found (think CNAMEs)
pointing to external names. This is only really useful when CoreDNS is configured as a proxy, for
normal authoritative serving you don't need *or* want to use this.
## Examples
~~~
secondary example.org {
transfer from 10.0.1.1
transfer from 10.1.2.1
}
~~~
+36
View File
@@ -0,0 +1,36 @@
+++
title = "tls"
description = "*tls* allows you to configure the server certificates for the TLS and gRPC servers. For other types of servers it is ignored. "
weight = 23
tags = [ "middleware" , "tls" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
~~~ txt
tls CERT KEY CA
~~~
## Examples
Start a DNS-over-TLS server.
~~~
tls://.:4453 {
tls cert.pem key.pem ca.pem
proxy . /etc/resolv.conf
}
~~~
Start a DNS-over-gRPC server. If the `tls` directive were omitted, then
it would use plain HTTP not HTTPS.
~~~
grpc://.:443 {
tls cert.pem key.pem ca.pem
proxy . /etc/resolv.conf
}
~~~
+78
View File
@@ -0,0 +1,78 @@
+++
title = "trace"
description = "This module enables OpenTracing-based tracing of DNS requests as they go through the middleware chain. "
weight = 24
tags = [ "middleware" , "trace" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
## Syntax
The simplest form is just:
~~~
trace [ENDPOINT-TYPE] [ENDPOINT]
~~~
* **ENDPOINT-TYPE** is the type of tracing destination. Currently only `zipkin` is supported
and that is what it defaults to.
* **ENDPOINT** is the tracing destination, and defaults to `localhost:9411`. For Zipkin, if
ENDPOINT does not begin with `http`, then it will be transformed to `http://ENDPOINT/api/v1/spans`.
With this form, all queries will be traced.
Additional features can be enabled with this syntax:
~~~
trace [ENDPOINT-TYPE] [ENDPOINT] {
every AMOUNT
service NAME
client_server
}
~~~
* `every` **AMOUNT** will only trace one query of each AMOUNT queries. For example, to trace 1 in every
100 queries, use AMOUNT of 100. The default is 1.
* `service` **NAME** allows you to specify the service name reported to the tracing server.
Default is `coredns`.
* `client_server` will enable the `ClientServerSameSpan` OpenTracing feature.
## Zipkin
You can run Zipkin on a Docker host like this:
```
docker run -d -p 9411:9411 openzipkin/zipkin
```
## Examples
Use an alternative Zipkin address:
~~~
trace tracinghost:9253
~~~
or
~~~
trace zipkin tracinghost:9253
~~~
If for some reason you are using an API reverse proxy or something and need to remap
the standard Zipkin URL you can do something like:
~~~
trace http://tracinghost:9411/zipkin/api/v1/spans
~~~
Trace one query every 10000 queries, rename the service, and enable same span:
~~~
trace tracinghost:9411 {
every 10000
service dnsproxy
client_server
}
~~~
+43
View File
@@ -0,0 +1,43 @@
+++
title = "whoami"
description = "*whoami* returns your local IP address, port and transport used. Your local IP address is returned in the additional section as either an A or AAAA record. "
weight = 25
tags = [ "middleware" , "whoami" ]
categories = [ "middleware" ]
date = "2017-07-24T15:25:40+00:00"
+++
The port and transport are included in the additional section as a SRV record, transport can be
"tcp" or "udp".
~~~ txt
._<transport>.qname. 0 IN SRV 0 0 <port> .
~~~
The *whoami* middleware will respond to every A or AAAA query, regardless of the query name.
## Syntax
~~~ txt
whoami
~~~
## Examples
~~~ txt
.:53 {
whoami
}
~~~
When queried for "example.org A", CoreDNS will respond with:
~~~ txt
;; QUESTION SECTION:
;example.org. IN A
;; ADDITIONAL SECTION:
example.org. 0 IN A 10.240.0.1
_udp.example.org. 0 IN SRV 0 0 40212
~~~
View File
+2
View File
@@ -0,0 +1,2 @@
[release]
version = "009"
+27
View File
@@ -0,0 +1,27 @@
# Oneliners for subtext on the different pages.
# Don't create new paragraphs, because each <p> adds a read line.
[docs]
content = """
How to use CoreDNS.
"""
[blog]
content = """
News covering CoreDNS.
"""
[middleware]
content = """
Here you can find all [in-tree](https://github.com/coredns/coredns/tree/master/middleware) middleware for CoreDNS.
"""
[exmiddleware]
content = """
Here you can find all out-of-tree middleware for CoreDNS.
"""
[community]
content = """
CoreDNS is developed in the open. Here are some of the channels we use to communicate and contribute.
"""
View File
+10
View File
@@ -0,0 +1,10 @@
{{ if .Site.Params.popup }}
<div class="message focus text-center" data-component="message"> <span class="close small"></span>
Currently we are aware of <mark>issues</mark> with CoreDNS.
See <a href="https://coredns.io/-">this page</a> for more info.
</div>
{{else}}
<!-- empty -->
{{ end }}
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

+1
View File
@@ -0,0 +1 @@
.DS_Store
+20
View File
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2017 mohamed jebli
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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.
+176
View File
@@ -0,0 +1,176 @@
# kube Theme for Hugo
`kube` Kube is a professional and a responsive Hugo theme for developers and designers that offers a documentation section mixed with a landing page and a blog.
I create this theme based on the `Version 6.5.2` [Kube Framework](https://imperavi.com/kube/).
![kube hugo landingPage](https://cldup.com/RjWtdJZNae.png)
# Demo
To see this theme in action, check out [kube project](http://kube.elemnts.org) which is rendered with this theme and some conetnt for documentation and blog posts.
## Features
- Mobile-first Design : Every element in kube is mobile-first and fully embraces latest and greatest tech.
- Responsive Design : Optimized for mobile, tablet, desktop
- Horizontal Rhythm : Like Kube framework this theme is based on a 4px vertical grid.
- Typography : beautiful typographie choice
- Google Analytics : Google Analytics using the internal async template
- Disqus Commenting : Post comments with Disqus using the internal template
- OpenGraph support : SEO-optimized using OpenGraph
- Schema Structured Data : Schema Structured Data and Meta tags
- Paginated Lists : Simple list pagination with page indicators
- Reading Time : Post reading time and update notice set user expectations
- Meta data for all blog article : Rich post data including links to category and tag taxonomy listings, author and word count
- Related Posts : Related Content for increased page views and reader loyalty
- Block Templates : Block Templates for foolproof layout extensions
- Table of Contents : Accessible Table of Contents for documentation
- SEO Site Verification : Site verification with Google, Bing Alexa and Yandex
- 404 page : 404 page with animated background
## Installation
Inside the folder of your Hugo site run:
$ mkdir themes
$ cd themes
$ git clone https://github.com/jeblister/kube.git
For more information read the official [setup guide](//gohugo.io/overview/installing/) for Hugo.
Copy custom archetypes to your site:
```shell
cp themes/kube/archetypes/* archetypes
```
Next, take a look in the `exampleSite` folder at. This directory contains an example config file and the content for the demo. It serves as an example setup for your blog.
Copy at least the `config.toml` in the root directory of your website. Overwrite the existing config file if necessary.
Hugo includes a development server, so you can view your changes as you go :
``` sh
hugo server -w
```
Now you can go to [localhost:1313](http://localhost:1313) and the `kube`
theme should be visible.
## Getting Started
There are a few concepts this theme employs to make a personal documentation site. It's important to read this as you may not see what you expect upon launching. It assumes you want to call your documentation posts `docs` and organizes them as such. For example, creating a new docs with Hugo would require you typing:
```
$ hugo new --kind docs docs/my-new-doc.md
```
It also assumes you want to display three types of content `docs` and `blog` and some pages : the `faq`, `company` and `sign-in` pages and and display links to this pages in the menu. This guide will take you through the steps to configure your documentation site to use the theme.
### Configuring you website
#### Where should blog post markdown files be stored?
The theme works with other content types, but docs pages work best when grouped under `docs`. When using the `docs` content type you'll have a customized list page sorted by `weight` and the default list page for all documentation. Here's an example:
![Custom List docs Page](https://cldup.com/8k1nU8TLuU.png)
#### Defining yourself as the Author
In this case you would want to add `author = "your name"` variable like your name to your post's Front Matter.
#### Webmaster Verification
Verify your site with several webmaster tools including Google, Bing, Alexa and Yandex. To allow verification of your site with any or all of these providers simply add the following to your `config.toml` and fill in their respective values:
```toml
[params.seo.webmaster_verifications]
google = "" # Optional, Google verification code
bing = "" # Optional, Bing verification code
alexa = "" # Optional, Alexa verification code
yandex = "" # Optional, Yandex verification code
```
### Index Blocking
Just because a page appears in your `sitemap.xml` does not mean you want it to appear in a SERP. Examples of pages which will appear in your `sitemap.xml` that you typically do not want indexed by crawlers include error pages, search pages, legal pages, and pages that simply list summaries of other pages.
Though it's possible to block search indexing from a `robots.txt` file, kube makes it possible to block page indexing using Hugo configuration as well. By default the following page types will be blocked:
- Section Pages (e.g. Post listings)
- Taxonomy Pages (e.g. Category and Tag listings)
- Taxonomy Terms Pages (e.g. Pages listing taxonomies)
To customize default blocking configure the `noindex_kinds` setting in the `[params]` section of your `config.toml`. For example, if you want to enable crawling for sections appearing in [Section Menu](#adding-a-section-menu) add the following to your configuration file:
```
[params]
noindex_kinds = [
"taxonomy",
"taxonomyTerm"
]
```
To block individual pages from being indexed add `nofollow` to your page's front matter and set the value to `true`, like:
```toml
noindex = true
```
And, finally, if you're using Hugo `v0.18` or better, you can also add an `_index.md` file with the `noindex` front matter to control indexing for specific section list layouts:
```shell
├── content
│ ├── modules
│ │ ├── starry-night.md
│ │ └── flying-toilets.md
│ └── news
│ ├── _index.md
│ └── return-flying-toasters.md
```
To learn more about how crawlers use this feature read [block search indexing with meta tags](https://support.google.com/webmasters/answer/93710).
### Custom CSS
To add your own theme css or override existing CSS without having to change theme files do the following:
1. Create a `style.css` in your site's `layouts/static/css directory` or use `custom.css` file in 'themes/kube/static/css/custom.css`
1. Add link to this file in 'themes/kube/layouts/_default/baseof.html'.
Default `style block` :
```html
<!-- Your own theme here -->
<link href="/css/custom.css" rel="stylesheet" type="text/css">
```
## Contributing
Did you find a bug or have an ideas for new features? Feel free to use the issue tracker to let me know or make a pull request.
There's only one rule...there are no rules.
## License
MIT
## Credit
[kube framework]: https://imperavi.com/kube/
[after dark]: https://github.com/comfusion/after-dark
## Contact
This is the second theme I've made for Hugo, so I'm sure I've done some things wrong or assumed too much. If you have ideas or things that should be fixed, please let me know.
- [Mohamed JEBLI](http://findme.surge.sh) [@jebli_7](http://twitter.com/jebli_7)
+9
View File
@@ -0,0 +1,9 @@
+++
title = ""
description = ""
weight = 20
draft = false
tags = ""
slug = ""
author = "joe"
+++
+8
View File
@@ -0,0 +1,8 @@
+++
title = ""
description = ""
weight = 20
draft = false
bref = ""
toc = true
+++
+25
View File
@@ -0,0 +1,25 @@
baseURL = "/"
languageCode = "en-us"
title = "Kube for Hugo"
theme = "kube"
description = "Kube is a professional and a responsive Hugo theme for developers and designers that offers a documentation section mixed with a landing page and a blog"
Paginate = 4
[Params]
RSSLink = "/index.xml"
author = "newpixcom" # add your company name
github = "" # add your github profile name
twitter = "" # add your twitter profile
email = "myemail@myaddress.xxx"
[[menu.main]]
name = "Docs"
weight = -100
url = "/docs/"
[[menu.main]]
name = "Blog"
weight = -100
url = "/blog/"
[[menu.main]]
name = "Faq"
weight = -100
url = "/faq/"
@@ -0,0 +1,20 @@
+++
title = "Sign In"
+++
<form action="" data-component="validate" method="post" class="form form-centered"><input type="hidden" name="authorize-token" value="">
<div class="form-item">
<label>Email <span id="user-email-validation-error"></span></label>
<input type="email" name="user-email" autofocus="true" autocomplete="off" style="background-image: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAAAXNSR0IArs4c6QAAAPhJREFUOBHlU70KgzAQPlMhEvoQTg6OPoOjT+JWOnRqkUKHgqWP4OQbOPokTk6OTkVULNSLVc62oJmbIdzd95NcuGjX2/3YVI/Ts+t0WLE2ut5xsQ0O+90F6UxFjAI8qNcEGONia08e6MNONYwCS7EQAizLmtGUDEzTBNd1fxsYhjEBnHPQNG3KKTYV34F8ec/zwHEciOMYyrIE3/ehKAqIoggo9inGXKmFXwbyBkmSQJqmUNe15IRhCG3byphitm1/eUzDM4qR0TTNjEixGdAnSi3keS5vSk2UDKqqgizLqB4YzvassiKhGtZ/jDMtLOnHz7TE+yf8BaDZXA509yeBAAAAAElFTkSuQmCC&quot;); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;">
</div>
<div class="form-item">
<label>Password <span id="user-password-validation-error"></span></label>
<input type="password" name="user-password" autocomplete="off" style="background-image: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAAAXNSR0IArs4c6QAAAPhJREFUOBHlU70KgzAQPlMhEvoQTg6OPoOjT+JWOnRqkUKHgqWP4OQbOPokTk6OTkVULNSLVc62oJmbIdzd95NcuGjX2/3YVI/Ts+t0WLE2ut5xsQ0O+90F6UxFjAI8qNcEGONia08e6MNONYwCS7EQAizLmtGUDEzTBNd1fxsYhjEBnHPQNG3KKTYV34F8ec/zwHEciOMYyrIE3/ehKAqIoggo9inGXKmFXwbyBkmSQJqmUNe15IRhCG3byphitm1/eUzDM4qR0TTNjEixGdAnSi3keS5vSk2UDKqqgizLqB4YzvassiKhGtZ/jDMtLOnHz7TE+yf8BaDZXA509yeBAAAAAElFTkSuQmCC&quot;); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;">
</div>
<p><button class="button primary width-100">Log in</button></p>
<p><a href="/password-recovery/" class="small muted">Forgot password?</a></p>
<p class="small">If you have any questions about authorization or you're our customer but haven't receive your login credentials, just send us a short email at <b>support@company.com</b> and we'll fix it right away.</p>
</form>
@@ -0,0 +1,207 @@
+++
date = "2017-04-10T16:42:50+01:00"
draft = false
weight = 180
description = "Smoothly and reliably collapse elements for extra convenience"
title = "Collapse"
bref = "A demo to collapsable elements"
+++
<h3 class="section-head" id="h-base"><a href="#h-base">Base</a></h3>
<div class="example">
<div class="my-collapse" data-component="collapse" id="my-collapse">
<h4><a class="collapse-toggle" href="#collapse-box-1">Item 1</a></h4>
<div class="collapse-box hide" id="collapse-box-1">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<h4><a class="collapse-toggle" href="#collapse-box-2">Item 2</a></h4>
<div class="collapse-box" id="collapse-box-2">
<p>I look active on load.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<h4><a class="collapse-toggle" href="#collapse-box-3">Item 3</a></h4>
<div class="collapse-box hide" id="collapse-box-3">
<h6>Important Heading</h6>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-collapse"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"collapse"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-1"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-1"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-2"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-2"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-3"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-3"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-navigation-example"><a href="#h-navigation-example">Navigation Example</a></h3>
<p>Here you can see a list of items forming a navigation menu, with a nested list which acts as a collapsable element</p>
<div class="example">
<ul id="demo-nav-collapse">
<li>
<a href="#">Installation</a>
</li>
<li>
<a href="#">Configuration</a>
</li>
<li>
<a href="#">Adding Content</a>
</li>
<li>
<a href="#">Templates</a>
</li>
<li data-component="collapse">
<a class="collapse-toggle" href="#languages-box-2">Languages <span class="caret down"></span></a>
<ul class="collapse-box" id="languages-box-2">
<li>
<a href="#">Setup</a>
</li>
<li>
<a href="#">Translating content</a>
</li>
<li>
<a href="#">Language variables</a>
</li>
<li>
<a href="#">Supporting RTL</a>
</li>
</ul>
</li>
<li>
<a href="#">Settings</a>
</li>
<li>
<a href="#">Callbacks</a>
</li>
<li>
<a href="#">API</a>
</li>
</ul>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"collapse"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#toggle-box"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>
Toggle
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"caret down"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"toggle-box"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-settings"><a href="#h-settings">Settings</a></h3>
<p>Settings are pretty straightforward: you can toggle, denote active element, turn animation on and off, and more.</p>
<h5>toggle</h5>
<ul>
<li>Type: <var>boolean</var></li>
<li>Default: <var>true</var></li>
</ul>
<h5>active</h5>
<ul>
<li>Type: <var>string or boolean</var></li>
<li>Default: <var>false</var></li>
</ul>
<h5>toggleClass</h5>
<ul>
<li>Type: <var>string</var></li>
<li>Default: <var>'collapse-toggle'</var></li>
</ul>
<p>Sets a class of a collapsable object.</p>
<h5>boxClass</h5>
<ul>
<li>Type: <var>string</var></li>
<li>Default: <var>'collapse-box'</var></li>
</ul>
<p>Sets a class for collapsable object's content</p>
<h5>animation</h5>
<ul>
<li>Type: <var>boolean</var></li>
<li>Default: <var>true</var></li>
</ul>
<p>Turns animation on and off.</p>
<h3 class="section-head" id="h-callbacks"><a href="#h-callbacks">Callbacks</a></h3>
<h5>open</h5>
<pre class="code skip">$(<span class="hljs-string">'#my-collapse'</span>).on(<span class="hljs-string">'open.collapse'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</pre>
<h5>opened</h5>
<pre class="code skip">$(<span class="hljs-string">'#my-collapse'</span>).on(<span class="hljs-string">'opened.collapse'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</pre>
<h5>close</h5>
<pre class="code skip">$(<span class="hljs-string">'#my-collapse'</span>).on(<span class="hljs-string">'close.collapse'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</pre>
<h5>closed</h5>
<pre class="code skip">$(<span class="hljs-string">'#my-collapse'</span>).on(<span class="hljs-string">'closed.collapse'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</pre>
<h3 class="section-head" id="h-api"><a href="#h-api">API</a></h3>
<p>We love APIs, and for interactive elements such as collapsable elements we offer ways to programmatically open and close individual elements, or all at once.</p>
<div class="example">
<p><button class="button outline" onclick="$('#my-collapse-api').collapse('open', '#box-2');">Open</button> <button class="button outline" onclick="$('#my-collapse-api').collapse('close', '#box-2');">Close</button> <button class="button outline" onclick="$('#my-collapse-api').collapse('openAll');">Open All</button> <button class="button outline" onclick="$('#my-collapse-api').collapse('closeAll');">Close All</button></p><br>
<div class="my-collapse" data-component="collapse" id="my-collapse-api">
<h4><a class="collapse-toggle" href="#box-1">Item 1</a></h4>
<div class="collapse-box hide" id="box-1">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<h4><a class="collapse-toggle" href="#box-2">Item 2</a></h4>
<div class="collapse-box hide" id="box-2">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<h4><a class="collapse-toggle" href="#box-3">Item 3</a></h4>
<div class="collapse-box hide" id="box-3">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"$('#my-collapse-api').collapse('open', '#box-2');"</span>&gt;</span>Open<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"$('#my-collapse-api').collapse('close', '#box-2');"</span>&gt;</span>Close<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"$('#my-collapse-api').collapse('openAll');"</span>&gt;</span>Open All<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"$('#my-collapse-api').collapse('closeAll');"</span>&gt;</span>Close All<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-collapse-api"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"collapse"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-1"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-1"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-2"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-2"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-3"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-3"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<h5>open</h5>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-collapse'</span>).collapse(<span class="hljs-string">'open'</span>);
</pre>
<h5>close</h5>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-collapse'</span>).collapse(<span class="hljs-string">'close'</span>);
</pre>
<h5>openAll</h5>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-collapse'</span>).collapse(<span class="hljs-string">'openAll'</span>);
</pre>
<h5>closeAll</h5>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-collapse'</span>).collapse(<span class="hljs-string">'closeAll'</span>);
</pre>
@@ -0,0 +1,10 @@
+++
date = "2017-04-02T21:56:55+01:00"
title = "Inline 🐣Text Styles"
tags = ["markdown","example"]
categories = ["general"]
draft = false
description = "This article is just a demo."
+++
Chocolate tiramisu pastry a link cotton candy sesame snaps. Dessert cake chocolate bar a bold part sugar plum bonbon marshmallow lollipop toffee soufflé. Donut caramels chocolate bar. Oat cake cookie a marked part cheesecake donut. Jelly-o <some> $code marzipan cake. Bonbon sesame snaps chocolate an italic part oat cake pudding sweet roll caramels bonbon. Soufflé muffin 👻 gummies sugar plum dessert bonbon bear claw. Sweet ice cream jujubes. Marzipan sugar plum pastry chocolate ⌘+A bar fruitcake. Lollipop lollipop brownie.
@@ -0,0 +1,158 @@
+++
date = "2017-04-10T16:41:34+01:00"
draft = false
weight = 90
description = "Versatile and refined messages, ideal for daily use"
title = "Messages"
bref = "Messages are an essential part of modern web and messages in Kube look nice"
+++
<h3 class="section-head" id="h-usage"><a href="#h-usage">Usage</a></h3>
<div class="example">
<div class="message open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="#install">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message error open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message error"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message success open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message success"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message warning open" data-component="message" data-loaded="true">
<h5>Warning!</h5>You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"message warning"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"message"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h5</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">h5</span>&gt;</span>
...
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"close small"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<div class="example">
<div class="message focus open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message focus"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message black open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small white"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message black"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message inverted open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message inverted"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<h3 class="section-head" id="h-options"><a href="#h-options">Options</a></h3>
<table>
<thead>
<tr>
<th class="w30">Name</th>
<th class="w30">Type</th>
<th class="w40">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>closeSelector</code></td>
<td><var>string</var></td>
<td>.close</td>
</tr>
<tr>
<td><code>closeEvent</code></td>
<td><var>string</var></td>
<td>click</td>
</tr>
<tr>
<td><code>animationOpen</code></td>
<td><var>string</var></td>
<td>fadeIn</td>
</tr>
<tr>
<td><code>animationClose</code></td>
<td><var>string</var></td>
<td>fadeOut</td>
</tr>
</tbody>
</table>
<h4>Set an option</h4>
<p>Via data attribute:</p>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"message"</span> data-component=<span class="hljs-string">"message"</span> data-close-selector=<span class="hljs-string">".my-custom-close"</span>&gt;
... &lt;span <span class="hljs-built_in">class</span>=<span class="hljs-string">"my-custom-close small"</span>&gt;&lt;/span&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
<p>Via Javascript:</p>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-message'</span>).message({
<span class="hljs-symbol">closeSelector:</span> <span class="hljs-string">'.my-custom-close'</span>
});
</pre>
<h3 class="section-head" id="h-methods"><a href="#h-methods">Methods</a></h3>
<p><button onclick="$('#message-1').message('open')">Open</button> <button onclick="$('#message-1').message('close')">Close</button></p>
<div class="message open" data-component="message" data-loaded="true" id="message-1">
You have 2 modules waiting to installation. <a href="#install">Install</a> <span class="close small"></span>
</div>
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>close</code></td>
<td>Manually closes a message.</td>
</tr>
<tr>
<td><code>open</code></td>
<td>Opens a message if it has been closed.</td>
</tr>
</tbody>
</table>
<h4>Example</h4>
<pre class="code">$(<span class="hljs-string">'#my-message'</span>).<span class="hljs-keyword">message</span>(<span class="hljs-string">'close'</span>);</pre>
<h3 class="section-head" id="h-callbacks"><a href="#h-callbacks">Callbacks</a></h3>
<table>
<thead>
<tr>
<th>Callback</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>open</code></td>
<td>This event fires immediately when the open instance method is called.</td>
</tr>
<tr>
<td><code>opened</code></td>
<td>This event is fired when the message has been opened, will wait for CSS animation to complete.</td>
</tr>
<tr>
<td><code>close</code></td>
<td>This event fires immediately when the close instance method is called.</td>
</tr>
<tr>
<td><code>closed</code></td>
<td>This event is fired when the message has been closed, will wait for CSS animation to complete.</td>
</tr>
</tbody>
</table>
<h4>Example</h4>
<pre class="code skip">$(<span class="hljs-string">'#my-message'</span>).on(<span class="hljs-string">'closed.message'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something</span>
})
</pre>
@@ -0,0 +1,23 @@
+++
date = "2017-04-02T22:01:15+01:00"
title = "Prototyping with markdown"
tags = ["markdown","prototype", "hugo"]
categories = ["design"]
description = "An idea to make website protoype with markdown"
draft = false
weight = 30
+++
<img data-src="https://cldup.com/3tov0aCFh8.png" class="lazyload">
I have been working on a large set of documentation for a prototype that will eventually make it into a product. One issue with the publishing system at my company is that it makes doing prototypes, or really anything not within the rigidly and narrowly scoped model, difficult to set up. It takes a lot of work just to get to the point where you can begin writing.
Since time was of the essence and writing is expensive, I decided to do the prototype outside of the publishing system. I also decided to avoid using the rigid DocBook variant we use. Instead, **I figured I do the prototype in Markdown using Hugo generator**. It gives me reasonably ~full featured Markdown support, flexibility to work wherever I want, easy HTML~ ,nd the stack/sheet metaphor fits nicely with topic based writing.
I wasn't sure how well the experiment was going to work when I started, but a few weeks in I think it is great. ~I was able to rapidly prototype fifteen topics in about ten days.~ The prototype pages look fairly close to what our actual system generates. ~I can quickly make changes to the content as needed and republish.~ ~The fact that I can work multi-platform is great. I am not chained to my desk. I can demo changes easily.~
~The fact that I am working in text that doesn't have to be structured in a rigid format makes the work flow faster~. It provides flexibility for quick changes, yet also allows for topic orientation.
For final production and long term maintenance, unstructured Markdown is not a great solution. There the benefits of the rigidity outweigh the cost. The rigidity enforces uniformity that large groups of variously skilled writers need to create and maintain content at scale.
> For small, fast projects or prototyping Markdown, with Hugo, have proven to be an excellent solution.
@@ -0,0 +1,452 @@
+++
title = "Typography with kube"
weight = 25
draft = false
description = "Always precise spacing and perfect font size"
bref = "Typography is perhaps one of the most important and most visible things on a web page. Even slightest imperfection can ruin otherwise perfect website. With Kube, you will have perfect typography with ideal spacing, font sizes and proportions, regardless of the exact style or font you choose for your site."
+++
<h3 class="section-head" id="h-get-started"><a href="#h-get-started">Get Started</a></h3>
<p>Typography of Kube based on the 4px horizontal grid, it means that for the headers, paragraphs, quotes and any other texts chosen are a combination of line-height, that fit into the 4px grid and help set the horizontal rhythm of design by default.</p>
<figure>
<img alt="4px horizontal rhythm" height="180" src="/img/kube/typography/01.png" width="676">
<figcaption>
4px grid for typography - the magic of the horizontal rhythm
</figcaption>
</figure>
<p>With this feature, you can quickly and easily make a solid and harmonious-looking website and UI design. You do not need to do complicated calculations to find the size and proportions of the text baseline, no need to look for the magic formula to build a horizontal rhythm. Magic is already in Kube.</p>
<p>You can use all the default settings of typography and it will always look balanced. But also you can easily change any font sizes, just try to set the value of line-height fold for 4px and your texts will still look great.</p>
<p>Additional balance and harmony, creates a classic typography scale, used in Kube.</p>
<figure>
<img alt="the typography scale" height="140" src="/img/kube/typography/02.png" width="520">
<figcaption>
The typography scale helps to build a balance between the size of headings and text elements
</figcaption>
</figure>
<h3 class="section-head" id="h-headings"><a href="#h-headings">Headings</a></h3>
<p>Use h1-h6 tags or <code>.h1-.h6</code> classes to define headers and <code>class="title"</code> for the title, which is suitable for the most important inscriptions, for example, in the hero or covers.</p>
<div class="example">
<h1 class="title">Title</h1>
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"title"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
...
<span class="hljs-tag">&lt;<span class="hljs-name">h6</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">h6</span>&gt;</span></pre>
</div>
<h3 class="section-head" id="h-paragraphs"><a href="#h-paragraphs">Paragraphs</a></h3>
<p>The base pragraph has an ideal ratio of font size and baseline. This text is easy to read in most cases.</p>
<div class="example">
<p class="section-item-desc">16px/24px</p>
<p>By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.</p>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></pre>
</div>
<p>In special cases, you can use modifiers which increase or decrease the text size. It is useful for building a variety of websites and UI, when you need to make a lead text or signatures with a small font size .</p>
<div class="example">
<p class="section-item-desc">20px/32px</p>
<p class="large">By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.</p>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"large"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></pre>
</div>
<div class="example">
<p class="section-item-desc">18px/28px</p>
<p class="big">By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.</p>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"big"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></pre>
</div>
<div class="example">
<p class="section-item-desc">14px/20px</p>
<p class="small">By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.</p>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"small"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></pre>
</div>
<div class="example">
<p class="section-item-desc">12px/20px</p>
<p class="smaller">By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.</p>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"smaller"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></pre>
</div>
<h3 class="section-head" id="h-columns"><a href="#h-columns">Columns</a></h3>
<p>Kube has three classes of <code>.columns-2</code> through <code>.columns-4</code> to create a multi-column layout. All multi-column layouts will be in a single column on mobile.</p>
<div class="example">
<p class="section-item-desc">2 columns</p>
<div class="columns-2">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"columns-2"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<div class="example">
<p class="section-item-desc">3 columns</p>
<div class="columns-3">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"columns-3"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<div class="example">
<p class="section-item-desc">4 columns</p>
<div class="columns-4">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"columns-4"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-quotes"><a href="#h-quotes">Quotes</a></h3>
<p>Quotes in the text stand out for contrast and added variety to the text. In the quotes you can mark text as a paragraph tag and without it.</p>
<div class="example">
<blockquote>
<p>No, she'll probably make me do it. Goodbye, friends. I never thought I'd die like this. But I always really hoped. I saw you with those two "ladies of the evening" at Elzars. Explain that. I never loved you.</p>
</blockquote>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">blockquote</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">blockquote</span>&gt;</span></pre>
</div>
<p>Use <code>small</code> tag for attribution. It's a prefer way for semantic code.</p>
<div class="example">
<blockquote>
<p>Who's brave enough to fly into something we all keep calling a death sphere? Yes. You gave me a dollar and some candy. I just want to talk. It has nothing to do with mating. Fry, that doesn't make sense.</p><small>— Bender</small>
</blockquote>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">blockquote</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Quotation content<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">small</span>&gt;</span>Author attribution<span class="hljs-tag">&lt;/<span class="hljs-name">small</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">blockquote</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-pre-formatted"><a href="#h-pre-formatted">Pre-formatted</a></h3>
<p>Pre-formatted text most often used to display code snippets or other text elements, for which you wish to preserve the exact formatting they've got.</p>
<div class="example">
<pre>Function.prototype.inherits = function(parent)
{
for (var key in parent.prototype)
{
this.prototype[key] = parent.prototype[key];
}
};
</pre>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span></pre>
</div>
<p>You feel free to use <code>code</code> tag inside <code>pre</code>.</p>
<div class="example">
<pre class="demo-pre"><code>Function.prototype.inherits = function(parent)
{
for (var key in parent.prototype)
{
this.prototype[key] = parent.prototype[key];
}
};
</code></pre>
<pre class="code">&lt;pre&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">code</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span></span></pre>
</div>
<h3 class="section-head" id="h-inline-elements"><a href="#h-inline-elements">Inline Elements</a></h3>
<p>Kube features various inline formatting elements. They all have their own semantic meaning, but you're free to use them just for their style.</p>
<table>
<thead>
<tr>
<th>Example</th>
<th>Tag</th>
<th>Example</th>
<th>Tag</th>
</tr>
</thead>
<tbody>
<tr>
<td><abbr title="Cascading Style Sheets">CSS</abbr></td>
<td class="col-6"><code>&lt;abbr&gt;</code></td>
<td><cite>Cite</cite></td>
<td class="col-6"><code>&lt;cite&gt;</code></td>
</tr>
<tr>
<td><code>Code</code></td>
<td><code>&lt;code&gt;</code></td>
<td><samp>Sample</samp></td>
<td><code>&lt;samp&gt;</code></td>
</tr>
<tr>
<td><var>Variable</var></td>
<td><code>&lt;var&gt;</code></td>
<td><mark>Mark</mark></td>
<td><code>&lt;mark&gt;</code></td>
</tr>
<tr>
<td><kbd>Shortcut</kbd></td>
<td><code>&lt;kbd&gt;</code></td>
<td>
<del>Deleted</del>
</td>
<td><code>&lt;del&gt;</code></td>
</tr>
<tr>
<td><i>Italic</i></td>
<td><code>&lt;i&gt;</code></td>
<td><em>Emphasis</em></td>
<td><code>&lt;em&gt;</code></td>
</tr>
<tr>
<td><strong>Highlighted</strong></td>
<td><code>&lt;strong&gt;</code></td>
<td><b>Bold</b></td>
<td><code>&lt;b&gt;</code></td>
</tr>
<tr>
<td>x<sup>superscript</sup></td>
<td><code>&lt;sup&gt;</code></td>
<td>x<sub>subscript</sub></td>
<td><code>&lt;sub&gt;</code></td>
</tr>
<tr>
<td><small>Small</small></td>
<td><code>&lt;small&gt;</code></td>
<td>
<ins>Inserted</ins>
</td>
<td><code>&lt;ins&gt;</code></td>
</tr>
</tbody>
</table>
<h3 class="section-head" id="h-modifiers"><a href="#h-modifiers">Modifiers</a></h3>
<p>Modifiers - a set of helper classes for creating accents in the text and for the solution of useful tasks without writing CSS code, for example, the alignment of the text in the center.</p>
<p>Modifiers can be applied to any tags as inline elements, links or block tags.</p>
<table>
<thead>
<tr>
<th>Example</th>
<th>Modifier</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="muted">Muted</span></td>
<td class="col-12"><code>.muted</code></td>
</tr>
<tr>
<td>
<a class="muted" href="#">Muted link</a>
</td>
<td><code>.muted</code></td>
</tr>
<tr>
<td>
<a class="black" href="#">Black link</a>
</td>
<td><code>.black</code></td>
</tr>
<tr>
<td><span class="highlight">Highlight</span></td>
<td><code>.highlight</code></td>
</tr>
<tr>
<td><span class="upper">upper</span></td>
<td><code>.upper</code></td>
</tr>
<tr>
<td><span class="lower">LOWER</span></td>
<td><code>.lower</code></td>
</tr>
<tr>
<td><span class="italic">Italic</span></td>
<td><code>.italic</code></td>
</tr>
<tr>
<td><span class="strong">Strong</span></td>
<td><code>.strong</code></td>
</tr>
<tr>
<td><strong class="normal">Not strong</strong></td>
<td><code>.normal</code></td>
</tr>
<tr>
<td><span class="monospace">Monospace</span></td>
<td><code>.monospace</code></td>
</tr>
<tr>
<td><span class="nowrap">Nowrap</span></td>
<td><code>.nowrap</code></td>
</tr>
<tr>
<td class="nowrap">Remove margin bottom</td>
<td><code>.end</code></td>
</tr>
<tr>
<td><span class="highlight">Highlight</span></td>
<td><code>.highlight</code></td>
</tr>
<tr>
<td><span class="small">Small</span></td>
<td><code>.small</code></td>
</tr>
<tr>
<td><span class="smaller">Smaller</span></td>
<td><code>.smaller</code></td>
</tr>
<tr>
<td><span class="large">Large</span></td>
<td><code>.large</code></td>
</tr>
<tr>
<td><span class="big">Big</span></td>
<td><code>.big</code></td>
</tr>
<tr>
<td class="text-left">Text left</td>
<td><code>.text-left</code></td>
</tr>
<tr>
<td class="text-center">Text center</td>
<td><code>.text-center</code></td>
</tr>
<tr>
<td class="text-right">Text right</td>
<td><code>.text-right</code></td>
</tr>
</tbody>
</table>
<h3 class="section-head" id="h-figure"><a href="#h-figure">Figure</a></h3>
<p>A figure tag features an image, a video or a code plus a caption. It is a good accessibility practice. It also helps serve responsive video to various devices when you wrap video into <code>.video-container</code> class.</p>
<h5>Images</h5>
<figure>
<img alt="Image" height="533" src="/img/favicons/logo-384x384.png" width="800">
<figcaption>
Lorem ipsum dolor sit amet, consectetur adipisicing elit...
</figcaption>
</figure>
<p class="end"><var>HTML</var></p>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">figure</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"image.jpg"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">figcaption</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">figcaption</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">figure</span>&gt;</span>
</pre>
<h5>Video</h5>
<figure>
<div class="video-container">
<iframe allowfullscreen frameborder="0" height="315" src="https://www.youtube.com/embed/nywsA8wCCfY" width="560"></iframe>
</div>
<figcaption>
Journey Through The Ice | National Geographic
</figcaption>
</figure>
<p class="end"><var>HTML</var></p>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">figure</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"video-container"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">iframe</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">iframe</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">figcaption</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">figcaption</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">figure</span>&gt;</span>
</pre>
<h5>Code</h5>
<figure>
<pre>Function.prototype.inherits = function(parent)
{
for (var key in parent.prototype)
{
this.prototype[key] = parent.prototype[key];
}
};
</pre>
<figcaption>
One of the implementations of inheritance
</figcaption>
</figure>
<p class="end"><var>HTML</var></p>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">figure</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">figcaption</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">figcaption</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">figure</span>&gt;</span>
</pre>
<h3 class="section-head" id="h-lists"><a href="#h-lists">Lists</a></h3>
<p>Although you most likely will not ever need to do so, you can still nest as many list levels as you like.</p>
<div class="row gutters">
<div class="col col-6">
<div class="example">
<ul>
<li>list item 1</li>
<li>list item 2
<ul>
<li>list item 2.1</li>
<li>list item 2.2
<ul>
<li>list item 2.2.1</li>
<li>list item 2.2.2</li>
</ul>
</li>
<li>list item 2.3</li>
<li>list item 2.4</li>
</ul>
</li>
<li>list item 3</li>
<li>list item 4</li>
</ul>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</pre>
</div>
</div>
<div class="col col-6">
<div class="example">
<ol>
<li>list item 1</li>
<li>list item 2
<ol>
<li>list item 2.1</li>
<li>list item 2.2
<ol>
<li>list item 2.2.1</li>
<li>list item 2.2.2</li>
</ol>
</li>
<li>list item 2.3</li>
<li>list item 2.4</li>
</ol>
</li>
<li>list item 3</li>
<li>list item 4</li>
</ol>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">ol</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ol</span>&gt;</span>
</pre>
</div>
</div>
</div>
<h5>Unstyled List</h5>
<p>To remove default list styling, use <code>.unstyled</code>.</p>
<div class="example">
<ul class="unstyled">
<li>list item 1</li>
<li>list item 2
<ul>
<li>list item 2.1</li>
<li>list item 2.2</li>
</ul>
</li>
<li>list item 3</li>
<li>list item 4</li>
</ul>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"unstyled"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</pre>
</div>
<h5>Definition List</h5>
<p>From time to time, you may need to produce a list of definitions, and there's one nicely built-in into Kube. We love semantic things. And lists. We love lists.</p>
<div class="example">
<dl>
<dt>Term 1</dt>
<dd>Description 1</dd>
<dt>Term 2</dt>
<dd>Description 2</dd>
<dt>Term 3</dt>
<dd>Description 3</dd>
</dl>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">dl</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dt</span>&gt;</span>Term<span class="hljs-tag">&lt;/<span class="hljs-name">dt</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dd</span>&gt;</span>Description<span class="hljs-tag">&lt;/<span class="hljs-name">dd</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dl</span>&gt;</span>
</pre>
</div>
@@ -0,0 +1,85 @@
+++
date = "2017-03-02T21:56:55+01:00"
title = "Welcome to Kube"
tags = ["markdown","example"]
categories = ["general"]
draft = false
description = "This article is just a demo post and shows you the style of common used elements writing in pure markdown without HTML code."
weight = 10
+++
# Welcome to Kube an open source documentation like theme for Hugo
Hi there and welcome to kube - my two theme for the static site generator [hugo](https://gohugo.io/). kube is open source and can be found on [kube](https://kube.elemnts.org/). This article is just a demo post and shows you the style of common used elements.
Bear claw danish chocolate lollipop soufflé jelly. Apple pie chocolate cake
jelly-o icing bonbon. Gingerbread pastry fruitcake muffin chocolate bar
cheesecake. Sugar plum bonbon bonbon lemon drops gummies.
## Inline 🦄 Text Styles [a link](http://kube.elemnts.org)
Chocolate tiramisu pastry [a link](http://zutrinken.com) cotton candy sesame snaps. Dessert cake chocolate bar **a bold part** sugar plum bonbon 🐓💨 marshmallow lollipop toffee soufflé. Donut caramels chocolate bar. Oat cake cookie <mark>a marked part</mark> cheesecake donut. Jelly-o `<some> $code` marzipan cake. Bonbon sesame snaps chocolate _an italic part_ oat cake pudding sweet roll caramels bonbon. Soufflé muffin 👻 gummies sugar plum dessert bonbon bear claw. Sweet ice cream jujubes. Marzipan sugar plum pastry chocolate <kbd>⌘</kbd>+<kbd>A</kbd> bar fruitcake. Lollipop lollipop brownie.
## Ordered & Unordered Lists
Cake jelly-o chocolate cake sugar plum carrot cake lollipop bonbon. Jelly beans pudding oat cake pie.
* Jelly beans pudding oat cake pie.
* Cupcake cupcake oat cake candy lemon
* Drops marzipan icing. Dessert topping croissant fruitcake sesame snaps cotton candy sweet danish
* Sweet roll sweet sugar plum donut
* Bear claw gingerbread cake donut chocolate bar
* Topping cake fruitcake fruitcake
* Ice cream icing chupa chups cupcake jelly-o candy
* Croissant jujubes topping tart soufflé pudding
* Cheesecake caramels icing
* Cake jelly-o chocolate cake sugar plum carrot cake lollipop bonbon
Ice cream icing chupa chups cupcake jelly-o candy. Croissant jujubes topping tart soufflé pudding. Cheesecake caramels icing.
1. Drops marzipan icing. Dessert topping croissant fruitcake sesame snaps cotton candy sweet danish
* Sweet roll sweet sugar plum donut
* Bear claw gingerbread cake donut chocolate bar
* Topping cake fruitcake fruitcake
3. Ice cream icing chupa chups cupcake jelly-o candy
Liquorice marshmallow sweet macaroon. Cotton candy pastry ice cream fruitcake tiramisu jelly beans dragée.
<dl><dt>Ice cream</dt><dd>icing chupa chups cupcake jelly-o candy. Croissant jujubes topping tart soufflé pudding</dd><dt>Cake</dt><dd>Jelly beans pudding oat cake pie</dd><dt>Drops marzipan icing</dt><dd>Cake jelly-o chocolate cake sugar plum carrot cake lollipop</dd></dl>
Soufflé tart topping gummi bears jujubes lollipop ice cream pudding. Apple pie jelly-o powder powder sweet.
Cake soufflé icing gingerbread topping jujubes. Chocolate cake pudding sweet biscuit cake. Soufflé tart topping gummi bears jujubes lollipop ice cream pudding. Apple pie jelly-o powder powder sweet. Halvah chocolate bar cotton candy sugar plum cake.
## Tables, Blockquotes and Codeblocks
Apple pie chocolate cake jelly-o icing bonbon. Gingerbread pastry fruitcake muffin chocolate bar cheesecake. Sugar plum bonbon bonbon lemon drops gummies.
| RGB | WMYN |
|---|---|
| Red | Cyan |
| Green | Magenta |
| Yellow | Black |
Brownie oat cake tart caramels croissant lollipop pastry soufflé lemon drops. Cotton candy pastry ice cream fruitcake tiramisu jelly beans dragée.
> Jelly beans dessert toffee caramels brownie ice cream croissant chupa chups liquorice. Danish sweet roll croissant. Powder sugar plum powder danish wafer cake.
>
> Candy jelly beans jujubes muffin. Bear claw danish chocolate lollipop soufflé jelly.
Cake soufflé icing gingerbread topping jujubes. Chocolate cake pudding sweet biscuit cake. Soufflé tart topping gummi bears jujubes lollipop ice cream pudding.
Apple pie jelly-o powder powder sweet. Halvah chocolate bar cotton candy sugar plum cake. Liquorice marshmallow sweet macaroon.
<blockquote>
<p>For example.</p>
</blockquote>
Macaroon jelly toffee cheesecake muffin lollipop dragée cake gummies. Cotton candy biscuit cupcake. Cupcake chupa chups carrot cake. Chocolate bar donut gummies wafer pastry sesame snaps oat cake.
* * *
Apple pie chocolate cake jelly-o icing bonbon. Gingerbread pastry fruitcake muffin chocolate bar cheesecake. Sugar plum bonbon bonbon lemon drops gummies. Brownie oat cake tart caramels croissant lollipop pastry soufflé lemon drops. Jelly beans dessert toffee caramels brownie ice cream croissant chupa chups liquorice. Danish sweet roll croissant. Powder sugar plum powder danish wafer cake. Candy jelly beans jujubes muffin. Bear claw danish chocolate lollipop soufflé jelly.
@@ -0,0 +1,4 @@
+++
title = "Company"
description = "We create apps and websites since 2009. We aim for minimalism and efficiency in everything we do. Our products are simple yet beautiful. They help you focus on your goals, not on your tools."
+++
@@ -0,0 +1,163 @@
+++
description = "Add some motion, shaking, pulsing, sliding and more"
title = "Animation"
date = "2017-04-10T16:43:08+01:00"
draft = false
weight = 200
bref="Although it is quite easy to overuse animation effects, Kube makes it pretty easy to create meaningful, smooth and overall nice looking animation. Feel free to click every button below to see what it does, and then only use those effects that are essential to your project"
toc = true
script = 'animation'
+++
<h3 class="section-head" id="h-slide"><a href="#h-slide">Slide</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div id="animation-box-slide-up">
slideUp
</div>
</div>
<div class="demo-animation-box">
<div class="hide" id="animation-box-slide-down">
slideDown
</div>
</div>
</div><a class="demo-animation-btn" data-back="slideDown" data-el="#animation-box-slide-up" data-to="slideUp" href="#" id="slide-up-btn">Slide Up</a> <a class="demo-animation-btn" data-back="slideUp" data-el="#animation-box-slide-down" data-to="slideDown" href="#" id="slide-down-btn">Slide Down</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'slideUp'</span>);
<span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'slideDown'</span>);</pre>
</div>
<h3 class="section-head" id="h-fade"><a href="#h-fade">Fade</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div class="hide" id="animation-box-fade-in">
fadeIn
</div>
</div>
<div class="demo-animation-box">
<div id="animation-box-fade-out">
fadeOut
</div>
</div>
</div><a class="demo-animation-btn" data-back="fadeOut" data-el="#animation-box-fade-in" data-to="fadeIn" href="#" id="fade-in-btn">Fade In</a> <a class="demo-animation-btn" data-back="fadeIn" data-el="#animation-box-fade-out" data-to="fadeOut" href="#" id="fade-out-btn">Fade Out</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'fadeIn'</span>);
<span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'fadeOut'</span>);</pre>
</div>
<h3 class="section-head" id="h-flip"><a href="#h-flip">Flip</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div class="hide" id="animation-box-flip-in">
flipIn
</div>
</div>
<div class="demo-animation-box">
<div id="animation-box-flip-out">
flipOut
</div>
</div>
</div><a class="demo-animation-btn" data-back="flipOut" data-el="#animation-box-flip-in" data-to="flipIn" href="#" id="flip-in-btn">Flip In</a> <a class="demo-animation-btn" data-back="flipIn" data-el="#animation-box-flip-out" data-to="flipOut" href="#" id="flip-out-btn">Flip Out</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'flipIn'</span>);
<span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'flipOut'</span>);</pre>
</div>
<h3 class="section-head" id="h-zoom"><a href="#h-zoom">Zoom</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div class="hide" id="animation-box-zoom-in">
zoomIn
</div>
</div>
<div class="demo-animation-box">
<div id="animation-box-zoom-out">
zoomOut
</div>
</div>
</div><a class="demo-animation-btn" data-back="zoomOut" data-el="#animation-box-zoom-in" data-to="zoomIn" href="#" id="zoom-in-btn">Zoom In</a> <a class="demo-animation-btn" data-back="zoomIn" data-el="#animation-box-zoom-out" data-to="zoomOut" href="#" id="zoom-out-btn">Zoom Out</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'zoomIn'</span>);
<span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'zoomOut'</span>);</pre>
</div>
<h3 class="section-head" id="h-rotate"><a href="#h-rotate">Rotate</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div id="animation-box-rotate">
rotate
</div>
</div>
</div><a class="demo-animation-btn" href="#" id="rotate-btn">Rotate</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'rotate'</span>);</pre>
</div>
<h3 class="section-head" id="h-shake"><a href="#h-shake">Shake</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div id="animation-box-shake">
shake
</div>
</div>
</div><a class="demo-animation-btn" href="#" id="shake-btn">Shake</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'shake'</span>);</pre>
</div>
<h3 class="section-head" id="h-pulse"><a href="#h-pulse">Pulse</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div id="animation-box-pulse">
pulse
</div>
</div>
</div><a class="demo-animation-btn" href="#" id="pulse-btn">Pulse</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'pulse'</span>);</pre>
</div>
<h3 class="section-head" id="h-slide-in"><a href="#h-slide-in">Slide In</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div class="hide" id="animation-box-slide-in-right">
slideInRight
</div>
</div>
<div class="demo-animation-box">
<div class="hide" id="animation-box-slide-in-left">
slideInLeft
</div>
</div>
<div class="demo-animation-box">
<div class="hide" id="animation-box-slide-in-down">
slideInDown
</div>
</div>
</div><a class="demo-animation-btn" data-back="slideOutRight" data-el="#animation-box-slide-in-right" data-to="slideInRight" href="#" id="slide-in-right-btn">Slide In Right</a> <a class="demo-animation-btn" data-back="slideOutLeft" data-el="#animation-box-slide-in-left" data-to="slideInLeft" href="#" id="slide-in-left-btn">Slide In Left</a> <a class="demo-animation-btn" data-back="slideOutUp" data-el="#animation-box-slide-in-down" data-to="slideInDown" href="#" id="slide-in-down-btn">Slide In Down</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'slideInRight'</span>);
<span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'slideInLeft'</span>);
<span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'slideInDown'</span>);</pre>
</div>
<h3 class="section-head" id="h-slide-out"><a href="#h-slide-out">Slide Out</a></h3>
<div class="example">
<div class="demo-animation-wrap">
<div class="demo-animation-box">
<div id="animation-box-slide-out-right">
slideOutRight
</div>
</div>
<div class="demo-animation-box">
<div id="animation-box-slide-out-left">
slideOutLeft
</div>
</div>
<div class="demo-animation-box">
<div id="animation-box-slide-out-up">
slideOutUp
</div>
</div>
</div><a class="demo-animation-btn" data-back="slideInRight" data-el="#animation-box-slide-out-right" data-to="slideOutRight" href="#" id="slide-out-right-btn">Slide Out Right</a> <a class="demo-animation-btn" data-back="slideInLeft" data-el="#animation-box-slide-out-left" data-to="slideOutLeft" href="#" id="slide-out-left-btn">Slide Out Left</a> <a class="demo-animation-btn" data-back="slideInDown" data-el="#animation-box-slide-out-up" data-to="slideOutUp" href="#" id="slide-out-up-btn">Slide Out Up</a>
<pre class="code"><span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'slideOutRight'</span>);
<span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'slideOutLeft'</span>);
<span class="hljs-variable">$(</span><span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'slideOutUp'</span>);</pre>
</div>
<h3 class="section-head" id="h-callback"><a href="#h-callback">Callback</a></h3>
<pre class="code">$(<span class="hljs-string">'#element'</span>).animation(<span class="hljs-string">'fadeIn'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// code ...</span>
});</pre>
@@ -0,0 +1,99 @@
+++
date = "2017-04-10T16:41:54+01:00"
weight = 110
description = "Traces for the users so they won't get lost"
title = "Breadcrumbs"
draft = false
bref= "Breadcrumbs in Kube are formed as lists with default separator. This separator can be customized with ease by simply changing a single CSS line"
toc = true
+++
<h3 class="section-head" id="h-base"><a href="#h-base">Base</a></h3>
<div class="example">
<nav class="breadcrumbs">
<ul>
<li>
<a href="#">Home</a>
</li>
<li>
<a href="#">Shop</a>
</li>
<li>
<a href="#">Catalog</a>
</li>
<li>
<a href="#">T-Shirts</a>
</li>
<li><span>Brand</span></li>
</ul>
</nav>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"breadcrumbs"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-centered"><a href="#h-centered">Centered</a></h3>
<div class="example">
<nav class="breadcrumbs push-center">
<ul>
<li>
<a href="#">Home</a>
</li>
<li>
<a href="#">Shop</a>
</li>
<li>
<a href="#">Catalog</a>
</li>
<li>
<a href="#">T-Shirts</a>
</li>
<li class="active">
<a href="">Brand</a>
</li>
</ul>
</nav>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"breadcrumbs push-center"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"active"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-custom-separator"><a href="#h-custom-separator">Custom Separator</a></h3>
<div class="example">
<nav class="breadcrumbs" id="breadcrumbs-custom-separator">
<ul>
<li>
<a href="#">Home</a>
</li>
<li>
<a href="#">Shop</a>
</li>
<li>
<a href="#">Catalog</a>
</li>
<li>
<a href="#">T-Shirts</a>
</li>
<li><span>Brand</span></li>
</ul>
</nav>
<pre class="code skip"><span class="hljs-comment">// css</span>
<span class="hljs-meta">#breadcrumbs-custom-separator li:after {</span>
<span class="hljs-symbol"> content:</span> <span class="hljs-string">'&gt;'</span>;
}
<span class="hljs-comment">// html</span>
<span class="hljs-params">&lt;nav id="breadcrumbs-custom-separator" class="breadcrumbs"&gt;</span>
<span class="hljs-params">&lt;ul&gt;</span>
<span class="hljs-params">&lt;li&gt;</span><span class="hljs-params">&lt;a href=""&gt;</span>...<span class="hljs-params">&lt;/a&gt;</span><span class="hljs-params">&lt;/li&gt;</span>
<span class="hljs-params">&lt;li&gt;</span><span class="hljs-params">&lt;span&gt;</span>...<span class="hljs-params">&lt;/span&gt;</span><span class="hljs-params">&lt;/li&gt;</span>
<span class="hljs-params">&lt;/ul&gt;</span>
<span class="hljs-params">&lt;/nav&gt;</span>
</pre>
</div>
@@ -0,0 +1,108 @@
+++
date = "2017-04-10T16:41:16+01:00"
weight = 70
description = "Full variety of pressible, clickable and pushable buttons"
title = "Buttons"
draft = false
bref = "Buttons in Kube are minimalistic, designed for instant and convenient customization, and are ready to be pushed, pressed, clicked and manipulated in whichever ways. A lot of interactive components use buttons, and you should too!"
toc = true
+++
<h3 class="section-head" id="h-primary"><a href="#h-primary">Primary</a></h3>
<div class="example">
<button class="button">Button</button> <a class="button" href="#">Button</a>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></pre>
</div>
<h3 class="section-head" id="h-secondary"><a href="#h-secondary">Secondary</a></h3>
<div class="example">
<button class="button secondary">Button</button> <a class="button secondary" href="#">Button</a>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></pre>
</div>
<h3 class="section-head" id="h-outline"><a href="#h-outline">Outline</a></h3>
<p>Outline class does exactly what it is supposed to do: styles a button with an outline with no fill color.</p>
<div class="example">
<button class="button outline">Button</button> <button class="button secondary outline">Button</button>
<pre class="code">&lt;<span class="hljs-keyword">button</span> class=<span class="hljs-string">"button outline"</span>&gt;<span class="hljs-keyword">Button</span>&lt;/<span class="hljs-keyword">button</span>&gt;
&lt;<span class="hljs-keyword">button</span> class=<span class="hljs-string">"button secondary outline"</span>&gt;<span class="hljs-keyword">Button</span>&lt;/<span class="hljs-keyword">button</span>&gt;</pre>
</div>
<h3 class="section-head" id="h-disabled"><a href="#h-disabled">Disabled</a></h3>
<p>Disabled buttons are automatically styles with muted colors, inactive and not clickable. As you can see, there's no need to set disabled class for the button element, and disabled argument is enough. Having this said, both a link and a button input require disabled class.</p>
<div class="example">
<a class="button disabled" href="#" role="button">Link</a> <button class="button secondary" disabled>Button</button> <button class="button outline" disabled>Button</button> <button class="button secondary outline" disabled>Button</button>
</div>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button disabled"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary"</span> <span class="hljs-attr">disabled</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
<h3 class="section-head" id="h-small"><a href="#h-small">Small</a></h3>
<p>Buttons come in all sizes and shapes.</p>
<div class="example">
<a class="button small" href="#" role="button">Link</a> <button class="button secondary small">Button</button>
</div>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button small"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary small"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
<h3 class="section-head" id="h-big"><a href="#h-big">Big</a></h3>
<div class="example">
<a class="button big" href="#" role="button">Link</a> <button class="button secondary big">Button</button>
</div>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button big"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary big"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
<h3 class="section-head" id="h-large"><a href="#h-large">Large</a></h3>
<div class="example">
<a class="button large" href="#" role="button">Link</a> <button class="button secondary large">Button</button>
</div>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button large"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary large"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
<h3 class="section-head" id="h-upper"><a href="#h-upper">Upper</a></h3>
<div class="example">
<a class="button upper" href="#" role="button">Link</a> <button class="button secondary upper">Button</button> <a class="button upper outline" href="#" role="button">Link</a> <button class="button secondary upper outline">Button</button>
</div>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button upper"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary upper"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button upper outline"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary upper outline"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
<h3 class="section-head" id="h-round"><a href="#h-round">Round</a></h3>
<div class="example">
<a class="button round" href="#" role="button">Link</a> <button class="button secondary round">Button</button> <a class="button round outline" href="#" role="button">Link</a> <button class="button secondary round outline">Button</button>
</div>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button round"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary round"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button round outline"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary round outline"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
<h3 class="section-head" id="h-inverted"><a href="#h-inverted">Inverted</a></h3>
<p>For use on darker backgrounds, you can just introduce inverted class to have your button flip its color to the opposite one.</p>
<div class="example bg-darkgray">
<a class="button inverted" href="#" role="button">Link</a> &nbsp; <button class="button inverted outline">Button</button> &nbsp;
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button inverted"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>&gt;</span>Link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button inverted outline"</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
</div>
<h3 class="section-head" id="h-width"><a href="#h-width">Width</a></h3>
<div class="example">
<p><button class="button w100">100%</button></p>
<p><button class="button secondary w50">50%</button></p>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button w100"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary w50"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
</div>
<h3 class="section-head" id="h-icons"><a href="#h-icons">Icons</a></h3>
<div class="example">
<button class="button"><i class="kube-calendar"></i></button> <button class="button secondary"><i class="kube-calendar"></i> Change</button> <button class="button outline"><i class="kube-search"></i></button> <button class="button secondary outline"><i class="kube-search"></i> Search</button>
<pre class="code"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"kube-calendar"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"kube-calendar"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> Change<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button outline"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"kube-search"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary outline"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"kube-search"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> Search<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></pre>
</div>
<h3 class="section-head" id="h-custom"><a href="#h-custom">Custom</a></h3>
<p>With some Sass magic, you can customize your buttons in a snap. Just include a color class declaration and set the color itself, and you're done.</p>
<div class="example">
<button class="button red">Button</button> <button class="button red outline">Button</button>
<pre class="code"><span class="hljs-comment">// scss</span>
.button.red {
<span class="hljs-comment">// $text-color, $back-color</span>
@include <span class="hljs-keyword">button</span>(<span class="hljs-meta">#fff, #ff3366);</span>
}
<span class="hljs-comment">// html</span>
&lt;<span class="hljs-keyword">button</span> class=<span class="hljs-string">"button red"</span>&gt;<span class="hljs-keyword">Button</span>&lt;/<span class="hljs-keyword">button</span>&gt;
&lt;<span class="hljs-keyword">button</span> class=<span class="hljs-string">"button red outline"</span>&gt;<span class="hljs-keyword">Button</span>&lt;/<span class="hljs-keyword">button</span>&gt;</pre>
</div>
@@ -0,0 +1,207 @@
+++
date = "2017-04-10T16:42:50+01:00"
draft = false
weight = 180
description = "Smoothly and reliably collapse elements for extra convenience"
title = "Collapse"
bref="Collapsable elements are horizontally aligned tabs, in a way. Jokes aside, collapsable elements are useful and easy to setup, both for direct purpose of switching between content while collapsing everything else, and for navigation use cases"
toc = true
+++
<h3 class="section-head" id="h-base"><a href="#h-base">Base</a></h3>
<div class="example">
<div class="my-collapse" data-component="collapse" id="my-collapse">
<h4><a class="collapse-toggle" href="#collapse-box-1">Item 1</a></h4>
<div class="collapse-box hide" id="collapse-box-1">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<h4><a class="collapse-toggle" href="#collapse-box-2">Item 2</a></h4>
<div class="collapse-box" id="collapse-box-2">
<p>I look active on load.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<h4><a class="collapse-toggle" href="#collapse-box-3">Item 3</a></h4>
<div class="collapse-box hide" id="collapse-box-3">
<h6>Important Heading</h6>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-collapse"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"collapse"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-1"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-1"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-2"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-2"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-3"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-3"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-navigation-example"><a href="#h-navigation-example">Navigation Example</a></h3>
<p>Here you can see a list of items forming a navigation menu, with a nested list which acts as a collapsable element</p>
<div class="example">
<ul id="demo-nav-collapse">
<li>
<a href="#">Installation</a>
</li>
<li>
<a href="#">Configuration</a>
</li>
<li>
<a href="#">Adding Content</a>
</li>
<li>
<a href="#">Templates</a>
</li>
<li data-component="collapse">
<a class="collapse-toggle" href="#languages-box-2">Languages <span class="caret down"></span></a>
<ul class="collapse-box" id="languages-box-2">
<li>
<a href="#">Setup</a>
</li>
<li>
<a href="#">Translating content</a>
</li>
<li>
<a href="#">Language variables</a>
</li>
<li>
<a href="#">Supporting RTL</a>
</li>
</ul>
</li>
<li>
<a href="#">Settings</a>
</li>
<li>
<a href="#">Callbacks</a>
</li>
<li>
<a href="#">API</a>
</li>
</ul>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"collapse"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#toggle-box"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>
Toggle
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"caret down"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"toggle-box"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-settings"><a href="#h-settings">Settings</a></h3>
<p>Settings are pretty straightforward: you can toggle, denote active element, turn animation on and off, and more.</p>
<h5>toggle</h5>
<ul>
<li>Type: <var>boolean</var></li>
<li>Default: <var>true</var></li>
</ul>
<h5>active</h5>
<ul>
<li>Type: <var>string or boolean</var></li>
<li>Default: <var>false</var></li>
</ul>
<h5>toggleClass</h5>
<ul>
<li>Type: <var>string</var></li>
<li>Default: <var>'collapse-toggle'</var></li>
</ul>
<p>Sets a class of a collapsable object.</p>
<h5>boxClass</h5>
<ul>
<li>Type: <var>string</var></li>
<li>Default: <var>'collapse-box'</var></li>
</ul>
<p>Sets a class for collapsable object's content</p>
<h5>animation</h5>
<ul>
<li>Type: <var>boolean</var></li>
<li>Default: <var>true</var></li>
</ul>
<p>Turns animation on and off.</p>
<h3 class="section-head" id="h-callbacks"><a href="#h-callbacks">Callbacks</a></h3>
<h5>open</h5>
<pre class="code skip">$(<span class="hljs-string">'#my-collapse'</span>).on(<span class="hljs-string">'open.collapse'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</pre>
<h5>opened</h5>
<pre class="code skip">$(<span class="hljs-string">'#my-collapse'</span>).on(<span class="hljs-string">'opened.collapse'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</pre>
<h5>close</h5>
<pre class="code skip">$(<span class="hljs-string">'#my-collapse'</span>).on(<span class="hljs-string">'close.collapse'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</pre>
<h5>closed</h5>
<pre class="code skip">$(<span class="hljs-string">'#my-collapse'</span>).on(<span class="hljs-string">'closed.collapse'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</pre>
<h3 class="section-head" id="h-api"><a href="#h-api">API</a></h3>
<p>We love APIs, and for interactive elements such as collapsable elements we offer ways to programmatically open and close individual elements, or all at once.</p>
<div class="example">
<p><button class="button outline" onclick="$('#my-collapse-api').collapse('open', '#box-2');">Open</button> <button class="button outline" onclick="$('#my-collapse-api').collapse('close', '#box-2');">Close</button> <button class="button outline" onclick="$('#my-collapse-api').collapse('openAll');">Open All</button> <button class="button outline" onclick="$('#my-collapse-api').collapse('closeAll');">Close All</button></p><br>
<div class="my-collapse" data-component="collapse" id="my-collapse-api">
<h4><a class="collapse-toggle" href="#box-1">Item 1</a></h4>
<div class="collapse-box hide" id="box-1">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<h4><a class="collapse-toggle" href="#box-2">Item 2</a></h4>
<div class="collapse-box hide" id="box-2">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<h4><a class="collapse-toggle" href="#box-3">Item 3</a></h4>
<div class="collapse-box hide" id="box-3">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"$('#my-collapse-api').collapse('open', '#box-2');"</span>&gt;</span>Open<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"$('#my-collapse-api').collapse('close', '#box-2');"</span>&gt;</span>Close<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"$('#my-collapse-api').collapse('openAll');"</span>&gt;</span>Open All<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"$('#my-collapse-api').collapse('closeAll');"</span>&gt;</span>Close All<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-collapse-api"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"collapse"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-1"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-1"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-2"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-2"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#box-3"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-toggle"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse-box hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box-3"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<h5>open</h5>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-collapse'</span>).collapse(<span class="hljs-string">'open'</span>);
</pre>
<h5>close</h5>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-collapse'</span>).collapse(<span class="hljs-string">'close'</span>);
</pre>
<h5>openAll</h5>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-collapse'</span>).collapse(<span class="hljs-string">'openAll'</span>);
</pre>
<h5>closeAll</h5>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-collapse'</span>).collapse(<span class="hljs-string">'closeAll'</span>);
</pre>
@@ -0,0 +1,141 @@
+++
date = "2017-04-10T16:43:14+01:00"
draft = false
weight = 210
description = "The basic set of colors"
title = "Colors"
bref="Kube has a basic set of colors for text, links, buttons, states and gray palette. These colors help to create uniformity and harmony in the look of UI elements. All colors are carefully selected and combined with each other. Of course, you can change the color scheme to your choice in the framework settings."
toc = true
+++
<h3 class="section-head">Text</h3>
<p>Contrasting black color for headings and less intense dark gray for the text helps to improve readability.</p>
<div class="example">
<div class="swatch-box">
<div class="swatch-item">
<span class="swatch swatch-bg-headings"></span>
<h5>Headings</h5>
<p>$color-headings</p>
</div>
<div class="swatch-item">
<span class="swatch swatch-bg-text"></span>
<h5>Text</h5>
<p>$color-text</p>
</div>
</div>
</div>
<h3 class="section-head" id="h-links"><a href="#h-links">Links</a></h3>
<p>Classic blue links and soft red for the hover state makes links visible and predictable.</p>
<div class="example">
<div class="swatch-box">
<div class="swatch-item">
<span class="swatch swatch-bg-link"></span>
<h5>Link</h5>
<p>$color-link</p>
</div>
<div class="swatch-item">
<span class="swatch swatch-bg-link-hover"></span>
<h5>Hover</h5>
<p>$color-link-hover</p>
</div>
</div>
</div>
<h3 class="section-head" id="h-buttons"><a href="#h-buttons">Buttons</a></h3>
<p>Blue color for primary buttons for greater consistency with links. Black color for secondary buttons allows you build a variety of UI.</p>
<div class="example">
<div class="swatch-box">
<div class="swatch-item">
<span class="swatch swatch-bg-button-primary"></span>
<h5>Primary</h5>
<p>$color-button-primary</p>
</div>
<div class="swatch-item">
<span class="swatch swatch-bg-button-secondary"></span>
<h5>Secondary</h5>
<p>$color-button-secondary</p>
</div>
</div>
</div>
<h3 class="section-head" id="h-states"><a href="#h-states">States</a></h3>
<p>All possible states of the UI are in the simple and intuitive color scheme helps to focus the user's attention when creating an interactive UI.</p>
<div class="example">
<div class="swatch-box">
<div class="swatch-item">
<span class="swatch bg-error"></span>
<h5>Error</h5>
<p>$color-error</p>
</div>
<div class="swatch-item">
<span class="swatch bg-focus"></span>
<h5>Focus</h5>
<p>$color-focus</p>
</div>
<div class="swatch-item">
<span class="swatch bg-success"></span>
<h5>Success</h5>
<p>$color-success</p>
</div>
<div class="swatch-item">
<span class="swatch bg-warning"></span>
<h5>Warning</h5>
<p>$color-warning</p>
</div>
</div>
</div>
<h3 class="section-head" id="h-extra"><a href="#h-extra">Extra</a></h3>
<p>Special color to highlight areas of interaction with the interface. And the white color for all cases.</p>
<div class="example">
<div class="swatch-box">
<div class="swatch-item">
<span class="swatch bg-highlight"></span>
<h5>Highlight</h5>
<p>$color-highlight</p>
</div>
<div class="swatch-item">
<span class="swatch swatch-bg-inverted"></span>
<h5>Inverted</h5>
<p>$color-inverted</p>
</div>
</div>
</div>
<h3 class="section-head" id="h-grayscale"><a href="#h-grayscale">Grayscale</a></h3>
<p>Harmonious and well-thought-out scheme of gray for a broad range of tasks in the designing of the interface from controls to backgrounds.</p>
<div class="example">
<div class="swatch-box">
<div class="swatch-item">
<span class="swatch bg-black"></span>
<h5>Black</h5>
<p>$color-black</p>
</div>
<div class="swatch-item">
<span class="swatch bg-darkgray"></span>
<h5>Darkgray</h5>
<p>$color-darkgray</p>
</div>
<div class="swatch-item">
<span class="swatch bg-midgray"></span>
<h5>Midgray</h5>
<p>$color-midgray</p>
</div>
<div class="swatch-item">
<span class="swatch bg-gray"></span>
<h5>Gray</h5>
<p>$color-gray</p>
</div>
<div class="swatch-item">
<span class="swatch bg-lightgray"></span>
<h5>Lightgray</h5>
<p>$color-lightgray</p>
</div>
<div class="swatch-item">
<span class="swatch bg-silver"></span>
<h5>Silver</h5>
<p>$color-silver</p>
</div>
<div class="swatch-item">
<span class="swatch bg-aluminum"></span>
<h5>Aluminum</h5>
<p>$color-aluminum</p>
</div>
</div>
</div>
@@ -0,0 +1,96 @@
+++
title = "Custom Plugins"
description = "Flexible and extensible way to add custom features"
weight = 20
draft = false
toc = true
bref = "Kube has a lot to offer in terms of extensibility and flexibility, and plugins are the way of doing incredible things without bloating the core. With plugins, you can extend existing features, make them more interactive, or you can crate completely new functionality."
+++
<h3 class="section-head" id="h-plugin"><a href="#h-plugin">Plugin Template</a></h3>
<p>Here's what a generic plugin looks like. This template gives an overall idea of what you can do with plugins in Kube. Feel free to use this one as a boilerplate for your custom plugins.</p>
<pre class="code skip">(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Kube</span>)
</span>{
Kube.Myplugin = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">element, options</span>)
</span>{
<span class="hljs-keyword">this</span>.namespace = <span class="hljs-string">'myplugin'</span>;
<span class="hljs-comment">// default settings</span>
<span class="hljs-keyword">this</span>.defaults = {
mysetting: <span class="hljs-literal">true</span>
};
<span class="hljs-comment">// Parent Constructor</span>
Kube.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
<span class="hljs-comment">// Initialization</span>
<span class="hljs-keyword">this</span>.start();
};
<span class="hljs-comment">// Functionality</span>
Kube.Myplugin.prototype = {
start: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// plugin element</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.$element);
<span class="hljs-comment">// call options</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.opts.mysetting);
<span class="hljs-comment">// call methods</span>
<span class="hljs-keyword">this</span>.method();
},
method: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
<span class="hljs-comment">// callback</span>
<span class="hljs-keyword">this</span>.callback(<span class="hljs-string">'show'</span>);
<span class="hljs-comment">// callback with arguments</span>
<span class="hljs-keyword">this</span>.callback(<span class="hljs-string">'show'</span>, value1, value2);
}
};
<span class="hljs-comment">// Inheritance</span>
Kube.Myplugin.inherits(Kube);
<span class="hljs-comment">// Plugin</span>
Kube.Plugin.create(<span class="hljs-string">'Myplugin'</span>);
Kube.Plugin.autoload(<span class="hljs-string">'Myplugin'</span>);
}(Kube));
</pre>
<h3 class="section-head" id="h-call"><a href="#h-call">Call</a></h3>
<p>Calling a plugin is very easy, just add the <code>data-component</code> with the name of your plugin and it will start automatic.</p>
<pre class="code">&lt;<span class="hljs-keyword">div</span> data-component=<span class="hljs-string">"myplugin"</span>&gt;&lt;/<span class="hljs-keyword">div</span>&gt;</pre>
<p>Or call manually</p>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-element"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
$(<span class="hljs-string">'#my-element'</span>).myplugin();
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</pre>
<h3 class="section-head" id="h-callbacks"><a href="#h-callbacks">Callbacks</a></h3>
<p>Kube plugins can react on events with callbacks. Whenever you need your plugin to do something in response to an action or an event, just use a callback.</p>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myplugin"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"myplugin"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
$(<span class="hljs-string">'#myplugin'</span>).on(<span class="hljs-string">'show.myplugin'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</pre>
<p>All plugin methods and variables are available within the plugin via <var>this</var>:</p>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
$(<span class="hljs-string">'#myplugin'</span>).on(<span class="hljs-string">'show.myplugin'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// plugin element</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.$element);
<span class="hljs-comment">// call plugin method</span>
<span class="hljs-keyword">this</span>.method();
});
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</pre>
@@ -0,0 +1,172 @@
+++
date = "2017-04-10T16:42:12+01:00"
draft = false
weight = 140
description = "Popular and adjustable menu and navigation option"
title = "Dropdown"
bref= "Dropdown menus in Kube are simple and intuitive. You've got a link with <code>data-component='dropdown'</code> and a <code>div</code> with some kind of HTML content. Clicking outside of the dropdown or hitting <kbd>Esc</kbd> closes dropdown"
toc = true
+++
<h3 class="section-head" id="h-demo"><a href="#h-demo">Demo</a></h3>
<div class="example">
<p><a data-component="dropdown" data-loaded="true" data-target="#dropdown1" href="#">Show Dropdown <span class="caret down"></span></a></p>
<div class="dropdown hide" id="dropdown1">
<a class="close show-sm" href=""></a>
<ul>
<li>
<a href="">Item 1</a>
</li>
<li>
<a href="">Item 2</a>
</li>
<li class="active">
<a href="">Item 3</a>
</li>
<li>
<a href="">Item 4</a>
</li>
<li>
<a href=""><span class="label primary">Item 5</span></a>
</li>
<li>
<a href=""><span class="label error">Item 6</span></a>
</li>
</ul>
</div>
<pre class="code skip">// Toggle
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"dropdown"</span> <span class="hljs-attr">data-target</span>=<span class="hljs-string">"#my-dropdown"</span>&gt;</span>Show <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"caret down"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
// Dropdown
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-dropdown"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"close show-sm"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<div class="example">
<p><button class="button outline" data-component="dropdown" data-loaded="true" data-target="#dropdown2">Show Dropdown <span class="caret down"></span></button></p>
<div class="dropdown hide" id="dropdown2">
<div style="padding: 24px;">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><a data-action="dropdown-close" href="#">Close</a>
</div>
</div>
<pre class="code skip">// Toggle
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"dropdown"</span> <span class="hljs-attr">data-target</span>=<span class="hljs-string">"#my-dropdown"</span>&gt;</span>Show Dropdown <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"caret down"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
// Dropdown
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-dropdown"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">data-action</span>=<span class="hljs-string">"dropdown-close"</span>&gt;</span>Close<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<h3 class="section-head">Navigation Fixed</h3>
<p>Scroll down a bit to make a fixed navigation bar appear at the top of the page, and then try out "Account" dropdown.</p>
<div class="example">
<div data-component="sticky" data-loaded="true" id="navbar-demo">
<div id="navbar-brand">
<a href=""><img alt="Brand" src="/img/kube/brand.png"></a>
</div>
<nav id="navbar-main">
<ul>
<li>
<a href="#">Shop</a>
</li>
<li>
<a href="#">News</a>
</li>
<li>
<a href="#">Contact</a>
</li>
<li>
<a href="#">Blog</a>
</li>
<li>
<a data-component="dropdown" data-loaded="true" data-target="#dropdown-fixed" href="">Account <span class="caret down"></span></a>
</li>
</ul>
</nav>
</div>
<div class="dropdown hide" id="dropdown-fixed">
<ul>
<li>
<a href="">Billing</a>
</li>
<li>
<a href="">Log Out</a>
</li>
</ul>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"navbar-demo"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"sticky"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"dropdown"</span> <span class="hljs-attr">data-target</span>=<span class="hljs-string">"#dropdown-fixed"</span>&gt;</span>
Account
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"caret down"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
// Dropdown
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown hide"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"dropdown-fixed"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">""</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-settings"><a href="#h-settings">Settings</a></h3>
<h5>target</h5>
<ul>
<li>Type: <var>string</var></li>
<li>Default: <var>null</var></li>
</ul>
<p>Sets an ID of a target dropdown layer.</p>
<h5>height</h5>
<ul>
<li>Type: <var>int</var></li>
<li>Default: <var>false</var></li>
</ul>
<p>Sets dropdown height.</p>
<h5>width</h5>
<ul>
<li>Type: <var>int</var></li>
<li>Default: <var>false</var></li>
</ul>
<p>Sets dropdown width.</p>
<h5>animation</h5>
<ul>
<li>Type: <var>boolean</var></li>
<li>Default: <var>true</var></li>
</ul>
<p>Turns opening and closing animation on and off.</p>
<h3 class="section-head" id="h-callbacks"><a href="#h-callbacks">Callbacks</a></h3>
<h5>open</h5>
<pre class="code">$(<span class="hljs-string">'#my-dropdown'</span>).on(<span class="hljs-string">'open.dropdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});</pre>
<h5>opened</h5>
<pre class="code">$(<span class="hljs-string">'#my-dropdown'</span>).on(<span class="hljs-string">'opened.dropdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});</pre>
<h5>close</h5>
<pre class="code">$(<span class="hljs-string">'#my-dropdown'</span>).on(<span class="hljs-string">'close.dropdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});</pre>
<h5>closed</h5>
<pre class="code">$(<span class="hljs-string">'#my-dropdown'</span>).on(<span class="hljs-string">'closed.dropdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something...</span>
});</pre>
@@ -0,0 +1,800 @@
+++
date = "2017-04-10T16:40:50+01:00"
title = "Forms"
draft = false
weight = 60
description = "Rows and columns for all sorts of tables"
bref = 'Forms come in all forms and shapes in Kube, and you can do all sorts of things with them, especially when combining with <a href="/docs/custom-plugins/">custom plugins</a> for extra interactivity. These forms are ideal building material for your awesome projects!'
toc = true
+++
<h3 class="section-head" id="h-base"><a href="#h-base">Base</a></h3>
<p>This is the most basic form with all the basic inputs.</p>
<div class="example">
<form action="" autocomplete="off" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad"> <input id="fake_user_name" name="fake_user[name]" style="position:absolute; top:-10000px;" type="text" value="Safari Autofill Me">
<div class="form-item">
<label>Email</label> <input class="w50" name="email" type="email">
</div>
<div class="form-item">
<label>Country</label> <select>
<option value="">
---
</option>
</select>
</div>
<div class="form-item">
<label class="checkbox"><input type="checkbox"> Check me</label> <label class="checkbox"><input type="radio"> Radio me</label>
</div>
<div class="form-item">
<textarea rows="6"></textarea>
</div>
<div class="form-item form-buttons">
<button>Log in</button> <button class="button secondary outline">Cancel</button>
</div>
</form>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Email<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w50"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Country<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span>&gt;</span>---<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"checkbox"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>&gt;</span> Check me<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"checkbox"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span>&gt;</span> Radio me<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"6"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Log in<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button secondary outline"</span>&gt;</span>Cancel<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-inputs"><a href="#h-inputs">Inputs</a></h3>
<p>Here's a standard input field with type set as text. Label serves as input's label, and the following div with class desc serves as an optional description.</p>
<div class="example">
<form class="form">
<div class="form-item">
<label>City</label> <input type="text">
<div class="desc">
This information helps us deliver orders on time.
</div>
</div>
</form>
<pre class="code skip">&lt;form <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>City<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<p>Here are two text input fields, one with a placeholder and another one disabled, both set to be 6 grid columns wide.</p>
<div class="example">
<form class="form">
<div class="row gutters">
<div class="col col-6">
<div class="form-item">
<input placeholder="Email" type="text">
</div>
</div>
<div class="col col-6">
<div class="form-item">
<input disabled="true" type="text" value="Disabled">
</div>
</div>
</div>
</form>
<pre class="code skip">&lt;form <span class="hljs-built_in">class</span>=<span class="hljs-string">"form"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row gutters"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"form-item"</span>&gt;
&lt;input type=<span class="hljs-string">"text"</span> placeholder=<span class="hljs-string">"Email"</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"form-item"</span>&gt;
&lt;input type=<span class="hljs-string">"text"</span> disabled=<span class="hljs-string">"true"</span> value=<span class="hljs-string">"Disabled"</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/form&gt;
</pre>
</div>
<p>Here's how you denote required fields with req class, and add descriptions to labels using span with class desc.</p>
<div class="example">
<form class="form">
<div class="row gutters">
<div class="col col-6">
<div class="form-item">
<label>City <span class="req">*</span></label> <input type="text">
</div>
</div>
<div class="col col-6">
<div class="form-item">
<label>City <span class="desc">Just curious.</span></label> <input type="text">
<div class="desc">
This information helps us deliver orders on time.
</div>
</div>
</div>
</div>
</form>
<pre class="code skip">&lt;form <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row gutters"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-6"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>City <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"req"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-6"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>City <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</span></pre>
</div>
<h3 class="section-head" id="h-search"><a href="#h-search">Search</a></h3>
<div class="example">
<form class="form">
<div class="form-item">
<input class="search" type="text">
</div>
</form>
<pre class="code skip">&lt;form <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-item"</span>&gt;
&lt;input <span class="hljs-class"><span class="hljs-keyword">type</span></span>=<span class="hljs-string">"text"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"search"</span>&gt;
&lt;/div&gt;
&lt;/form&gt;
</pre>
</div>
<h3 class="section-head" id="h-checkboxes"><a href="#h-checkboxes">Checkboxes &amp; Radio</a></h3>
<p>Kube features full variety of stylish checkboxes and radio buttons. You can feature them on your pages by defining input type as checkbox or radio. There's also a neat option to place checkboxes inline by adding <code>form-checkboxes</code> class to the container (works for both checkboxes and radio buttons)</p>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item form-checkboxes">
<label class="checkbox"><input type="checkbox"> Check 1</label> <label class="checkbox"><input type="checkbox"> Check 2</label> <label class="checkbox"><input type="checkbox"> Check 3</label> <label class="checkbox"><input type="checkbox"> Check 4</label>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item form-checkboxes"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"checkbox"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>&gt;</span> Check 1<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
...
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label class="checkbox"><input type="checkbox"> Check 1</label> <label class="checkbox"><input type="checkbox"> Check 2</label> <label class="checkbox"><input type="checkbox"> Check 3</label> <label class="checkbox"><input type="checkbox"> Check 4</label>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"checkbox"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>&gt;</span> Check 1<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
...
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item form-checkboxes">
<label class="checkbox"><input name="check" type="radio"> Check 1</label> <label class="checkbox"><input name="check" type="radio"> Check 2</label> <label class="checkbox"><input name="check" type="radio"> Check 3</label> <label class="checkbox"><input name="check" type="radio"> Check 4</label>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item form-checkboxes"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"checkbox"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span>&gt;</span> Check 1<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
...
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label class="checkbox"><input name="check" type="radio"> Check 1</label> <label class="checkbox"><input name="check" type="radio"> Check 2</label> <label class="checkbox"><input name="check" type="radio"> Check 3</label> <label class="checkbox"><input name="check" type="radio"> Check 4</label>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"checkbox"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span>&gt;</span> Check 1<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
...
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<h3 class="section-head" id="h-fieldset"><a href="#h-fieldset">Fieldset</a></h3>
<p>Fieldsets in Kube are nicely pre-formatted and ready to go. Just wrap your form in a fieldset tag and you're good to go.</p>
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<fieldset>
<legend>Login data</legend>
<div class="form-item">
<label>Email</label> <input class="w50" name="user-email" type="email">
</div>
<div class="form-item">
<label>Password</label> <input class="w50" name="user-password" type="password">
</div>
</fieldset>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">fieldset</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">legend</span>&gt;</span>Login data<span class="hljs-tag">&lt;/<span class="hljs-name">legend</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Email<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"user-email"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w50"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Password<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"user-password"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w50"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">fieldset</span>&gt;</span>
</pre>
<fieldset>
<legend>About</legend>
<div class="form-item">
<textarea name="user-about" rows="5"></textarea>
</div>
<div class="form-item">
<button>Submit</button>
</div>
</fieldset>
</form>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">fieldset</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">legend</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">legend</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"user-about"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"5"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">fieldset</span>&gt;</span>
</pre>
<h3 class="section-head" id="h-small"><a href="#h-small">Small</a></h3>
<p>Simple class <code>.small</code> makes your selects and fields, well, smaller.</p>
<div class="example">
<form class="form">
<div class="form-item">
<input class="small" placeholder="Title" type="text">
</div>
<div class="form-item">
<select class="small">
<option>
Choose me
</option>
</select>
</div>
</form>
<pre class="code skip">&lt;form <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"small"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Title"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"small"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">option</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<h3 class="section-head" id="h-big"><a href="#h-big">Big</a></h3>
<p>Simple class <code>.big</code> makes your selects and fields, well, bigger.</p>
<div class="example">
<form class="form">
<div class="form-item">
<input class="big" placeholder="Title" type="text">
</div>
<div class="form-item">
<select class="big">
<option>
Choose me
</option>
</select>
</div>
</form>
<pre class="code skip">&lt;form <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"big"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Title"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"big"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">option</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<h3 class="section-head" id="h-width"><a href="#h-width">Width</a></h3>
<p>Following framework-wide rules, it is very easy to manipulate form fields sizes. Just use <code>w50</code> class to make a field 50% wide or <code>w25</code> to a 25% wide.</p>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<input class="w25" type="text" value=".w25">
</div>
<div class="form-item">
<input class="w50" type="text" value=".w50">
</div>
<div class="form-item">
<input class="w75" type="text" value=".w75">
</div>
<div class="form-item">
<input type="text" value="100% by default">
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-item"</span>&gt;
&lt;input <span class="hljs-class"><span class="hljs-keyword">type</span></span>=<span class="hljs-string">"text"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"w25"</span>&gt;
&lt;/div&gt;
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-item"</span>&gt;
&lt;input <span class="hljs-class"><span class="hljs-keyword">type</span></span>=<span class="hljs-string">"text"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"w50"</span>&gt;
&lt;/div&gt;
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-item"</span>&gt;
&lt;input <span class="hljs-class"><span class="hljs-keyword">type</span></span>=<span class="hljs-string">"text"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"w75"</span>&gt;
&lt;/div&gt;
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-item"</span>&gt;
&lt;input <span class="hljs-class"><span class="hljs-keyword">type</span></span>=<span class="hljs-string">"text"</span> value=<span class="hljs-string">"100% by default"</span>&gt;
&lt;/div&gt;
&lt;/form&gt;
</pre>
</div>
<h3 class="section-head" id="h-states"><a href="#h-states">States</a></h3>
<p>By default, Kube features two different states: success and failure.</p>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Your height <span class="success">Looks like a valid value</span></label> <input class="success" type="text">
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Your height <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"success"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"success"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Enter your weight <span class="error">No negative numbers, please</span></label> <input class="error" type="text">
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Enter your weight <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"error"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"error"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<h3 class="section-head" id="h-required"><a href="#h-required">Required</a></h3>
<p>Along with making a field actually required, you can add a visual clue for the users using a span with req class.</p>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Email <span class="req">*</span></label> <input name="user-email" type="email">
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Email <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"req"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"user-email"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<h3 class="section-head" id="h-descriptions"><a href="#h-descriptions">Descriptions</a></h3>
<p>Descriptions are simple: as long as form's element has desc class, Kube will treat it as a description.</p>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Name <span class="desc">Always nice to feel important.</span></label> <input name="user-name" type="text">
</div>
<div class="form-item">
<label>Email</label> <input name="user-email" type="email">
<div class="desc">
Please enter your email.
</div>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Name <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"user-name"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Email<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"user-email"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</span></pre>
</div>
<h3 class="section-head" id="h-disabled"><a href="#h-disabled">Disabled</a></h3>
<p>Not only text inputs can be disabled, but checkboxes and radio buttons as well. Just add <code>disabled</code> attribute or <code>.disabled</code> class to the input.</p>
<div class="example">
<p><input disabled type="text" value="Text"></p>
<p><input class="disabled" type="checkbox"></p>
<p><input disabled type="radio"></p>
<p>
<textarea disabled>Text</textarea></p>
<p><select disabled>
<option>
Item
</option>
</select></p>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> <span class="hljs-attr">disabled</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"disabled"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">disabled</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">disabled</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">disabled</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">option</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-append"><a href="#h-append">Append &amp; Prepend</a></h3>
<p>You can prepend or append certain elements within your input fields, such as currency characters.</p>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>How much is it?</label>
<div class="prepend w50">
<span>$</span> <input type="text">
</div>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>How much is it?<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"prepend w50"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>$<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>It is much how?</label>
<div class="append">
<input type="text"><span>$</span>
</div>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>It is much how?<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"append"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>$<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<h3 class="section-head" id="h-append-button"><a href="#h-append-button">Button Append</a></h3>
<p>Appending works for buttons as well. Here you can see a button that has been appended and included withing a text input field.</p>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Label</label>
<div class="append w50">
<input name="search" placeholder="Search" type="text"> <button class="button outline">Go</button>
</div>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Label<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"append w50"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"search"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Search"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button outline"</span>&gt;</span>Go<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<h3 class="section-head" id="h-more-examples"><a href="#h-more-examples">More Examples</a></h3>
<p>The examples below are quite self explanatory and they cover multiple selections, selecting dates, filling in phone numbers, a ready feedback form template and more. Feel free to use any of these examples as templates for your sites.</p>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Select multiple</label> <select class="w50" multiple="multiple" size="10">
<optgroup label="Group 1">
<option value="1">
Some text goes here
</option>
<option value="2">
Another choice could be here
</option>
<option value="3">
Yet another item to be chosen
</option>
</optgroup>
<optgroup label="Group 2">
<option value="4">
Some text goes here
</option>
<option value="5">
Another choice could be here
</option>
<option value="6">
Yet another item to be chosen
</option>
</optgroup>
<optgroup label="Group 3">
<option value="7">
Some text goes here
</option>
<option value="8">
Another choice could be here
</option>
<option value="9">
Yet another item to be chosen
</option>
</optgroup>
</select>
</div>
</form>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Select multiple<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w50"</span> <span class="hljs-attr">multiple</span>=<span class="hljs-string">"multiple"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"10"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">optgroup</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"Group 1"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">optgroup</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad"> <label>Choose date</label>
<div class="row gutters">
<div class="col col-3">
<div class="form-item">
<select>
<option>
---
</option>
</select>
<div class="desc">
Month
</div>
</div>
</div>
<div class="col col-3">
<div class="form-item">
<select>
<option>
---
</option>
</select>
<div class="desc">
Day
</div>
</div>
</div>
<div class="col col-6">
<div class="form-item">
<select>
<option>
---
</option>
</select>
<div class="desc">
Year
</div>
</div>
</div>
</div>
</form>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Choose date<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row gutters"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-3"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">option</span>&gt;</span>---<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>Month<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-3"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">option</span>&gt;</span>---<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>Day<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-6"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">option</span>&gt;</span>---<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>Year<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</pre>
</div>
<div class="example">
<form action="" class="form form-inline" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Phone number</label> ( <input class="small" name="phone-prefix" size="3" type="text"> ) <input class="small w50" name="phone-number" type="text"> &nbsp;ext: <input class="small" name="phone-ext" size="3" type="text">
<div class="desc">
Needed if there are questions about your order
</div>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form form-inline"</span>&gt;
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-item"</span>&gt;
&lt;label&gt;<span class="hljs-type">Phone</span> number&lt;/label&gt;
( &lt;input <span class="hljs-class"><span class="hljs-keyword">type</span></span>=<span class="hljs-string">"text"</span> name=<span class="hljs-string">"phone-prefix"</span> size=<span class="hljs-string">"3"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"small"</span>&gt; )
&lt;input <span class="hljs-class"><span class="hljs-keyword">type</span></span>=<span class="hljs-string">"text"</span> name=<span class="hljs-string">"phone-number"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"small w50"</span>&gt;
&amp;nbsp;ext: &lt;input <span class="hljs-class"><span class="hljs-keyword">type</span></span>=<span class="hljs-string">"text"</span> name=<span class="hljs-string">"phone-ext"</span> size=<span class="hljs-string">"3"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"small"</span>&gt;
&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"desc"</span>&gt;...&lt;/div&gt;
&lt;/div&gt;
&lt;/form&gt;
</pre>
</div>
<div class="example">
<form class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="row gutters">
<div class="col col-6">
<div class="form-item">
<label>Email</label> <input type="email">
</div>
</div>
<div class="col col-6">
<div class="form-item">
<label>Topic</label> <select>
<option value="">
Questions
</option>
</select>
</div>
</div>
</div>
<div class="form-item">
<label>Message</label>
<textarea rows="6"></textarea>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row gutters"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-6"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Email<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-6"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Topic<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Message<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"6"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="row gutters">
<div class="col col-6">
<div class="form-item">
<label>Country</label> <select>
<option>
---
</option>
</select>
<div class="desc">
Where are you from?
</div>
</div>
</div>
<div class="col col-6">
<div class="form-item">
<label><br></label> <button>Submit</button>
</div>
</div>
</div>
</form>
<pre class="code skip">&lt;form method=<span class="hljs-string">"post"</span> action=<span class="hljs-string">""</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form"</span>&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row gutters"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-6"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Country<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">option</span>&gt;</span>---<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"desc"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-6"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Text</label>
<textarea rows="4"></textarea>
</div>
</form>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Text<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</pre>
</div>
<div class="example">
<form action="" class="form" method="post">
<input name="authorize-token" type="hidden" value="c6851d805bd96d2c91d52574c65d3ae26ce4b6bca43f560518a0bea61335f9d52acc6055807bf8616ff3d13d3882d5aa2f4b15a046562c1e6a9d932e369e9fad">
<div class="form-item">
<label>Text</label>
<textarea class="w50" rows="4"></textarea>
</div>
</form>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Text<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"4"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</pre>
</div>
@@ -0,0 +1,588 @@
+++
draft = false
weight = 30
description = "Flexible, fully responsive and ready to use"
title = "Grid"
bref = "Kube uses fully responsive, flexbox-enabled 12-column grid. You can combine or divide columns, nest them, center them horizontally or vertically, and do all sorts of things. Here are a few examples of what you can do with Kube's grid."
toc = true
+++
<div id="main">
<h3 class="section-head" id="h-columns"><a href="#h-columns">Columns</a></h3>
<p>Columns are building blocks for many websites. Here's how columns are formed in Kube, and here's how you can use them right away.</p>
<div class="example demo-grid">
<div class="row">
<div class="col col-1">
1
</div>
<div class="col col-11">
11
</div>
</div>
<div class="row">
<div class="col col-2">
2
</div>
<div class="col col-10">
10
</div>
</div>
<div class="row">
<div class="col col-3">
3
</div>
<div class="col col-9">
9
</div>
</div>
<div class="row">
<div class="col col-4">
4
</div>
<div class="col col-8">
8
</div>
</div>
<div class="row">
<div class="col col-5">
5
</div>
<div class="col col-7">
7
</div>
</div>
<div class="row">
<div class="col col-6">
6
</div>
<div class="col col-6">
6
</div>
</div>
<div class="row">
<div class="col col-7">
7
</div>
<div class="col col-5">
5
</div>
</div>
<div class="row">
<div class="col col-8">
8
</div>
<div class="col col-4">
4
</div>
</div>
<div class="row">
<div class="col col-9">
9
</div>
<div class="col col-3">
3
</div>
</div>
<div class="row">
<div class="col col-10">
10
</div>
<div class="col col-2">
2
</div>
</div>
<div class="row">
<div class="col col-11">
11
</div>
<div class="col col-1">
1
</div>
</div>
<div class="row">
<div class="col col-12">
12
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-8"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-gutters"><a href="#h-gutters">Gutters</a></h3>
<div class="example demo-grid">
<div class="row gutters">
<div class="col col-3">
3
</div>
<div class="col col-9">
9
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row gutters"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-9"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-auto-width"><a href="#h-auto-width">Auto Width</a></h3>
<div class="example demo-grid">
<div class="row auto">
<div class="col">
auto
</div>
<div class="col">
auto
</div>
<div class="col">
auto
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row auto"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Auto + Gutters</h5>
<div class="example demo-grid">
<div class="row gutters auto">
<div class="col">
auto
</div>
<div class="col">
auto
</div>
<div class="col">
auto
</div>
<div class="col">
auto
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row gutters auto"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-bricks"><a href="#h-bricks">Bricks</a></h3>
<div class="example demo-grid">
<div class="row">
<div class="col col-6">
50%
</div>
<div class="col col-6">
50%
</div>
<div class="col col-6">
50%
</div>
<div class="col col-6">
50%
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Bricks + Gutters</h5>
<div class="example demo-grid">
<div class="row gutters">
<div class="col col-4">
33%
</div>
<div class="col col-4">
33%
</div>
<div class="col col-4">
33%
</div>
<div class="col col-4">
33%
</div>
<div class="col col-4">
33%
</div>
<div class="col col-4">
33%
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row gutters"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-offset"><a href="#h-offset">Offset</a></h3>
<p>Offsetting columns is very simple in Kube. Just use column's class as usual, for example, <code>col col-2</code> and then add the offset value <code>offset-4</code>. This will offset this column and all following columns by 4.</p>
<div class="example demo-grid">
<div class="row">
<div class="col col-2">
2
</div>
<div class="col col-6 offset-4">
6
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-2"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6 offset-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-nested"><a href="#h-nested">Nested</a></h3>
<p>Here's an example of nesting columns within columns. In this example, we have a single row, with two columns .col col-6, a div nested within the second column, with .row end class to denote where to inject nested columns, and the three nested columns.</p>
<div class="example demo-grid">
<div class="row">
<div class="col col-6">
6
</div>
<div class="col col-6 demo-col-nested">
<div class="row">
<div class="col col-4">
4
</div>
<div class="col col-4">
4
</div>
<div class="col col-4">
4
</div>
</div>
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-equal-height"><a href="#h-equal-height">Equal Height Columns</a></h3>
<p>Columns are equal height by default in Kube</p>
<div class="example demo-grid">
<div class="row">
<div class="col col-6">
1
</div>
<div class="col col-6">
1<br>
2<br>
3
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;
...
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;
...
...
...
&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-reordering"><a href="#h-reordering">Reordering</a></h3>
<h5>First</h5>
<div class="example demo-grid">
<div class="row">
<div class="col col-4">
4
</div>
<div class="col col-8 first">
8
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-8 first"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Last</h5>
<div class="example demo-grid">
<div class="row">
<div class="col col-3 last">
3
</div>
<div class="col col-9">
9
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3 last"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-9"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-around"><a href="#h-around">Around</a></h3>
<p>When you want your columns to be surrounded by an even margins on both sides, just use <code>.around</code> class.</p>
<div class="example demo-grid">
<div class="row around">
<div class="col col-3">
3
</div>
<div class="col col-3">
3
</div>
<div class="col col-3">
3
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row around"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-between"><a href="#h-between">Between</a></h3>
<p>Sometime you just need space between columns, and not around them. Well, there's a class for that: <code>.between</code></p>
<div class="example demo-grid">
<div class="row between">
<div class="col col-3">
3
</div>
<div class="col col-3">
3
</div>
<div class="col col-3">
3
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row between"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-alignment"><a href="#h-alignment">Alignment</a></h3>
<h5>Align Center</h5>
<div class="example demo-grid">
<div class="row align-center">
<div class="col col-6">
6
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row align-center"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Align Right</h5>
<div class="example demo-grid">
<div class="row align-right">
<div class="col col-3">
3
</div>
<div class="col col-3">
3
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row align-right"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-3"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Align Middle</h5>
<div class="example demo-grid">
<div class="row align-middle" style="height: 104px; border: 1px solid #eee;">
<div class="col col-4" style="height: 36px;">
4
</div>
<div class="col col-4" style="height: 56px;">
4
</div>
<div class="col col-4" style="height: 36px;">
4
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row align-middle"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-push"><a href="#h-push">Push</a></h3>
<h5>Push Center</h5>
<div class="example demo-grid">
<div class="row">
<div class="col col-4 push-center">
.push-center
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4 push-center"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Push Right</h5>
<div class="example demo-grid">
<div class="row">
<div class="col col-6">
...
</div>
<div class="col col-4 push-right">
.push-right
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-6"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-4 push-right"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Push Middle</h5>
<div class="example demo-grid">
<div class="row" style="height: 104px;">
<div class="col col-8 push-middle">
.push-middle
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-8 push-middle"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Push Mixed</h5>
<div class="example demo-grid">
<div class="row" style="height: 104px;">
<div class="col col-8 push-middle push-center">
.push-middle.push-center
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-8 push-middle push-center"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h5>Push Bottom</h5>
<div class="example demo-grid">
<div class="row" style="height: 104px;">
<div class="col col-8 push-bottom">
.push-bottom
</div>
</div>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"row"</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"col col-8 push-bottom"</span>&gt;...&lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
</div>
<h3 class="section-head" id="h-fixed-column"><a href="#h-fixed-column">Fixed Width Column</a></h3>
<p>Here's one more bit of magic. You can set a fixed width column and still have a responsive and flexible layout right beside this fixed width column.</p>
<div class="example demo-grid">
<div id="demo-container">
<div id="demo-sidebar">
sidebar
</div>
<div id="demo-content">
content
</div>
</div>
<pre class="code skip"><span class="hljs-comment">&lt;!-- scss --&gt;</span>
#container {
@include grid-row;
}
#sidebar {
@include flex-item-width(300px);
}
#content {
@include flex-item-auto;
}
<span class="hljs-comment">&lt;!-- html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"sidebar"</span>&gt;</span>Sidebar<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span>&gt;</span>Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<h3 class="section-head" id="h-media-grid"><a href="#h-media-grid">Media Grid</a></h3>
<p>Media grid is a great example of Kube's flexibility and versatility. Whenever you have some media to display, you can choose to use Media grid. This type of grid is ideal for featuring photos; it adds some visual music and slight randomness to your layout.</p>
<div class="example demo-grid">
<div id="demo-media-grid">
<div>
1
</div>
<div>
2
</div>
<div>
3
</div>
<div>
4
</div>
<div>
5
</div>
<div>
6
</div>
<div>
7
</div>
<div>
8
</div>
<div>
9
</div>
<div>
10
</div>
</div>
<pre class="code skip"><span class="hljs-comment">&lt;!-- scss --&gt;</span>
#media-grid {
@include grid-media-columns(2);
&amp; &gt; div {
margin-bottom: 20px;
height: 80px;
}
&amp; &gt; div:nth-child(2n) {
height: 200px;
}
&amp; &gt; div:nth-child(5n) {
height: 120px;
}
}
<span class="hljs-comment">&lt;!-- html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"media-grid"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>2<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>3<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>4<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>5<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>6<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>7<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>8<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>9<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>10<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
</div>
@@ -0,0 +1,51 @@
+++
date = "2017-04-10T16:40:43+01:00"
title = "Labels"
draft = false
weight = 80
description = "Label things with all sorts of labels"
bref = "Labels have all standard Kube styling options available: outline, states (success, error, warning), inverted color, and more. You can also customize labels to your requirements, and place them inside other elements, such as buttons, for example"
toc = true
+++
<h3 class="section-head" id="h-base"><a href="#h-base">Base</a></h3>
<div class="example">
<span class="label">Default</span> &nbsp; <span class="label success">Success</span> &nbsp; <span class="label error">Error</span> &nbsp; <span class="label warning">Warning</span> &nbsp; <span class="label focus">Focus</span> &nbsp; <span class="label black">Black</span> &nbsp; <span class="example-inverted-box"><span class="label inverted">Inverted</span></span>
</div>
<h3 class="section-head" id="h-outline"><a href="#h-outline">Outline</a></h3>
<div class="example">
<span class="label outline">Default</span> &nbsp; <span class="label success outline">Success</span> &nbsp; <span class="label error outline">Error</span> &nbsp; <span class="label warning outline">Warning</span> &nbsp; <span class="label focus outline">Focus</span> &nbsp; <span class="label black outline">Black</span> &nbsp; <span class="example-inverted-box"><span class="label inverted outline">Inverted</span></span>
</div>
<h3 class="section-head" id="h-upper"><a href="#h-upper">Upper</a></h3>
<div class="example">
<span class="label upper">Default</span> &nbsp; <span class="label success upper">Success</span> &nbsp; <span class="label error upper">Error</span> &nbsp; <span class="label warning upper">Warning</span> &nbsp; <span class="label focus upper">Focus</span> &nbsp; <span class="label black upper">Black</span> &nbsp; <span class="example-inverted-box"><span class="label inverted upper">Inverted</span></span>
</div>
<h3 class="section-head" id="h-tag"><a href="#h-tag">Tag</a></h3>
<div class="example">
<span class="label tag"><a href="#">Default</a></span> &nbsp; <span class="label tag success">Success</span> &nbsp; <span class="label tag error">Error</span> &nbsp; <span class="label tag warning">Warning</span> &nbsp; <span class="label tag focus"><a href="#">Focus</a></span> &nbsp; <span class="label tag black">Black</span> &nbsp; <span class="example-inverted-box"><span class="label tag inverted">Inverted</span></span>
</div>
<h3 class="section-head" id="h-badges"><a href="#h-badges">Badges</a></h3>
<p>Labels are ideal for use as badges with badge class.</p>
<div class="example">
<span class="label badge"><a href="#">1</a></span> <span class="label badge error">2</span> <span class="label badge success">3</span> <span class="label badge warning">4</span> <span class="label badge focus"><a href="#">5</a></span> <span class="label badge black">6</span> <span class="example-inverted-box"><span class="label badge inverted">7</span></span>
</div>
<h3 class="section-head" id="h-outline-badges"><a href="#h-outline-badges">Outline Badges</a></h3>
<div class="example">
<span class="label badge outline"><a href="#">1</a></span> <span class="label badge error outline">2</span> <span class="label badge success outline">3</span> <span class="label badge warning outline">4</span> <span class="label badge focus outline"><a href="#">5</a></span> <span class="label badge black outline">6</span> <span class="example-inverted-box"><span class="label badge inverted outline">7</span></span>
</div>
<h3 class="section-head" id="h-custom"><a href="#h-custom">Custom</a></h3>
<p>You can use mixins to customize your labels and badges.</p>
<div class="example">
<span class="label custom">Label</span> &nbsp; <span class="label badge custom">1</span> &nbsp; <span class="label tag custom">Tag</span>
<pre class="code skip"><span class="hljs-comment">&lt;!-- scss --&gt;</span>
.label.custom {
// $text-color, $back-color
@include label(#fff, #ea48a7);
}
<span class="hljs-comment">&lt;!-- html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"label custom"</span>&gt;</span>Label<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"label badge custom"</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"label tag custom"</span>&gt;</span>Tag<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
</pre>
</div>
@@ -0,0 +1,159 @@
+++
date = "2017-04-10T16:41:34+01:00"
draft = false
weight = 90
description = "Versatile and refined messages, ideal for daily use"
title = "Messages"
bref = "Messages are an essential part of modern web, and they can provide invaluable feedback to the users. Messages in Kube look nice, they are informative, simple and very easy to set up to whatever requirements you may have, style-wise or otherwise. Take a div, give it an message class, add a color using meaningful classes like error or success and you're practically done!"
toc = true
+++
<h3 class="section-head" id="h-usage"><a href="#h-usage">Usage</a></h3>
<div class="example">
<div class="message open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="#install">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message error open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message error"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message success open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message success"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message warning open" data-component="message" data-loaded="true">
<h5>Warning!</h5>You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code skip"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"message warning"</span> <span class="hljs-attr">data-component</span>=<span class="hljs-string">"message"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h5</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">h5</span>&gt;</span>
...
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"close small"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</pre>
</div>
<div class="example">
<div class="message focus open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message focus"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message black open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small white"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message black"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<div class="example">
<div class="message inverted open" data-component="message" data-loaded="true">
You have 2 modules waiting to installation. <a href="">Install</a> <span class="close small"></span>
</div>
<pre class="code">&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"message inverted"</span> data-component=<span class="hljs-string">"message"</span>&gt; ... &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"close small"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></pre>
</div>
<h3 class="section-head" id="h-options"><a href="#h-options">Options</a></h3>
<table>
<thead>
<tr>
<th class="w30">Name</th>
<th class="w30">Type</th>
<th class="w40">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>closeSelector</code></td>
<td><var>string</var></td>
<td>.close</td>
</tr>
<tr>
<td><code>closeEvent</code></td>
<td><var>string</var></td>
<td>click</td>
</tr>
<tr>
<td><code>animationOpen</code></td>
<td><var>string</var></td>
<td>fadeIn</td>
</tr>
<tr>
<td><code>animationClose</code></td>
<td><var>string</var></td>
<td>fadeOut</td>
</tr>
</tbody>
</table>
<h4>Set an option</h4>
<p>Via data attribute:</p>
<pre class="code skip">&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"message"</span> data-component=<span class="hljs-string">"message"</span> data-close-selector=<span class="hljs-string">".my-custom-close"</span>&gt;
... &lt;span <span class="hljs-built_in">class</span>=<span class="hljs-string">"my-custom-close small"</span>&gt;&lt;/span&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</pre>
<p>Via Javascript:</p>
<pre class="code skip"><span class="hljs-variable">$(</span><span class="hljs-string">'#my-message'</span>).message({
<span class="hljs-symbol">closeSelector:</span> <span class="hljs-string">'.my-custom-close'</span>
});
</pre>
<h3 class="section-head" id="h-methods"><a href="#h-methods">Methods</a></h3>
<p><button onclick="$('#message-1').message('open')">Open</button> <button onclick="$('#message-1').message('close')">Close</button></p>
<div class="message open" data-component="message" data-loaded="true" id="message-1">
You have 2 modules waiting to installation. <a href="#install">Install</a> <span class="close small"></span>
</div>
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>close</code></td>
<td>Manually closes a message.</td>
</tr>
<tr>
<td><code>open</code></td>
<td>Opens a message if it has been closed.</td>
</tr>
</tbody>
</table>
<h4>Example</h4>
<pre class="code">$(<span class="hljs-string">'#my-message'</span>).<span class="hljs-keyword">message</span>(<span class="hljs-string">'close'</span>);</pre>
<h3 class="section-head" id="h-callbacks"><a href="#h-callbacks">Callbacks</a></h3>
<table>
<thead>
<tr>
<th>Callback</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>open</code></td>
<td>This event fires immediately when the open instance method is called.</td>
</tr>
<tr>
<td><code>opened</code></td>
<td>This event is fired when the message has been opened, will wait for CSS animation to complete.</td>
</tr>
<tr>
<td><code>close</code></td>
<td>This event fires immediately when the close instance method is called.</td>
</tr>
<tr>
<td><code>closed</code></td>
<td>This event is fired when the message has been closed, will wait for CSS animation to complete.</td>
</tr>
</tbody>
</table>
<h4>Example</h4>
<pre class="code skip">$(<span class="hljs-string">'#my-message'</span>).on(<span class="hljs-string">'closed.message'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">// do something</span>
})
</pre>
@@ -0,0 +1,268 @@
+++
weight = 230
description = "Mixins save countless hours and bring results faster"
date = "2017-04-10T16:43:36+01:00"
title = "Mixins"
draft = false
bref="Mixins are a great way to produce things and effects way faster with Sass then with pure CSS. Kube has a lot to offer in this respect; feel free to use any of these mixins with any Kube components."
toc = true
+++
<h3 class="section-head" id="h-get-started"><a href="#h-get-started">Get Started</a></h3>
<p>Kube has been designed to help you with web development, that's why it's so easy to use Kube when building websites. To move forward quickly and efficiently, just link <code>kube.scss</code> from Kube package: this file contains variables, mixins and everything you need to simplify daily routine tasks.</p>
<p>For example, import <code>kube.scss</code> into your <code>master.scss</code> styles file, which you will later compile into <code>master.css</code></p>
<pre class="code skip"><span class="hljs-comment">// master.scss</span>
@<span class="hljs-keyword">import</span> <span class="hljs-string">"dist/scss/kube.scss"</span>;
</pre>
<p>Now all Kube's variables and mixins are readily available in <code>master.scss</code>, and you can use them whenever needed.</p>
<pre class="code skip"><span class="hljs-comment">// master.scss</span>
@<span class="hljs-keyword">import</span> <span class="hljs-string">"dist/scss/kube.scss"</span>;
<span class="hljs-comment">// use mixins</span>
<span class="hljs-selector-id">#my-layout</span> {
@<span class="hljs-keyword">include</span> flex;
}
<span class="hljs-comment">// use variables</span>
<span class="hljs-selector-id">#my-layout</span> {
<span class="hljs-attribute">padding</span>: <span class="hljs-variable">$base-line</span>;
}
</pre>
<h3 class="section-head" id="h-fonts"><a href="#h-fonts">Fonts</a></h3>
<p>Generates a font-family declarations for text, headings, buttons or inputs.</p>
<pre class="code skip"><span class="hljs-comment">// import Kube</span>
@<span class="hljs-keyword">import</span> <span class="hljs-string">"dist/scss/kube.scss"</span>;
<span class="hljs-comment">// use mixins</span>
@<span class="hljs-keyword">include</span> text-font(<span class="hljs-string">"Lato, 'Helvetica Neue', sans-serif"</span>);
@<span class="hljs-keyword">include</span> headings-font(<span class="hljs-string">"Lato, 'Helvetica Neue', sans-serif"</span>);
@<span class="hljs-keyword">include</span> buttons-font(<span class="hljs-string">"Lato, 'Helvetica Neue', sans-serif"</span>);
@<span class="hljs-keyword">include</span> inputs-font(<span class="hljs-string">"Lato, 'Helvetica Neue', sans-serif"</span>);
</pre>
<p>CSS Output</p>
<pre class="code skip"><span class="hljs-comment">// Text</span>
<span class="hljs-selector-tag">body</span> {
<span class="hljs-attribute">font-family</span>: Lato, <span class="hljs-string">'Helvetica Neue'</span>, sans-serif;
}
<span class="hljs-comment">// Headings</span>
<span class="hljs-selector-tag">h1</span><span class="hljs-selector-class">.title</span>, <span class="hljs-selector-tag">h1</span>, <span class="hljs-selector-tag">h2</span>, <span class="hljs-selector-tag">h3</span>, <span class="hljs-selector-tag">h4</span>, <span class="hljs-selector-tag">h5</span>, <span class="hljs-selector-tag">h6</span>, <span class="hljs-selector-class">.h1</span>, <span class="hljs-selector-class">.h2</span>, <span class="hljs-selector-class">.h3</span>, <span class="hljs-selector-class">.h4</span>, <span class="hljs-selector-class">.h5</span>, <span class="hljs-selector-class">.h6</span> {
<span class="hljs-attribute">font-family</span>: Lato, <span class="hljs-string">'Helvetica Neue'</span>, sans-serif;
}
<span class="hljs-comment">// Buttons</span>
<span class="hljs-selector-tag">button</span>, <span class="hljs-selector-class">.button</span> {
<span class="hljs-attribute">font-family</span>: Lato, <span class="hljs-string">'Helvetica Neue'</span>, sans-serif;
}
<span class="hljs-comment">// Inputs</span>
<span class="hljs-selector-tag">input</span>, <span class="hljs-selector-tag">textarea</span>, select {
<span class="hljs-attribute">font-family</span>: Lato, <span class="hljs-string">'Helvetica Neue'</span>, sans-serif;
}
</pre>
<h3 class="section-head" id="h-breakpoints"><a href="#h-breakpoints">Breakpoints</a></h3>
<p>Breakpoint for small screens (max-width 768px by default).</p>
<pre class="code skip">@<span class="hljs-keyword">include</span> breakpoint(sm) {
<span class="hljs-selector-class">.span</span> {
<span class="hljs-attribute">display</span>: none;
}
}
</pre>
<p>Breakpoint for medium screens (min-width 1024px by default).</p>
<pre class="code skip">@<span class="hljs-keyword">include</span> breakpoint(md) {
<span class="hljs-selector-class">.span</span> {
<span class="hljs-attribute">display</span>: none;
}
}
</pre>
<p>Breakpoint for large screens (min-width 1200px by default).</p>
<pre class="code skip">@<span class="hljs-keyword">include</span> breakpoint(lg) {
<span class="hljs-selector-class">.span</span> {
<span class="hljs-attribute">display</span>: none;
}
}
</pre>
<p>Custom breakpoints:</p>
<pre class="code skip"><span class="hljs-comment">// min-width 768px;</span>
<span class="hljs-variable">@include</span> breakpoint(<span class="hljs-number">768px</span>) {}
<span class="hljs-comment">// min-width 768px and max-width 1024px;</span>
<span class="hljs-variable">@include</span> breakpoint(<span class="hljs-number">768px</span>, <span class="hljs-number">1024px</span>) {}
<span class="hljs-comment">// max-width 1024px;</span>
<span class="hljs-variable">@include</span> breakpoint(<span class="hljs-number">0</span>, <span class="hljs-number">1024px</span>) {}
</pre>
<h3 class="section-head" id="h-grid"><a href="#h-grid">Grid</a></h3>
<h5 id="h-grid-row">Row</h5>
<p>Generates a grid row.</p>
<pre class="code skip"><span class="hljs-selector-class">.my-row</span> {
<span class="hljs-variable">@include</span> grid-row;
}
</pre>
<p>CSS Output</p>
<pre class="code skip"><span class="hljs-selector-class">.my-row</span> {
<span class="hljs-attribute">display</span>: -ms-flexbox;
<span class="hljs-attribute">display</span>: -webkit-flex;
<span class="hljs-attribute">display</span>: flex;
<span class="hljs-attribute">-ms-flex-direction</span>: row;
<span class="hljs-attribute">-webkit-flex-direction</span>: row;
<span class="hljs-attribute">flex-direction</span>: row;
<span class="hljs-attribute">-ms-flex-wrap</span>: wrap;
<span class="hljs-attribute">-webkit-flex-wrap</span>: wrap;
<span class="hljs-attribute">flex-wrap</span>: wrap;
}
</pre>
<h5 id="h-grid-media">Media Grid</h5>
<p>Generates a media grid. See <a href="/kube/docs/grid/#h-media-grid">live example</a>.</p>
<pre class="code skip"><span class="hljs-selector-class">.my-media-grid</span> {
@include grid-media-<span class="hljs-attribute">columns</span>(<span class="hljs-number">3</span>);
}
</pre>
<p>CSS Output</p>
<pre class="code skip"><span class="hljs-selector-class">.my-media-grid</span> {
-webkit-<span class="hljs-attribute">column-count</span>: <span class="hljs-number">3</span>;
-moz-<span class="hljs-attribute">column-count</span>: <span class="hljs-number">3</span>;
<span class="hljs-attribute">column-count</span>: <span class="hljs-number">3</span>;
<span class="hljs-comment">// column gap is specified</span>
<span class="hljs-comment">// in the grid settings (variables.scss) as $grid-gutter</span>
-webkit-<span class="hljs-attribute">column-gap</span>: <span class="hljs-number">2%</span>;
-moz-<span class="hljs-attribute">column-gap</span>: <span class="hljs-number">2%</span>;
<span class="hljs-attribute">column-gap</span>: <span class="hljs-number">2%</span>;
}
<span class="hljs-selector-class">.my-media-grid</span> &gt; <span class="hljs-selector-tag">div</span> {
<span class="hljs-attribute">display</span>: inline-block;
<span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
}
@<span class="hljs-keyword">media</span> (max-width: 768px) {
<span class="hljs-selector-class">.my-media-grid</span> {
-webkit-<span class="hljs-attribute">column-count</span>: <span class="hljs-number">1</span>;
-moz-<span class="hljs-attribute">column-count</span>: <span class="hljs-number">1</span>;
<span class="hljs-attribute">column-count</span>: <span class="hljs-number">1</span>;
}
}
</pre>
<h3 class="section-head" id="h-flex"><a href="#h-flex">Flex</a></h3>
<pre class="code skip"><span class="hljs-variable">@include</span> flex;
<span class="hljs-variable">@include</span> flex-basis($basis);
<span class="hljs-comment">// items</span>
<span class="hljs-variable">@include</span> flex-items-wrap;
<span class="hljs-variable">@include</span> flex-items-nowrap;
<span class="hljs-variable">@include</span> flex-items-row
<span class="hljs-variable">@include</span> flex-items-column;
<span class="hljs-variable">@include</span> flex-items-left;
<span class="hljs-variable">@include</span> flex-items-right;
<span class="hljs-variable">@include</span> flex-items-center;
<span class="hljs-variable">@include</span> flex-items-space-between;
<span class="hljs-variable">@include</span> flex-items-space-around;
<span class="hljs-variable">@include</span> flex-items-top;
<span class="hljs-variable">@include</span> flex-items-middle;
<span class="hljs-variable">@include</span> flex-items-bottom;
<span class="hljs-comment">// item</span>
<span class="hljs-variable">@include</span> flex-item-grow($grow);
<span class="hljs-variable">@include</span> flex-item-auto;
<span class="hljs-variable">@include</span> flex-item-one;
<span class="hljs-variable">@include</span> flex-item-shrink($shrink);
<span class="hljs-variable">@include</span> flex-item-width($width);
</pre>
<h3 class="section-head" id="h-gradients"><a href="#h-gradients">Gradients</a></h3>
<h5 id="h-gradients-vertical">Vertical</h5>
<pre class="code skip">@<span class="hljs-keyword">include</span> gradient-vertical(<span class="hljs-variable">$startColor</span>, <span class="hljs-variable">$endColor</span>);</pre>
<div class="demo-gradient demo-gradient-vertical"></div>
<pre class="code skip"><span class="hljs-symbol">@include</span> gradient-vertical-<span class="hljs-keyword">to</span>-opacity($startColor, $opacity)<span class="hljs-comment">;</span></pre>
<div class="demo-gradient demo-gradient-vertical-to-opacity"></div>
<h5 id="h-gradients-horizontal">Horizontal</h5>
<pre class="code skip">@<span class="hljs-keyword">include</span> gradient-horizontal(<span class="hljs-variable">$startColor</span>, <span class="hljs-variable">$endColor</span>);</pre>
<div class="demo-gradient demo-gradient-horizontal"></div>
<pre class="code skip"><span class="hljs-symbol">@include</span> gradient-horizontal-<span class="hljs-keyword">to</span>-opacity($startColor, $opacity)<span class="hljs-comment">;</span></pre>
<div class="demo-gradient demo-gradient-horizontal-to-opacity"></div>
<h5 id="h-gradients-radial">Radial</h5>
<pre class="code skip">@include gradient-<span class="hljs-keyword">radial</span>($innerColor, $outerColor);</pre>
<div class="demo-gradient demo-gradient-radial"></div>
<h3 class="section-head" id="h-utils"><a href="#h-utils">Utils</a></h3>
<h5 id="h-utils-clearfix">Clearfix</h5>
<p>Provides an easy way to include a clearfix for containing floats.</p>
<pre class="code skip"><span class="hljs-selector-class">.layout</span> {
<span class="hljs-variable">@include</span> clearfix;
}
</pre>
<p>CSS Output</p>
<pre class="code skip"><span class="hljs-selector-class">.layout</span><span class="hljs-selector-pseudo">:after</span> {
<span class="hljs-attribute">content</span>: <span class="hljs-string">''</span>;
<span class="hljs-attribute">display</span>: table;
<span class="hljs-attribute">clear</span>: both;
}
</pre>
<h5 id="h-utils-transition">Transition</h5>
<p>This mixin provides a shorthand syntax for transitions.</p>
<pre class="code skip"><span class="hljs-comment">// by default 'all linear .2s'</span>
<span class="hljs-meta">@include</span> transition;
<span class="hljs-comment">// custom transitions</span>
<span class="hljs-meta">@include</span> transition(all .<span class="hljs-number">2</span>s ease-<span class="hljs-keyword">in</span>-<span class="hljs-keyword">out</span>);
<span class="hljs-meta">@include</span> transition(opacity <span class="hljs-number">1</span>s ease-<span class="hljs-keyword">in</span>, width .<span class="hljs-number">2</span>s ease-<span class="hljs-keyword">in</span>);
</pre>
<h5 id="h-utils-transform">Transform</h5>
<p>Provides a shorthand syntax for transforms.</p>
<pre class="code skip"><span class="hljs-selector-class">.span</span> {
@include <span class="hljs-attribute">transform</span>(rotate(<span class="hljs-number">90deg</span>));
}
</pre>
<p>CSS Output</p>
<pre class="code skip"><span class="hljs-selector-class">.span</span> {
<span class="hljs-attribute">-webkit-transform</span>: <span class="hljs-built_in">rotate</span>(90deg);
<span class="hljs-attribute">-moz-transform</span>: <span class="hljs-built_in">rotate</span>(90deg);
<span class="hljs-attribute">-ms-transform</span>: <span class="hljs-built_in">rotate</span>(90deg);
<span class="hljs-attribute">transform</span>: <span class="hljs-built_in">rotate</span>(90deg);
}
</pre>
<h5 id="h-utils-blur">Blur</h5>
<p>Provides a shorthand syntax for blur filter.</p>
<pre class="code skip"><span class="hljs-selector-class">.span</span> {
<span class="hljs-variable">@include</span> blur(<span class="hljs-number">5px</span>);
}
</pre>
<p>CSS Output</p>
<pre class="code skip"><span class="hljs-selector-class">.span</span> {
<span class="hljs-attribute">-webkit-filter</span>: <span class="hljs-built_in">blur</span>(5px);
<span class="hljs-attribute">-moz-filter</span>: <span class="hljs-built_in">blur</span>(5px);
<span class="hljs-attribute">-ms-filter</span>: <span class="hljs-built_in">blur</span>(5px);
<span class="hljs-attribute">filter</span>: <span class="hljs-built_in">blur</span>(5px);
}
</pre>
<h5 id="h-utils-retina-image">Retina Image</h5>
<p>Retina image must have a suffix <code>-2x</code>, for example: <code>image-2x.jpg</code></p>
<pre class="code skip">@include retina-<span class="hljs-built_in">background</span>-<span class="hljs-built_in">image</span>($<span class="hljs-built_in">image</span>-url, $<span class="hljs-built_in">image</span>-type, $<span class="hljs-built_in">image</span>-<span class="hljs-built_in">width</span>, $<span class="hljs-built_in">image</span>-<span class="hljs-built_in">height</span>);
// $<span class="hljs-built_in">image</span>-type - jpg, png, gif
// $<span class="hljs-built_in">image</span>-<span class="hljs-built_in">height</span> - optional
</pre>
<p>Example:</p>
<pre class="code skip"><span class="hljs-selector-class">.brand</span> {
@include retina-<span class="hljs-attribute">background-image</span>(<span class="hljs-string">'../logo'</span>, <span class="hljs-string">'png'</span>, <span class="hljs-number">100px</span>);
}
</pre>
<p>CSS Output</p>
<pre class="code skip"><span class="hljs-selector-class">.brand</span> {
<span class="hljs-attribute">background-repeat</span>: no-repeat;
<span class="hljs-attribute">background-image</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">"../logo.png"</span>);
}
@<span class="hljs-keyword">media</span> only screen and (-webkit-min-device-pixel-ratio: <span class="hljs-number">2</span>),
only screen and (min--moz-device-pixel-ratio: <span class="hljs-number">2</span>),
only screen and (-o-min-device-pixel-ratio: <span class="hljs-number">2</span> / <span class="hljs-number">1</span>),
only screen and (min-device-pixel-ratio: <span class="hljs-number">2</span>),
only screen and (min-resolution: <span class="hljs-number">192dpi</span>),
only screen and (min-resolution: <span class="hljs-number">2dppx</span>)
{
<span class="hljs-selector-class">.brand</span> {
<span class="hljs-attribute">background-image</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">"../logo-2x.png"</span>);
<span class="hljs-attribute">background-size</span>: <span class="hljs-number">100px</span> auto;
}
}
</pre>

Some files were not shown because too many files have changed in this diff Show More