GithubHelp home page GithubHelp logo

bss's People

Contributors

dead-claudia avatar fuzetsu avatar porsager avatar stephanhoyer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bss's Issues

Overload $nest to allow single hash input, split selector on commas

  1. Overload $nest to allow single hash input
// make
b.$nest({
  'td' : 'color red',
  'th' : 'color blue',
})
// equivalent to 
b
.$nest('td', 'color red')
.$nest('th', 'color blue')
  1. Split selectors on commas
// make
b.$nest('td, th', 'padding 1em')
// equivalent to
b.$nest('td', 'padding 1em').$nest('th', 'padding 1em')

What do you think?

Meta concerns

I'd like to be able to run an application across several windows. At this point, the don't make me think magic style injections become a limitation.

I realise addressing this kind of outside context problem raises all sorts of other concerns - why not chuck in SSR and GTK native decorators while we're at it? - but for my part I'd be happy with what I think is a pretty modest proposal - a b.toString() method that returns the whole sheet as a string.

I think this would do a good job of preempting meta concerns down the road (multiple instances, stateless mode, etc) without complicating the API too much.

convert fractions to percentage values

Hello @porsager

bss/lib/utils.js

Lines 136 to 140 in 64d8d7f

function formatValue(prop, value) {
return value in vendorValuePrefix
? vendorValuePrefix[value]
: value + (isNaN(value) || value === null || typeof value === 'boolean' || cssVar(prop) ? '' : appendPx(prop))
}

Would it make sense to automatically convert fractions to percentage values instead of adding px?

so instead of

b({ width: 1 / 3 }) // -> { style: { width: '0.3333333333333333px' } }

you'd get

b({ width: 1 / 3 }) // -> { style: { width: '33.3333333333333333%' } }

Or can you think of a situation where % would not be the desired outcome when working with Integer < 0

assign deeper

@porsager

please consider the following scenario:

I have preset styles grow and hoverShadow, both accessing pseudo :hover & :focus :

const preset = const preset = {
  grow: b({
    __style: {
      '-moz-osx-font-smoothing': 'grayscale',
      backfaceVisibility: 'hidden',
      transform: 'translateZ(0)',
      transition: 'transform 0.25s ease-out',
      ':hover': _growHover,
      ':focus': _growHover,
      ':active': { transform: 'scale(.90)' }
    }
  }),
  
  hoverShadow: b({
    __style: {
      cursor: 'pointer',
      position: 'relative',
      transition: 'all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1)',
      '::after': {
        content: '""',
        boxShadow: '0px 0px 16px 2px rgba(0, 0, 0, .2)', // box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3)
        borderRadius: 'inherit',
        opacity: '0',
        position: 'absolute',
        top: '0',
        left: '0',
        width: '100%',
        height: '100%',
        zIndex: '-1',
        transition: 'opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1)'
      },
      ':hover': { '::after': { opacity: '1' } },
      ':focus': { '::after': { opacity: '1' } }
    }
  })
}

When I attempt to combine both preset styles on a base style, e. g.

const base = b`
  width: 100px
  height: 100px
  bc: lightgrey
  margin-left: 14
  margin-bottom: 28
`

... there are two options:

a) String concatenation (e. g. mithril hyperscript query)

m('div' + base + preset.grow + preset.hoverShadow, 'String composition')

b) bss helpers

b.helper(preset)
m('div' + base.grow.hoverShadow, 'Helper composition')

Now option a) with strings works as expected, of course
However, the helper variant will only shallow-merge the pseudo selectors and hence miss the hover-grow effect

here is a flems to illustrate

I assume the assign function in lib/utils is responsible for the merge

bss/lib/utils.js

Lines 58 to 64 in bebc419

export function assign(obj, obj2) {
for (const key in obj2) {
if (obj2.hasOwnProperty(key))
obj[key] = obj2[key]
}
return obj
}

maybe it could be extended with something more recursive like this:

