@jorsek/content-portal-themes
v4.0.1
Published
## Structure
Downloads
20
Maintainers
Keywords
Readme
Themes
Structure
+-- base
+-- dark
+-- light
+-- whitelabel
...
The dark and light themes independently inherit from the base theme using the npm deepmerge
package.
base
should never containcolor
properties and should only contain structural (grid
,flex
,position
, etc...) CSSdark
,light
, and any other color themes should contain mostly color specifications but should avoid containing structural CSS changes. This should be limited in scope.- None of the basic themes should make use of
:before
or:after
pseudo-selectors.- Those are powerful tools for drastically changing the layout structure and presentation of a specific tenant. They should be reserved exclusively for tenant theme CSS.
- Tenant themes will likely contain
all of the above
and css adjustments (position
,top
,margins
,padding
)
Rules
- Never use negative margins in the base themes. Customer overrides may require it (such as Vyatta's hero image and background color) but should be avoided if at all possible.
- Never use percentages unless It's a base 8 root %. (100%, 50%, 25%, 12.5%, 6.25% 3.125%)
- 33% sucks for this very reason. Use it sparingly.
- Instead, try to use
flex
properties andflex-basis
when forced to use awkward percentages.)
- Use rems whenever possible. The html base font-size should be set by default to 16px. Scale everything off rems that way.
- Use
flex
for general layout properties. Usegrid
for specific use-cases with lists and items that need to be fixed to a certain number.grid
is an extension offlex
and anything can be achieved with flex that you can withgrid
albeit less rigid.
BEM
BEM stands for "{Block}-{Element}-{Modifier}". We use a slightly modified variation of BEM for CSS naming, but it's good to understand BEM and why it exists. The reason for this is we want and invite people to apply their own styling.
Typical jss/sass stylesheet generation obfuscates the names of CSS classes.
What we generate are semantic naming of elements based on the layout and page they are rendered on.
Element CSS naming
Every element should have a specifically unique CSS name. No elements should be left without a class.
Do NOT do this:
<!-- not very descriptive of your intent. What are your dogs doing here? Why should I care if they are YOUR dogs?-->
<div className={classes.my_dogs}>
<!-- THIS SPAN IS BAD AND DIFFICULT TO TARGET WITH CSS AND YOOU SHOULD FEEL BAD -->
<span>
<!-- ... just... why? ...WHY!? a ul serves the same function. just style the ul -->
<div>
<!-- Cool, but COMPLETELY unrelated to the parent container. -->
<!-- kittens/kitten This creates a TON of confusion and it often easy to overlook and hard to remember -->
<ul className={classes.kittensBlender}>
<!-- Why it is a blender? Does it need to be a blender? maybe a more apt name would be blendedKitten -->
<!-- Also, "toys_1" Does NOT describe the INTENT of the list. we should be more SPECIFIC! -->
{this.props.toys_1.map((item, i)=> <li className={classes.kitten}></li>}
</ul>
</div>
</span>
</div>
Much better:
<!-- if the name of the component pa-->
<div className={classes.dogToys}>
<!-- Title vs Header is debatable here. just pick one and BE CONSISTENT -->
<h3 className={classes.dogToysTitle}>{props.title}</h3>
<!-- If wrap an element within another div, just make sure there are at least TWO elements inside it-->
<!-- In fact, we should consider wrappiing every TWO elements within a div to provide better style override opportinities -->
<div className={classes.dogToysContainer}>
<!-- don't switch up from Title to Header now. If you do, go back and change the other one to header. -->
<!-- You might be tempted to go with SubTitle here, but we are within the Container. -->
<!-- If you want to move this next to to be a sibling of the dogToysTitle element, -->
<!-- you would name it SubTitle and wrap both dogToysTitle and dogToysSubTitle in a dogToysTitleWrapper div. -->
<p className={classes.dogToysContainerTitle}></p>
<!-- dogToysChewToys vs dogToysChewToyList - always go with the List instead of pluralizing a shorter name. -->
<!-- Remember, we want to be SPECIFIC! The name chosen based on the property we are maping over to generate the list -->
<!-- that name should also be SPECIFIC to the intent. -->
<ul className={classes.dogToysChewToyList}>
<!-- dogToysChewToys vs dogToysChewToyList - always go with the List instead of pluralizing a shorter name. -->
<!-- Remember, we want to be specific! Theese are Dog Chew toys. -->
<!-- The naming should be consistent so it's easy to find issues -->
{this.props.dogChewToys.map((item, i)=> (
<!-- dogToysChewToyListItem. This is a highly specific name. this shows intent, itration, specificity, -->
<!-- and it is VERY easy to see what it is doing JUST by looking at the name -->
<li key={title+i} className={classes.dogToysChewToyListItem}>{item}</li>
))}
</ul>
</div>
</div>
Full~ish example:
<!-- Wrapper - outer becomes .dog-toys-wrapper -->
<div className={classes.dogToysWrapper}>
<!-- when unsure, Think of the intent, then fall back to the name of the element if need be.-->
<!-- becomes .dog-toys-caption -->
<caption className={classes.dogToysCaption}></caption>
<!-- this will become .dog-toys-root. Why is the root inside a wrapper? It doesn't need to be. Just be consistent. -->
<div className={classes.dogToys}>
<!-- becomes .dog-toys-title -->
<h3 className={classes.dogToysTitle}>{props.title}</h3>
<!-- becomes .dog-toys-container -->
<div className={classes.dogToysContainer}>
<!-- becomes .dog-toys-container-title -->
<p className={classes.dogToysContainerTitle}></p>
<!-- becomes .dog-toys-chew-toy-list -->
<ul className={classes.dogToysChewToyList}>
<!-- becomes .dog-toys-chew-toy-list -->
{this.props.dogChewToys.map((item, i)=> (
<!-- becomes .dog-toys-chew-toy-list-item -->
<li key={title+i} className={classes.dogToysChewToyListItem}>{item}</li>
))}
</ul>
</div>
</div>
</div>
If you end up nesting containers within containers and wrappers within wrappers, etc...
STOP
Make a new component.
Breakpoints.
We have standardized the breakpoints to hit most popular device widths.
mediaBreakpoints: [375, 480, 640, 768, 1024, 1280, 1366]
- 375 - 640: targets most Mobile devices. Some guides show 320, but those are older iphone 4s~5 era devices.
- 640 - 1280 Targets most tablet devices and smaller laptop screens
- 1366+ - Desktop Only
Local Development within in the content-portal repo
$ cd ~/src
$ git clone [email protected]:Jorsek/content-portal-themes.git
$ cd content-portal-themes
$ npm link
$ cd ../content-portal
& npm link @jorsek/content-portal-themes