acss-io / atomizer Goto Github PK
View Code? Open in Web Editor NEWA library to create small, reusable CSS that scales as your website grows.
Home Page: https://acss.io
License: Other
A library to create small, reusable CSS that scales as your website grows.
Home Page: https://acss.io
License: Other
It'd be helpful if the CLI could output the config file generated during parsing, either in addition to the CSS (aka a sidecar) or in lieu of CSS. The file could be named similar to the value of --output
, so like:
atomizer -c base-config.json -o myatomic.css *.html
Which would generate:
myatomic.css
myatomic.config.json
Or, we can have a new flag for config output which is like -o|--output
and takes a filename.
We need to be able to pass !
in the class and have Atomizer writes the rule with !important
, for example:
<div class="Bgc-000!"></div>
.Bgc-000\! {
background: #000 !important;
}
Currently the rules.js
file has 2170 LoC and lots of duplication, that makes it harder to maintain because there is no way for changes in one style to affect others so we have to duplicate a lot of code over and over.
We can allow Rules to inherit from each other so that what we only write the code that different and reuse what is the same, below thee is on suggestion to simplify our Rules.css:
// rules.js
Atomizer.setRules([
/**
==================================================================
PADDING
==================================================================
*/
// all edges
{
type: 'pattern',
id: 'padding',
name: 'Padding (all edges)',
prefix: '.P-',
properties: ['padding'],
allowCustom: true,
allowSuffixToValue: true,
rules: [
{suffix: '0', values: [0]},
{suffix: 'inh', values: ['inherit']}
]
},
// top
{
parent: 'padding',
id: 'padding-top',
name: 'Padding top',
prefix: '.Pt-',
properties: ['padding-top'],
},
// end
{
parent: 'padding',
id: 'padding-end',
name: 'Padding end',
prefix: '.Pend-',
properties: ['padding-$END'],
},
...
]);
module.exports = Atomizer.getRules();
An other advantage of this approach is that we can have rules being defined in different files and even allow the user to set his custom rules. But IMHO the best part is because we because it would make our rules.js
file at least half the size.
Right now we parse individual keys/values for the RTL $START and $END tokens. We could just be parsing the CSS output for those tokens instead.
Also, these tokens could easily be mistaken for custom values ($ is used for globals in some projects), so maybe Atomizer should use tokens that are a little more unique?
Houston, I think we have a typo!
https://github.com/yahoo/atomic.css/blob/master/src/rules.js#L854
Here is a typical use case (for transition): Trs-all_2s
Atomizer would replace the _
with a space:
.Trs-all_2s {
transition: all 2s;
}
``
The tool output this for D-ib
:
#atomic .D-ib {
display: inline-block;
}
instead of:
#atomic .D-ib {
display: inline-block;
*display: inline;
zoom: 1;
}
We want to allow the creation of classes like Td-u:h
which would style text with an underline on mouseover.
As discussed, it could be in the form of:
{
suffix: 'f',
values: ['foo'],
breakPoints: ['sm'],
pseudo-classes: ['hover', 'focus']
}
But what about if the user wanted to sandbox this class within a breakpoint? Should that be a concern? I'm not sure there are real use cases for that though.
Absurd adds extra overhead for not a lot of added value. The kind of conversions we're doing aren't particularly complicated and could probably be done more efficiently with a little custom JS. Will explore what it'd take to pull out Absurd, and do the conversions ourselves.
fyi @renatoi
Let's discuss the value of such style sheet in this project and if we think it makes sense to include one
Right now, 'banner' is the only option we don't expose via the CLI. It'd be good to expose this finally.
Add support for globally-defined suffixes, which will make it easier for common values to be reused across a number of CSS properties. For example, in config you may specify something like:
{
globals: {
foo: '10px'
}
}
...which would allow you to write classes like H-foo
and P-foo
, which would output:
.H-foo {
height: 10px;
}
.P-foo {
padding: 10px;
}
...without requiring you to write custom config for every class using the foo
suffix.
Would be helpful to tag configuration output with semver that's tied to the ruleset, that way as the rulesets change over time we can properly ensure that configuration files work with a particular version of the ruleset.
Should be possible to pass extra rulesets, now that we have an addRules()
API.
Right now we have a few tests for getCss()
that are a dumping ground for every unique type of class (hex values, hex + alpha, customs, child selectors, customs, etc). It'd be better if we could break this up into one test per class type, so we can be more explicit about having proper coverage for all syntax we support.
The 1.x configuration format is overly complex and verbose, and no longer fits well with how we're using Atomizer to parse classes. Instead, we'll migrate 2.x to use a new config format that is class-centric, and then @renatoi will refactor/replace AtomicBuilder.js
to no longer generate the 1.x config, but instead dump an array of classes into the config output, and then atomizer.js will parse those classes as necessary when generating the CSS. (Basically, we're cutting out the middle stage of configuration and going straight from classes to CSS.)
Custom classes/suffixes will continue to be supported in configuration as in 1.x.
From an issue posted by @hankhsiao on grunt-atomizer
's repo (https://github.com/yahoo/grunt-atomizer/issues/11):
I got
'vertical-align':{ custom: [ {suffix: 'c', values: ['YOUR-CUSTOM-VALUE']} ] }
And then I tried to put it in my custom configuration, I got
Warning: Custom has been passed but it is not allowed for this rule. Config key: vertical-align.
@thierryk recently pointed out that Atomizer's breakpoint design, which limits you to three breakpoints, is not flexible enough to accommodate common use cases. We probably should allow developers to create unlimited arbitrary breakpoints.
Also, it'd be a good opportunity to revisit whether it makes sense to have any default breakpoints (such as the 3 we have now), and if so, what their default values should be.
Starting this issue to discuss ideas for documentation improvements based on my first impressions trying to play with the lib. fyi @renatoi @thierryk
font-size
or text-align
or something similar.atomicConfig.js
and atomicObjects.js
files as well.atomicConfig.js
, but there's no instructions as to whether that's what users should edit or replace. This could be made more clear (eg, make that file an explicit "example" config)Currently hex values are ambiguous, since they're just 3 or 6 digits in a suffix with no special char to set them apart. They can easily be confused with custom suffixes (eg, Fz-100
would incorrectly produce font-size: #100
).
We need to introduce a more explicit way of specifying colors, eg C-#333
Right now namespace is not exposed via the CLI tool. (Or at best, support is there but not documented.) Need to make sure this is working for 2.0.0
If you try and use a class like D-n!
, it will render as:
.D-n\! {
display: none;
}
However, if I use a suffix that's a value, such as Op-1!
, then I get !important
as expected:
.Op-1\! {
opacity: 1 !important;
}
Seems that getCss()
is rendering "rule" values without reference the property in the treeo
array which has !important
appended?
fyi @renatoi
Right now the CLI requires you to pass files for parsing, not directories. It also therefore can't parse recursively. We'll add support for directories, and a -R
flag for recursive parsing.
Example:
'padding-x': {
'custom': [{
suffix: '10',
values: ['10px']
}]
},
output:
#atomic .Mx-10 {
padding-left: 10px;
padding-right: 10px;
}
instead of:
#atomic .Px-10 {
padding-left: 10px;
padding-right: 10px;
}
"Line clamping" is not a simple thing as it relies on a few things:
.LineClamp
needs:
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
while a.LineClamp
relies on those:
display: inline-block;
*display: inline;
zoom: 1;
and a.LineClamp:after
on these (WebKit bug):
content: ".";
font-size: 0;
visibility: hidden;
display: inline-block;
overflow: hidden;
height: 0;
width: 0;
The above are the styles we need regardless of the number of lines to show, because for that we need a couple more declarations:
-webkit-line-clamp: <number of lines>;
max-height: <line-height * font-size>;
Not sure what is the best way to approach this. I'm thinking of a helper and a modifier would be the easiest way to go here.
And we'd pass both the number of lines and the max-height
we want in the suffix?
Something like this may be:
<div class="LineClamp-372px">No more than 3 lines please (font-size is 16px and line-height is 1.5 in here)...</div>
The first digit is the number of lines we want followed by the height
we need. This is a helper class, so I think we don't really have to stick to any particular syntax as long as it makes sense somehow without complicating things much.
Then helpers.css contains:
[class*=LineClamp] {
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
a[class*=LineClamp] {
display: inline-block;
*display: inline;
zoom: 1;
}
a[class*=LineClamp]:after {
content: ".";
font-size: 0;
visibility: hidden;
display: inline-block;
overflow: hidden;
height: 0;
width: 0;
}
And Atomizer outputs this:
.LineClamp-372px {
-webkit-line-clamp: 3;
max-height: 72px; /* 16px * 1.5 * 3 */
}
Thoughts?
Note that I'd prefer to use [class|=LineClamp]
instead of [class*=LineClamp]
for this, but I think IE8 does not support the former :-(
Right now the CLI tool requires you to pass a default config file, because at the very least we need the config
preamble at the beginning of the config file (stuff like namespace
, start
, end
are defined within config
.) We should allow those config params to be passed as args to the CLI so that users won't have to manually create a config file to get started.
getConfig()
accepts an argument representing existing config which is currently used to determine if custom classes have been defined (otherwise a warning is displayed.) However, the config returned by getConfig()
doesn't include any of this configuration, so a developer would still have to manually merge the newly generated config with the pre-existing config. This seems unhelpful, so we should have getConfig()
just do the merge for you, and return the final configuration.
For example:
transform: none
transform: matrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0)
transform: translate(12px, 50%)
transform: translateX(2em)
transform: translateY(3in)
transform: scale(2, 0.5)
transform: scaleX(2)
transform: scaleY(0.5)
transform: rotate(0.5turn)
transform: skewX(30deg)
transform: skewY(1.07rad)
transform: matrix3d(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0)
transform: translate3d(12px, 50%, 3em)
transform: translateZ(2px)
transform: scale3d(2.5, 1.2, 0.3)
transform: scaleZ(0.3)
transform: rotate3d(1, 2.0, 3.0, 10deg)
transform: rotateX(10deg)
transform: rotateY(10deg)
transform: rotateZ(10deg)
transform: perspective(17px)
transform: translateX(10px) rotate(10deg) translateY(5px)
Plus:
transform-function
transform-origin
transform-style
Following Emmet syntax things should look like this:
Trfskx-30deg {
transform: rotate(30deg);
}
.Trfsky-0.5 {
transform: scaleY(0.5);
}
We could also discuss the value of going a slightly different route, using the value as a prefix and the parameter as suffix(?) It may be easier for people to make sense of the class names. For example:
.SkewX-30deg {
transform: skewX(30deg)
}
.ScaleY-0.5 {
transform: scaleY(0.5);
}
A depart from what we do, but may be worth making an exception as in my opinion, it makes things much more readable.
In any case, we need to change things a little bit because we cannot plug suffix as parameters yet.
Thoughts?
We need to bring back the mergeConfigs()
API we had in 1.0, so that various libs (like grunt-atomizer) can easily merge multiple configs before calling Atomizer APIs.
We know why we have chosen to capitalize Atomic classes (for a very good reason), but it seems many people are bothered by this. I'm wondering if we should allow users to go full lowercase... Even though it is not a smart move.
We often use rules like this one:
.menu-on .menu-button {
display: block;
}
What if we created atomic classes to take care of this and remove the need of most of these rule?
Imaging this:
<button class="menu-on--D-b" ..>
Such class would produce this in atomic.css:
.D-b,
.menu-on .menu-on--D-b {
display: block;
}
I don't think this would be a good idea after all, but it was worth writing it down :)
The following does not output anything:
'box-sizing': {
'bb': true
}
This is a place holder. I'll list the classes and rules here soon.
Right now rules.js
require()'s example-config.js
to get the $START
and $END
config values. This seems like something that should be passed in if it needs to be configurable, which means making the export a function rather than an array, I think. Do we still need those values to be configurable, @renatoi and @thierryk?
I am thinking of how we could allow authors to create a rule like the one below by passing the value as a suffix:
transition-delay: 2s, 4ms;
.Trsde-<what should this be?>
Right now it's not possible to have a custom suffix that's numeric if a rule has allowSuffixToValue
set to true, such as Fz-10
. Currently such a class would be translated into:
.Fz-10 {
font-size: 10;
}
...which isn't valid.
The problem is that sometimes numerics are valid values, such as in the case of z-index
, font-weight
, or line-height
, but in all other cases, a unit of measure (eg px
) would be required.
I propose that we add a boolean to the rules that basically declares that for a given rule, the suffix-to-value requires a unit of measure. Something like suffixRequiresUnit
, though I'm not sure how to best word it. By default this setting would be true
, but would be false
for the exceptions such as the ones listed above.
start
and end
occurrences with S
and E
, not necessary to reduce bytes but rather to make sure these standout and are seen by devs as offset values - that stand for start
and end
. I also think it will make things easier to read across rules/declarations. This is far from perfect, but I think it is better than keeping what we have now. Unfortunately, abstracting left
and right
keywords comes at a cost :-(Mend
would become ME
,Bgp-st
would become Bgp-St
,Bd-start
would become Bd-S
,Ta-s
would become Ta-S
,Cl-start
would become Cl-S
,.Bd-start-0
would become .Bd-S-0
,box-shadow
because we need to be able to pass 4 length (offset-x, offset-y, blur-radius, spread-radius), not just 3, and we should also be able to pass inset
as a value.font-size
. Fz-a
, Fz-b
, Fz-c
, etc. sound weird to me.%
) values without having to escape them. I think we should do that for them as I'm afraid people would have no clue. Actually, they may have no clue that they can use percentages in the firt place, so may be this is a moot point...Dn
class or add !important
to it because as it is today it duplicates what we already have in the D-n
class.We have the following helper classes:
.Bd-0 {
border: 0;
}
.Bd-1,
.Bdx-1,
.Bdy-1,
.Bdt-1,
.Bdend-1,
.Bdb-1,
.Bdstart-1 {
border-width: 0;
border-style: solid;
}
.Bdstart-1 {
border-left-width: 1px;
}
.Bdend-1 {
border-right-width: 1px;
}
.Bdx-1 {
border-right-width: 1px;
border-left-width: 1px;
}
.Bdy-1 {
border-top-width: 1px;
border-bottom-width: 1px;
}
But I think we should move all this to rules.js
โ using classes like Bdw-
, Bds-
, Bdc-
.
That way users can create border styling without having to create custom Atomic classes.
Thoughts?
Options currently given defaults by atomizer.js:
{
require: [],
morph: null,
combineSelectors: true,
minify: false,
keepCamelCase: false,
extCSS: '.css',
banner: '',
namespace: '#atomic',
rtl: false
}
banner
is used by atomizer.js
morph
and require
are used by AbsurdJS (via atomizer.js).
rtl
and namespace
are used by AtomicBuilder.js currently.
extCSS
, combineSelectors
, minify
, and keepCamelCase
I believe are not being used, and can be removed.
From issue #76:
For the record: helpers.css (from another repo) has been updated with border classes meant to help when styling boxes with a single pixel border but those rules need to integrate Atomizer somehow.
More details from @thierryk:
border needs 3 values:
width style color
. We can get style borders the way we want with Atomizer by using those 3 but a common use case is to style border with a single pixel, so what we added to the helper classes are border declarations mixing bothstyle
andwidth
that way authors can do this:
Bd Bdc-000
to get a black border around a box instead of having to go verbose with AtomicBdc-000 Bds-s Bdw-1px
I think the config file could hold some "meta data" and output that at the top of atomic.css.
I'm thinking of author's name, project name, version(?), and stuff like that (time stamp too?)...
I think we could go this route:
.C-FFF\.4 {
color: rgba(255, 255, 255, .4);
}
Same as we have now, C-
followed by hex
value to what we'd add the transparency value.
The .
in there can be used as marker since 1
(opaque) should be expressed as plain grb()
/hex
value.
Thoughts?
Even though they should belong there since those are valid values for this property, I think it'll confuse people more than it'll help them.
So let's make sm
, md
, and the like custom values...
We should plug IE hacks along with Ov-h
and D-ib
:
.D-ib {
display: inline-block;
*display: inline;
zoom: 1;
}
.Ov-h {
overflow: hidden;
zoom: 1;
}
I've removed the Bfc
helper classes as it will be meaningless to most users and also because it maps to overflow:hidden
, so I think it's better people know what they are dealing with.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.