Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
|
b0036c491b |
|
@ -0,0 +1,220 @@
|
|||
# Go CSS Coding Guidelines
|
||||
|
||||
**Please [discuss changes](https://go.dev/issue/new?title=wiki%3A+CSSStyleGuide+change&body=&labels=Documentation) before editing this page**, even _minor_ ones. Many people have opinions and this is not the place for edit wars.
|
||||
|
||||
Go's naming conventions are adapted from [Medium's style guide](https://gist.github.com/fat/a47b882eb5f84293c4ed#javascript) and the work being done in the [SUIT CSS framework](https://github.com/suitcss/suit/blob/master/doc/naming-conventions.md). Which is to say, it relies on _structured class names_ and _meaningful hyphens_ (i.e., not using hyphens merely to separate words). This is to help work around the current limits of applying CSS to the DOM (i.e., the lack of style encapsulation) and to better communicate the relationships between classes.
|
||||
|
||||
We require plain CSS over preprocessors like LESS, SASS, etc. This is to avoid additional tooling dependencies.
|
||||
|
||||
## JavaScript
|
||||
|
||||
syntax: `js-<targetName>`
|
||||
|
||||
JavaScript-specific classes reduce the risk that changing the structure or theme of components will inadvertently affect any required JavaScript behavior and complex functionality. You must use these classes if you interact with the DOM via JavaScript. In practice this looks like this:
|
||||
|
||||
```
|
||||
<a href="/login" class="btn btn-primary js-login"></a>
|
||||
```
|
||||
|
||||
Again, JavaScript-specific classes should not, under any circumstances, be styled.
|
||||
|
||||
## Components
|
||||
|
||||
Syntax: `[namespace-]<ComponentName>[-descendantName][--modifierName]`
|
||||
|
||||
Component driven development offers several benefits when reading and writing HTML and CSS:
|
||||
|
||||
* It helps to distinguish between the classes for the root of the component, descendant elements, and modifications.
|
||||
* It keeps the specificity of selectors low.
|
||||
* It helps to decouple presentation semantics from document semantics.
|
||||
|
||||
You can think of components as custom elements that enclose specific semantics, styling, and behavior.
|
||||
|
||||
### namespace (optional)
|
||||
|
||||
If necessary, components can be prefixed with a namespace. For example, you may wish to avoid the potential for collisions between libraries and your custom components by prefixing all your components with a namespace.
|
||||
|
||||
```
|
||||
.godoc-Button { /* … */ }
|
||||
.godoc-Tabs { /* … */ }
|
||||
```
|
||||
|
||||
This makes it clear, when reading the HTML, which components are part of your library.
|
||||
|
||||
### ComponentName
|
||||
|
||||
The component's name must be written in camel case.
|
||||
|
||||
```
|
||||
.MyComponent { /* … */ }
|
||||
<article class="MyComponent">
|
||||
…
|
||||
</article>
|
||||
```
|
||||
|
||||
### ComponentName--modifierName
|
||||
|
||||
A component modifier is a class that modifies the presentation of the base component in some form. Modifier names must be written in camel case and be separated from the component name by two hyphens. The class should be included in the HTML _in addition_ to the base component class.
|
||||
|
||||
```
|
||||
/* Core button */
|
||||
.Button { /* … */ }
|
||||
/* Default button style */
|
||||
.Button--default { /* … */ }
|
||||
<button class="Button Button--primary">…</button>
|
||||
```
|
||||
|
||||
### ComponentName-descendantName
|
||||
|
||||
A component descendant is a class that is attached to a descendant node of a component. It's responsible for applying presentation directly to the descendant on behalf of a particular component. Descendant names must be written in camel case.
|
||||
|
||||
```
|
||||
<article class="Tweet">
|
||||
<header class="Tweet-header">
|
||||
<img class="Tweet-avatar" src="{$src}" alt="{$alt}">
|
||||
…
|
||||
</header>
|
||||
<div class="Tweet-body">
|
||||
…
|
||||
</div>
|
||||
</article>
|
||||
```
|
||||
|
||||
### ComponentName[aria-<state of component>]
|
||||
|
||||
Almost always, component states can be represented using ARIA (aria-expanded, aria-disabled, etc.) so they are recommended for state-based modifications of components. In the very rare case that there is a state that cannot be represented using ARIA, a CSS class of the format `is-stateName` can be used. The CSS state name must be Camel case. Never style these attributes/classes directly; they should always be used as an adjoining class or attribute.
|
||||
|
||||
JS can add/remove these attributes/classes. Every component must define its own styles for the state (as they are scoped to the component).
|
||||
|
||||
```
|
||||
.Tweet { /* … */ }
|
||||
.Tweet[aria-expanded=true] { /* … */ }
|
||||
.Tweet.is-blorked { /* … */ }
|
||||
<article class="Tweet is-blorked" aria-expanded="true">
|
||||
…
|
||||
</article>
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
Prefer lower-case hex values, RGB, or RGBA over named, HSL, or HSLA values. Use short-form hex values where applicable.
|
||||
|
||||
Right:
|
||||
|
||||
```
|
||||
#fff;
|
||||
#f1f2f3;
|
||||
rgb(50, 50, 50);
|
||||
rgba(50, 50, 50, 0.2);
|
||||
```
|
||||
|
||||
Wrong:
|
||||
|
||||
```
|
||||
#FFFFFF;
|
||||
#F1F2F3;
|
||||
white;
|
||||
hsl(120, 100%, 50%);
|
||||
hsla(120, 100%, 50%, 1);
|
||||
```
|
||||
|
||||
## Formatting
|
||||
|
||||
The following are some high level page formatting style rules.
|
||||
|
||||
### Spacing
|
||||
|
||||
CSS rules should be comma separated but live on new lines:
|
||||
|
||||
Right:
|
||||
|
||||
```
|
||||
.Content,
|
||||
.Content-edit {
|
||||
…
|
||||
}
|
||||
```
|
||||
|
||||
Wrong:
|
||||
|
||||
```
|
||||
.Content, .Content-edit {
|
||||
…
|
||||
}
|
||||
```
|
||||
|
||||
CSS blocks should be separated by a single new line. not two. not 0.
|
||||
|
||||
Right:
|
||||
|
||||
```
|
||||
.Content {
|
||||
…
|
||||
}
|
||||
.Content-edit {
|
||||
…
|
||||
}
|
||||
```
|
||||
|
||||
Wrong:
|
||||
|
||||
```
|
||||
.Content {
|
||||
…
|
||||
}
|
||||
|
||||
.Content-edit {
|
||||
…
|
||||
}
|
||||
```
|
||||
|
||||
### Quotes
|
||||
|
||||
Quotes are optional in CSS. We use single quotes as it is visually clearer that the string is not a selector or a style property.
|
||||
|
||||
Right:
|
||||
|
||||
```
|
||||
background-image: url('/img/you.jpg');
|
||||
font-family: 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial;
|
||||
```
|
||||
|
||||
|
||||
Wrong:
|
||||
|
||||
```
|
||||
background-image: url(/img/you.jpg);
|
||||
font-family: Helvetica Neue Light, Helvetica Neue, Helvetica, Arial;
|
||||
```
|
||||
|
||||
## Write Simple Selectors
|
||||
|
||||
Avoid sequences of simple selectors ("compound selectors").
|
||||
|
||||
The only exceptions are state-based selectors that are dynamically added to indicate a state change (for example, a tweet that has "[aria-expanded=true]").
|
||||
|
||||
Right:
|
||||
|
||||
```
|
||||
/* State-based simple selector. */
|
||||
tweet[aria-expanded=true] {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Wrong:
|
||||
|
||||
```
|
||||
/* Sequence of simple selectors. */
|
||||
button.foo.bar {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Images
|
||||
|
||||
Add height and width attributes to images in the html markup to help minimize layout shift during page load.
|
||||
|
||||
```
|
||||
<img src="url/to/image.png" height="240" width="160">
|
||||
```
|
|
@ -1,150 +0,0 @@
|
|||
Originally published at https://rakyll.org/coredumps/.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Debugging is highly useful to examine the execution flow
|
||||
and to understand the current state of a program.
|
||||
|
||||
A core file is a file that contains the memory dump of a running
|
||||
process and its process status. It is primarily used for post-mortem
|
||||
debugging of a program, as well as to understand a program's state
|
||||
while it is still running. These two cases make debugging of core dumps
|
||||
a good diagnostics aid to postmortem and analyze production
|
||||
services.
|
||||
|
||||
I will use a simple hello world web server in this article,
|
||||
but in real life our programs might get very
|
||||
complicated easily.
|
||||
The availability of core dump analysis gives you an
|
||||
opportunity to resurrect a program from specific snapshot
|
||||
and look into cases that might only reproducible in certain
|
||||
conditions/environments.
|
||||
|
||||
__Note__: This flow only works on Linux at this point end-to-end,
|
||||
I am not quite sure about the other Unixes but it is not
|
||||
yet supported on macOS. Windows is not supported at this point.
|
||||
|
||||
Before we begin, you need to make sure that your ulimit
|
||||
for core dumps are at a reasonable level. It is by default
|
||||
0 which means the max core file size can only be zero.
|
||||
I usually set it to unlimited on my development machine by typing:
|
||||
|
||||
```
|
||||
$ ulimit -c unlimited
|
||||
```
|
||||
|
||||
Then, make sure you have [delve](https://github.com/derekparker/delve)
|
||||
installed on your machine.
|
||||
|
||||
Here is a `main.go` that contains a simple handler and it starts an HTTP server.
|
||||
|
||||
```
|
||||
$ cat main.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "hello world\n")
|
||||
})
|
||||
log.Fatal(http.ListenAndServe("localhost:7777", nil))
|
||||
}
|
||||
```
|
||||
|
||||
Let's build this and have a binary.
|
||||
|
||||
```
|
||||
$ go build .
|
||||
```
|
||||
|
||||
Let’s assume, in the future, there is something messy going on with
|
||||
this server but you are not so sure about what it might be.
|
||||
You might have instrumented your program in various ways but it
|
||||
might not be enough for getting any clue from the existing
|
||||
instrumentation data.
|
||||
|
||||
Basically, in a situation like this, it would be nice to have a
|
||||
snapshot of the current process, and then use that snapshot to dive
|
||||
into to the current state of your program with your existing debugging
|
||||
tools.
|
||||
|
||||
There are several ways to obtain a core file. You might have been
|
||||
already familiar with crash dumps, these are basically core dumps
|
||||
written to disk when a program is crashing. Go doesn't enable crash dumps
|
||||
by default but gives you this option on Ctrl+backslash when
|
||||
`GOTRACEBACK` env variable is set to "crash".
|
||||
|
||||
```
|
||||
$ GOTRACEBACK=crash ./hello
|
||||
(Ctrl+\)
|
||||
```
|
||||
|
||||
It will crash the program with stack trace printed and core dump file
|
||||
will be written.
|
||||
|
||||
Another option is to retrieve a core dump from a running process
|
||||
without having to kill a process.
|
||||
With `gcore`, it is possible to get the core
|
||||
files without crashing. Let’s start the server again:
|
||||
|
||||
```
|
||||
$ ./hello &
|
||||
$ gcore 546 # 546 is the PID of hello.
|
||||
```
|
||||
We have a dump without crashing the process. The next step
|
||||
is to load the core file to delve and start analyzing.
|
||||
|
||||
```
|
||||
$ dlv core ./hello core.546
|
||||
```
|
||||
|
||||
Alright, this is it! This is no different than the typical delve interactive.
|
||||
You can backtrace, list, see variables, and more. Some features will be disabled
|
||||
given a core dump is a snapshot and not a currently running process, but
|
||||
the execution flow and the program state will be entirely accessible.
|
||||
|
||||
```
|
||||
(dlv) bt
|
||||
0 0x0000000000457774 in runtime.raise
|
||||
at /usr/lib/go/src/runtime/sys_linux_amd64.s:110
|
||||
1 0x000000000043f7fb in runtime.dieFromSignal
|
||||
at /usr/lib/go/src/runtime/signal_unix.go:323
|
||||
2 0x000000000043f9a1 in runtime.crash
|
||||
at /usr/lib/go/src/runtime/signal_unix.go:409
|
||||
3 0x000000000043e982 in runtime.sighandler
|
||||
at /usr/lib/go/src/runtime/signal_sighandler.go:129
|
||||
4 0x000000000043f2d1 in runtime.sigtrampgo
|
||||
at /usr/lib/go/src/runtime/signal_unix.go:257
|
||||
5 0x00000000004579d3 in runtime.sigtramp
|
||||
at /usr/lib/go/src/runtime/sys_linux_amd64.s:262
|
||||
6 0x00007ff68afec330 in (nil)
|
||||
at :0
|
||||
7 0x000000000040f2d6 in runtime.notetsleep
|
||||
at /usr/lib/go/src/runtime/lock_futex.go:209
|
||||
8 0x0000000000435be5 in runtime.sysmon
|
||||
at /usr/lib/go/src/runtime/proc.go:3866
|
||||
9 0x000000000042ee2e in runtime.mstart1
|
||||
at /usr/lib/go/src/runtime/proc.go:1182
|
||||
10 0x000000000042ed04 in runtime.mstart
|
||||
at /usr/lib/go/src/runtime/proc.go:1152
|
||||
|
||||
(dlv) ls
|
||||
> runtime.raise() /usr/lib/go/src/runtime/sys_linux_amd64.s:110 (PC: 0x457774)
|
||||
105: SYSCALL
|
||||
106: MOVL AX, DI // arg 1 tid
|
||||
107: MOVL sig+0(FP), SI // arg 2
|
||||
108: MOVL $200, AX // syscall - tkill
|
||||
109: SYSCALL
|
||||
=> 110: RET
|
||||
111:
|
||||
112: TEXT runtime·raiseproc(SB),NOSPLIT,$0
|
||||
113: MOVL $39, AX // syscall - getpid
|
||||
114: SYSCALL
|
||||
115: MOVL AX, DI // arg 1 pid
|
||||
```
|
Loading…
Reference in New Issue