const _blnkObj = {}
/**
 * mergeStyles :: (a, b) -> Object
 * Immutably deep merge two objects
 *
 * @param a
 * @param b
 * @return {object}
 */
export function mergeStyles (a = _blnkObj, b = _blnkObj) {
  const list = Object.keys(b || _blnkObj)
  const res = Object.assign({}, a)
  for (let i = 0; i < list.length; i++) {
    const k = list[i]
    const ak = a[k]
    const bk = b[k]
    res[k] = (typeof ak === 'object' && !Array.isArray(ak)) ? mergeStyles(ak, bk) : bk
  }
  return res
}

add 2 rules for same property

I've try to add 2 rules for same property like below:

console.log(b.cursor('ns-resize').cursor('-webkit-grab').style)

But result is only last style, is this an issue?

`userSelect none` not auto-prefixed in Firefox

b`userSelect none`

This works fine in Chrome but is apparently not correctly prefixed for Firefox. Using mozUserSelect none explicitly works as expected.

I did a bit of poking in Firefox and found that, for cssProperties in utils.js:

  • cssProperties.includes('userSelect') === false
  • cssProperties.includes('MozUserSelect') === false

For Chrome:

  • cssProperties.includes('userSelect') === true
  • cssProperties.includes('webkitUserSelect') === true

Not sure if any of that helps... Sorry, the code is kind of beyond me.

support `$nest` directly

Think below:

b.$nest({'td':{color: 'blue'}}).class
console.log(b.getSheet())

It's not generate any class, can it be supported?

Partial application overload for binary signature methods

HEY! :D

As you may know, I dislike parentheses. Therefore this displeases me:

css.$nest(', *', `
        display: flex;
        flex: 1 0 0;
        align-items: stretch;
      `)

But what about...

css.$nest`, *``
        display: flex;
        flex: 1 0 0;
        align-items: stretch;
      `

Isn't that first line some of the tastiest punctuation soup you've ever seen? :D

Shorthand properties using JS object syntax

Is it intentional that shorthand properties are not available when using JS objects to specify CSS rules? For example:

console.log(b('b 1').style);
console.log(b('b: 1').style);
console.log(b.b(1).style);
console.log(b({ b: 1 }).style);

Output:

{ bottom: '1px' }
{ bottom: '1px' }
{ bottom: '1px' }
{ b: '1px' }

Duplicate selector doesn't concat style.

Hi πŸ‘‹ apologies if this is intentional behaviour or if this is an existing issue (I couldn't find anything). I've run into this issue a lot recently as I've started using $nest more and more.

I think the style sheet should just concat. I assume this is tied to bss' mechanism for preventing regenerating duplicate styles across redraws. Maybe the caching mechanism need's to key using the full definition instead of just the selector.

Expected

Duplicate selectors do not prevent non conflicting styles from being applied.

Actual

The same selector cannot be reused, even for non conflicting styles.

Repro

allow way to lift selector specificity

when has something set in b.css using class as selector, it's very easy to override inline bss definitions.

Please see this demo

The li never be blue.

Is there any way to lift selector specificity?

Document how bss handles specificity

Please close if this isn't a concern but I just came across it, and was a bit confused for a sec, might be worth documenting.

m('a' + b.d('block'), { hidden: true }, 'Still Visible')

Makes sense why it happens, and easily solvable.

Flems to reproduce.

Applying global styles.

Is there a recommended approach in bss for applying styles to the body or as top level wildcards?

Error form UglifyJs

Hello,

I am getting a strange error from UglifyJS.
Running this through webpack

Here is the error:

{ Error: 4.714f43602dc9cdd1454a.js from UglifyJs
Unexpected token: operator (>) [4.714f43602dc9cdd1454a.js:29,12]

It points to this section in the bss code:

const cssProperties = ['float'].concat(Object.keys(
  findWidth(document.documentElement.style)
).filter(p => p.indexOf('-') === -1 && p !== 'length'))

which looks fine.

I don't know what might cause this. The code works fine. It just wont minify.

Unit interpolation fails in node

const el = document.createElement('div')

just noticed in a unit test that this line throws an exeption in node when calling bss like this

b({
    backgroundColor: 'pink',
    fontSize: 1.3 // <- no unit
})

while suprisingly seems to work fine

b({
    backgroundColor: 'pink',
    fontSize: '1.3px' // <- with unit
})

not really an issue, but may be helpful to remember in case you want to make it work in node down the line. Hence posting it here.

using bss-react module just for react

I'm make a module bss-react to make bss work better with react, it's a very early idea, the usage is only simple case:

bssReact(`color: red`, 'some', 'external', 'classes')

Or

bssReact({
  backgroundColor: 'black',
  textAlign: 'center',
  $hover: {
    backgroundColor: 'red'
  }
}, 'some', 'external', 'classes')

The restriction here is it cannot chained. Any suggestion for this?

Priority of generated styles

First of all thank you for awesome module!

Steps to reproduce

  1. Create component with bss
  2. Wrap component into mixin that override some styles using bss
  3. Render component and mixed component
  4. Look into generated classes

Expected behavior

We get output like: .component { ... } and .component.mixed { ... }

Actual behavior

Output: .component.component { ... } and .mixed.mixed { ... }

Live example

example

Make shorthands a little magic

I'm thinking it would be nice to put a little magic on the shorthand properties.

Currently it's a bit annoying for collisions of popular properties such as bottom / border and padding / position.

@thomasll came up with the idea of auto-detecting the correct property depending on the value.

This would make it possible to allow both p 10px and p absolute.

What do you think?

v2: Extract shorthands into helpers object

I'm thinking the shorthands are actually better off being added as helpers instead of having them automatically mapped.

I feel there's too much uncertainty with the auto registration resulting from taking all browser registrered property names and mapping them to their shorthand by initials.

I think I'd rather specify them statically in a named export that can be added using .helper().

It would look something like this:

import b, { shorthands } from 'bss'

b.helper(shorthands)

Another one that I'd add in a simliar fashion would be unique values as property names. That would look like this:

import b, { shorthands, valueProps } from 'bss'

b.helper({
  ...shorthands,
  ...valueProps
})

// yay
b`
  absolute
  hidden
  scale(2)
`

POJO style question

Hello @porsager

just stumbled over this:

in the README.md under 'Ways of writing CSS', it says:

JS Objects

b({
  backgroundColor: 'black',
  textAlign: 'center',
  $hover: {
    backgroundColor: 'red'
  }
})

while the only way I could make it work, was actually a POJO / function mix like this:

b({
  margin: '2em',
  backgroundColor: 'black',
  textAlign: 'center',
}).$hover({ backgroundColor: 'pink '})

flems here

I am wondering if this is just a typo in the README.md or if it was actually supposed to work the POJO way, too?

The POJO way of writing css may be advantageous when it comes to media queries:

I am currently working on a little script to provide React-agnostic styled-components and styled-system functionality with lovely bss doing the heavy lifting under the hood. Consider the following output from a styled-system type of function such as space

where this

// (attrs :: Object, theme :: Object?) -> Object
function space (attrs, theme = {}) { /* sausage factory */ }

let spacing = space({
  p: '1px 2px 3px 4px',
  mr: [0, 2, 4, 6],
  ml: [1, 3, 5, 7],
  mb: [0, 2, 4, 6],
  mt: [1, 3, 5, 7]
})

...yields an Object like this (after some tweaking of the original space function):

{
  padding: '1px 2px 3px 4px',
  marginTop: '4px'
  marginLeft: '4px',
  marginRight: '0px'
  marginBottom: '0px',
  $media: {
    'screen and (min-width: 40em)': {
        marginBottom: '8px',
        marginLeft: '16px',
        marginRight: '8px',
        marginTop: '16px'
    },
    'screen and (min-width: 52em)': {
        marginBottom: '32px',
        marginLeft: '64px',
        marginRight: '32px',
        marginTop: '64px'
    },
    'screen and (min-width: 64em)': {
        marginBottom: '128px',
        marginLeft: '256px',
        marginRight: '128px',
        marginTop: '256px'
    }
  }
}

if 'Ways of writing CSS' worked as currently documented, I would be able to just drop the space yield into bss as is, right?

const result = bss(spacing)

as opposed to iteratively calling result.$media(ding, dong) like this:

const { $media } = Object.assign({}, spacing)
delete spacing.$media
let result = bss(spacing)
for (let k in $media) {
 result = result.$media(k,$media[k])
}

... which works just fine, but seems more wasteful. But maybe it isn't under the hood. What do you think?

other flems

Line Height when given a unitless value doesn't return as expected

G'day, love BSS - keep up the good work πŸ™Œ

I'm trying to use a unitless value for line-height (MDN) however bss is adding 'px'.

For example, when I pass in 1.25 as an int or the string '1.25', I am getting 1.25px however I want 1.25 (uses the number multiplied by the element's font size).

Debug mode makes bugs harder to find

I just spent an afternoon tracking down an elusive bug to the following code

<span className={b.fw(600).c('rgba(0, 0, 0, 0.7').class}>{children}</span>

When rules are added with sheet.insertRule, the only effect is the invalid color rule not being applied.

When in debug mode (which was turned on in an unrelated part of the codebase), all subsequent rules are inside the unclosed color rule, which breaks everything except the component containing the bug.

False positives in the px detector

I just noticed that the detection trick would fail for the flex shortcut that can take both plain numbers (for flex-grow) or lengths (for flex-basis).

A user that specifies flex: 2 would expect it to mean flex-grow: 2, not flex-basis: 2px...

There may be other cases where the cache needs to be pre-populated, not sure which ones.

Suggestion: Adopt the j2c v1 backend API (and get automatic prefixes for free)

Hi, @porsager I just notice this thanks to @JAForbes' tweet.

Would you mind adopting the j2c backend API? The general idea is that, rather than having your functions return strings, you pass a backend that accumulates them. So for example

export function selectorBlock(selector, style) {
  return selector + '{'
    + stylesToCss((typeof style === 'string' ? stringToObject(style) : style))
    + '}'
}

would become

export function selectorBlock(selector, style, backend) {
  backend.rule(selector)
  stylesToCss((typeof style === 'string' ? stringToObject(style) : style))
  backend._rule()
}

and

function propToString(style, k) {
  return (vendorRegex.test(k) ? '-' : '')
  + camelCaseToHyphen(k) + ':' + style[k] + ';'
}

would become

function emitDecl(style, k, backend) {
  backend.decl((vendorRegex.test(k) ? '-' : '') + camelCaseToHyphen(k), style[k])
}

The main advantage here is that it allows one to write plugins that decorate the backend, like this prefixing plugin that no one uses currently because I've yet to publish j2c v1 that uses the same architecture.

The prefix plugin supports more than one prefix per browser (FF and Edge have some properties that are exclusively available with a webkit prefix), is IIRC 3KB mingzipped and uses feature detection rather than a list of properties/selectors, etc... like autoprefixer and the inline style prefixer.

The architecture makes it trivial to turn one rule into many (e.g. flex-direction => -webkit-box-direction + -webkit-box-orient) without causing the allocation of extra objects.

Edit I can't English tonight...

Edit2: here's the full feature list: https://github.com/j2css/j2c/tree/3039875258bd69f04a16c51b69ca71361b5d5560/plugins/prefix-browser#features

Edit3: here's the full backend (sink) API.

Prefixer bugs, and other weirdness

In Firefox,

sheet = b({appearance: "none"})
sheet2 = b("appearance: none")
sheet + sheet2
p(sheet.getSheet())
p(sheet2.getSheet())

prints

.bajq6bd1.bajq6bd1{--moz-appearance:none;}.bajq6bd2.bajq6bd2{appearance:none;}
''

--moz-appearance should be -moz-appearance, as should appearance, I suppose.

Also, are you intentionally duplicating the classes? It has an impact on the specificity of the selector, but is probably harmless otherwise.

At last, AFAICT getSheet() is not documented, but it is supposed to behave like that?

v2: letter-spacing auto px

There's a little inconsistency with letter-spacing and auto-px since letter-spacing allows floats as a unit. Bss can't guess when the intention is to have px auto added or if a fraction was actually desired.

A current workaround is to do letter-spacing: calc(2) but I'd like a better solution for v2, either just exclude the letter-spacing property from the auto-px list, or some other more clever thing :P ?

Allow `style` and `class` output to be determined early on in the chain

There's something I really dislike about assigning BSS as style and class (and .toString() TBH) at the trailing end of a multi-line, multi-block chain. Having that stuff visible ahead of time would be good.

What do you think about introducing simple b.class and b.style functions that simply consume an object (or operate as tagged template interfaces like b) and return the corresponding property of the same name?

`$nest` and `$media` not applying style.

Hi @porsager πŸ‘‹

I'm not sure if this a bug or just me misusing the library 😊.

It seems $nest doesn't apply within a $media if there is already a non-empty declaration. See the repro below:

flems

If the $nest is chained without a parent declaration, it works fine:

flems

I am not sure if the generated syntax is correct. But the outputted getSheet shows a comma separated css block. But I think if it's not comma separated, it works fine.

Generated:

@media (min-width: 0px){
    .b69m3411.b69m3411{
        font-family:Helvetica;
    }
    ,.b69m3411 h1{
        color:red;
    }
}

Proposed generation:

@media (min-width: 0px){
    .b69m3411.b69m3411{
        font-family:Helvetica;
    }
    .b69m3411 h1{
        color:red;
    }
}

I hope that's helpful! If I'm doing anything strange please let me know!

Multiline properties should not be parsed as key / value

Eg. the following @font-face declaration fails

b.css({
  '@font-face': b(`
    font-family: 'Titillium Web';
    font-weight: 200;
    font-style: normal;
    src: url('/fonts/Titillium-Web-200.eot');
    src: url('/fonts/Titillium-Web-200.eot?#iefix') format('embedded-opentype'),local('Titillium WebThin'),local('Titillium-Web-200'),url('/fonts/Titillium-Web-200.woff2') format('woff2'),url('/fonts/Titillium-Web-200.woff') format('woff'),url('/fonts/Titillium-Web-200.ttf') format('truetype'),url('/fonts/Titillium-Web-200.svg#TitilliumWeb') format('svg');
  `)
})

Feature Request: Built-in CSS Class Composition

This is something I talked to @fuzetsu about in the Mithril.js Gitter.

I'm coming from using exclusively plain .css files and atomic CSS frameworks like Basscss. Usually, when I'd build a component (in my case, a Mithril component), I just chain a bunch of Basscss classes to style it. bss is great because I'm able to define additional component-specific styles very easily, and not have to go to a separate .css file to define 5 different atomic classes I'd probably only use once.

Here is how I'm using bss at the moment in conjunction with Basscss:

const bssClass = b`
  transition all 0.2s ease
`.$hover`
  background-color red
`;

const StyledBtn = `button.btn.btn-primary.not-rounded.${bssClass}`;

const Btn = {
    view: ({ attrs, children }) => m(StyledBtn, attrs, children)
};

Flems link

While this works totally fine for my purposes, I think it would be nice to have a built-in way to specify classes to compose, perhaps something like this:

const StyledBtn = b`
    $compose btn btn-primary not-rounded
    transition all 0.2s ease
`.$hover`
    background green
`;

Which may produce a className string such as

.btn.btn-primary.not-rounded.bdp4f3o1

for me to use with my component of choice.

What do you think?

Simple integration width vuejs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.