Coder Social home page Coder Social logo

engine's Introduction

GSS engine Build Status

Cross-browser testing status

Compiles and runs Grid Style Sheet (GSS) rules. GSS is an implementation of Badros & Borning's Constraint Cascading Style Sheets, enabling far better layout control through building relational rules between different elements.

GSS supports the following syntaxes for defining layout rules:

Please refer to http://gss.github.io/ for documentation and usage instructions.

engine's People

Contributors

bergie avatar d4tocchini avatar inviz avatar jemgold avatar johnrandom avatar jonnor avatar kkirsche avatar nathanstitt avatar paulyoung avatar ritschwumm avatar subtlegradient 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  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  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

engine's Issues

Auto vendor prefix

It's best to minimize how hard the solver is pushed, so:

.post {
      -webkit-column-gap: == [baseline];
         -moz-column-gap: == [baseline];
              column-gap: == [baseline];
    } 

creates 2 unused constraints & 2 unused constraint variables. No good.

Definitely better to:

.post {
      column-gap: == [baseline];
    } 

and have GSS auto prefix during the display pass, after cassowary has solved.

Normal CSS props not working correctly

Regular CSS should work within a GSS style sheet like:

#css-only {
  color: purple;
}

As well as with nested rules:

.outer, .outie {
  #css-inner-dump-1 {
    width: == 100;
    height: 100px;
  }
  .innie-outie {
    #css-inner-dump-2 {
      height: 200px;
    }
  }
}

But, the hard part is getting it to work within @if @else conditionals...

Threshold for triggering screen resize calculation

There are some situations where screen resize calculation may not be desired when the size change is only a small one.

Example: when viewing a page on Chrome for Android and scrolling down, the navigation bar will disappear from view (triggering vertical resize), then when scrolling upwards again, the navigation bar will again come into view (triggering another vertical resize).

It seems there is no way to control this behavior, and the resize calculations can make GSS layouts with viewport constraints a bit "jumpy". It would be good to be able to ignore resizes on a given axis when the change is smaller than X%.

Example (see how the text sizes change):

screenshot_2013-12-20-12-24-59
screenshot_2013-12-20-12-25-07
screenshot_2013-12-20-12-25-17

What license is this published under?

Maybe I'm missing something, but I don't see any license terms mentioned here or on your website. Could you please add one, and hopefully a BSD or MIT license? Thanks!

roundBeforeSet by default

Half-pixels, blurry wtf

If roundBeforeSet is true by default, we'll avoid inflicting blurry text onto the web. Can then set it false for the page when it makes sense (and/or for specific elements?).

Better failure mode with some legacy IE versions

The GSS website renders perfectly on IE11:

screenshot 2014-03-05 at 16 07 07

On IE8 we have a nice failure mode where only the CSS gets rendered, so users of this crappy legacy browser can read everything, but don't get the layout. This is acceptable:

screenshot 2014-03-05 at 16 00 11

However, IE9&10 both have the issue where they render nothing:

screenshot 2014-03-05 at 16 04 27

screenshot 2014-03-05 at 16 06 14

We should investigate whether we can either:

  1. Fix GSS on those so that they will be like IE11
  2. Disable GSS on those so that they will have the nicer failure mode that you get with IE8

Units

Right now GSS assumes pixels for most things, and doesn't work for much else.

No License

As there's no license on the repository, it's not clear to people that it's actually open source (no license=default restrictive copyright). Please add one so it's clear that we're actually able to do cool stuff with it :)

Parse error: property colon in ruleset

breaks when a space is between property and :, as with width below:

button {
    width : == ::[intrinsic-width] !require;
    height: == ::[intrinsic-height] !require;
}

Full transform support - rotate, skew, scale, anchor-point

Local-to-global issues

Will be tough to minimize API surface and allow relative positioning & sizing across transform contexts. For example"

#box {
  rotate: == 45;
  center-x: == ::window[center-x];
  width: == 100;
  #inner-box {
    rotate: == 45;
    width: == 100;
    center-x: == ::window[center-x];
  }
}

Are #box and #inner-box centered within window? Would prefer not to have to fiddle with transform-origin. toLocal() & toGlobal() property functions would be nice to use in constraints, but, scaling or rotating by a constraint variable make constraint expressions go nonlinear, assuming the constraints span transform contexts...

Assuming global position context so that the above #box and #inner-box would indeed be centered sounds nice... But, sizes should not be assumed orthogonal to the global transform context, otherwise the two above boxes would be scaled by different amounts to maintain a horizontal width of 100px parallel to the top of the screen. And, unfortunately, center-x is an expression of size & position. What about left top, right & bottom? Can of worms.

Anchor point

Might as well throw in anchor-point while I'm at it. I've always preferred the semantics of Adobe After Effects's "anchor-point" over "transform-origin":

  • align by anchor-points vs. align by transform-origin
  • #hole[center] == #wall[anchor-point] vs. #hole[center] == #wall[transform-origin]

Setting the transform prop

Do the math before setting matrix3d or add props other than matrix3d? Probably stick with doing the matrix math manually.

Gotcha - display:none w/ intrinsic measurements

When the page loads the layout is thus:

screen shot 2014-03-28 at 9 59 07 am

Then, given a tug on the window size (any which way), gss lays out correctly:
screen shot 2014-03-28 at 9 59 09 am

See failing case at: http://jasonkuhrt.github.io/sandbox/

The gss code in question is:

body, html {width: 100%; height: 100%; margin: 0; padding: 0;}

html {
  font-size: 24px;
  text-align: center;
  font-family: Helvetica;
}

.box {
  center-x: == ::window[center-x];
  center-y: == ::window[center-y];
  width: <= ::window[width] / 2;
  height: == ::this[intrinsic-height];
  background: red;
  color: white;
}

Leaking 'exports' into global

I believe the offending code is related to the snippet below, but what is happening is that, when including gss as a plain tag in a project that also has amd components, exports is getting added to window which prevents modules that check for both commonJS and AMD fail if they look for the existence of exports as does PIXI.js, for example. (I'm guessing scope == window when this runs).

// For Node...not that I'm bitter. No no, not at all. Not me. Never...
if (typeof require == "function" &&
    typeof module != "undefined" &&
    typeof load == "undefined") {
  scope.exports = c;
}
// ...well, hardly ever.

Support // for comments

Syntax highlighting for GSS is currently provided by LESS. LESS uses // for comments, so the Cmd+/ keyboard shortcut for commenting will insert //s rather than CSS's /*...*/. This makes commenting out sections of code painful.

In the interests of not re-inventing wheels that don't need to be reinvented, it would be nice if // was supported by the GSS engine.

Is GSS's syntax otherwise a subset of LESS, or does it make sense to make GSS-specific bundles for Sublime/TextMate/et al?

Threshold for triggering screen resize calculation

There are some situations where screen resize calculation may not be desired when the size change is only a small one.

Example: when viewing a page on Chrome for Android and scrolling down, the navigation bar will disappear from view (triggering vertical resize), then when scrolling upwards again, the navigation bar will again come into view (triggering another vertical resize).

It seems there is no way to control this behavior, and the resize calculations can make GSS layouts with viewport constraints a bit "jumpy". It would be good to be able to ignore resizes on a given axis when the change is smaller than X%.

Example (see how the text sizes change):

screenshot_2013-12-20-12-24-59
screenshot_2013-12-20-12-25-07
screenshot_2013-12-20-12-25-17

Support "_" in VGL @grid-template directives

Using _ as a zone in VGL silently breaks the layout. (Everything disappears.) Since the purpose of VGL is to design layouts in a visual way, _ would be a good character to use for a zone that doesn't accept content.

Since it doesn't accept content, this character would ideally be able to be used in multiple non-contiguous places in a single layout. Since VGL compiles down to VFL, I'm not sure if this is feasible, but it would be useful.

Using component.js

I am a little confused about component support. Happily for me you have chosen to use it but I didn't see simple component integration for worker.js. I am currently manually storing the worker file under /dist/, however, if I am installing from component this should be taken care of automatically?

You are also missing component install instructions at http://gridstylesheets.org/usage/

@put sugar for @horizontal + @vertical

VGL requires a lot of duplicate lines, e.g:

@h |[selector]| in("virtual-id");
@v |[selector]| in ("virtual-id");

Since grids specify both horizontal and vertical position, there should be sugar to shorten this into something more readable. @fit could be a good choice; it's both short and descriptive. @put would also be quite readable.

Does it make sense to skip pipes for this shorthand? This seems ideal for most cases:

@put [selector] in("virtual-id");

How do you handle multiline text?

I've been prototyping with Cassowary to do UI layout but I've been stuck at the point where you need to have multi-line text.

Since you cannot express text wrapping as a linear constraint, you cannot really know the height of the text based on its width within the system. One idea is to encode an estimate like height = num_characters * constant * width, run the solver, then compute the exact text height, push it again in the solver and repeat until it converges (or not ...).

Unrelated, but here's an example of writing Facebook's image viewer using constraints (resize the window): http://fooo.fr/~vjeux/github/cassowary-js-refactor/demos/layout/layout.html

Load AST directly from Javascript

Hi!

I would like to load the AST without parsing the DOM, just with a function call. I think this should just be a matter of calling StyleSheet constructor but I have some difficulties to understand how exactly this should be done. What would be the right entry point?

Support for `>` selector

Given this template:

    <address>
      <figure
        class="avatar"
        style="background-image: url('http://lorempixel.com/400/400/business');"
      ></figure>
      <a>@somebody<a/>
    </address>

This selector doesn't work as expected:

address > figure {
    width:== 100;
    height:== ::[width];
}

However, it works fine without the >

Implicit Connections w/ Containment

I know you're working hard to document this project more, and I'm inspired by what I've seen so far.

I can't seem to get a simple implicit connection in VFL working.

For example, with:

<div id="container">
  <div class="button" id="button1"></div>
  <div class="button" id="button2"></div>
  <div class="button" id="button3"></div>
  <div class="button" id="button4"></div>
</div>

adding:

@h |-[#button1]-[#button2]-[#button3]-[#button4]-| in(#container) gap(10);

works as expected.

However adding:

@h .button in(#container) gap(10);

gives unexpected results. The documentation on VFL says more constraints are needed to make these examples work, but I'm at a loss as to what those would be in this case.

I'd appreciate the help, and I'm eager to contribute once I've wrapped my head around this!

Query Scope Gotcha

Currently, query scopes are only inherited in rulesets (aka blocks), which leads to confusion when querying for elements...

If there are 10 .box's on a page, 3 of which are inside #item, then the following creates 3 constraints:

    #item {
        .box {
            width: == 100;
        }
    }    

whereas, the following creates 10:

    #item {
        .box[width] == 100;
    }    

Should all the queries be lexically scoped? Then could have a way to reach out of scope & query from root...

@elif directive

Consider implementing @elif as an alias for @else to make if/elif/else blocks easier to read.

(@else condition isn't terrible, but implementing an alias should be cheap on the parser side and make it easier for programmers experienced in other languages to avoid a context switch when moving to GSS. One less gotcha = better dev experience)

Basic syntax question

Why does the following code not work:

.a1[width] == [X];
.a2[width] == .a1[width];
[X] == 20;

The second line is the one that breaks it with the error "bindRoot:: only one multiquery per statement ".

Also is there an api doc describing what exactly is allowed and how to use the basic css features (fonts, comments, colors, etc)? The articles on the webpage do not provide a very clear definition of the allowed operators and syntax.

Validate the constraints

In constraints we should not allow selectors on both sides of the constraint, except in the following cases:

  • The selector on both sides is the same (i.e. referencing a dimension of the same element)
  • The selector is for an ID (so there can be only one)

Normal CSS doesn't work within conditionals

Normal CSS within an @if @else conditional is ignored. For example:

.post {
  @if ::[height] >= 500 {
    color: blue;
  } @else {
    color: red;
  }
}

The conditional values of .post's color are ignored.

Nested Conditionals

Currently, @if @else conditionals cannot be nested like so:

@if ::window[width] >= 960 {
  .box {
    @if ::[width] < 700 {
      height: == 200;
    }
    @else {
      height: == 400;
    }
  }
}

Syntax highlighting for Sublime+TextMate

There are too many conflicting syntaxes in GSS (VGL/VFL/CCSS/CSS). As a result, it's easy for novice authors to make mistakes conflating multiple forms. For instance:

#id {
    height: == #other[height]; /* height is a CSS property, so the colon is neccessary
    ::[height] == #other[height]; /* using GSS attribute syntax, placing a colon before the equality would be invalid */

    @horizontal <"variable_name"[right]> #id <"other_variable_name"[left]>; /* uses <>s around the points */
    "variable_name"[right] == "other_variable_name"[left] - 500; /* no <>s or :s in this CCSS statement */

}

It would be awesome if the languages could be simplified and standardized to follow a consistent mental model (so authors would never fall into this pattern of mistakes). Barring that, there needs to be a GSS bundle for TextMate/Sublime that will highlight common syntactical errors so authors can find them before they cause confusion at runtime.

Contextual Conditionals do not work above nested rulesets

Non-contextual conditionals work as expected. The following example works as it should:

@if ::window[width] > 960 {

  .section {
    height: == ::[intrinsic-height];    
    .post {
      right: == ::window[right] - 100;
      left: == ::window[left] + 100;
      top:>= ::window[top];
    }
  }

}

@else {

  .section {
    height: == ::[intrinsic-height];
    .post {
      right: == ::window[right] - 10;
      left: == ::window[left] + 10;
      top:>= ::window[top];
    }
  }

}

But, contextual conditionals currently only work one level above leaf-node rules. So, the following does not work:

.outer {
  @if ::[width] < 700 {
    .inner {
      height: == 200;
    }
  }
  @else {
    .inner {
      height: == 400;
    }
  }
}

A possible work around, assuming .outer's are parents of .inner's, is to flatten everything within the contextual conditional:

.inner {
  @if ::parent[width] < 700 {
    height: == 200;
  }
  @else {
    height: == 400;
  }
}

Allow constraints based on element index within parent

I would be cool if we could use elements' zero-based index within their parent in the RHS of constraints. Combined with slightly more sophisticated math functions this would let you do some fun things.

For example, given the following HTML...

<ul>
  <li class="box">...</li>
  <li class="box">...</li>
  <li class="box">...</li>
  <li class="box">...</li>
  <li class="box">...</li>
</ul>

...and the following hypothetical GSS...

[col-width] == ::window[width] / 3 !require;
@chain .box height();

.box {
  width: == [col-width];
  left: == (::[index] mod 3) * [col-width];
  top: == floor(::[index] / 3) * ::[height]
}

The boxes would form a wrapping grid of three columns...

+---+---+---+
|   |   |   |
+---+---+---+
|   |   |
+---+---+

Then you could add a CSS transition rule like this...

.box { transition: transform 0.3s ease; }

...and when the element order in the DOM changed, either due to a reordering of the list elements, or the addition/removal of items, they would all animate into their new positions.

Choice within solution domain

This is really a question, although it can be seen as something to include in the website more explicitly.

When there's a range of possible solutions that do not break any constraint, does it implicitly optimize for a certain property? E.g. will element size properties always be as large as allowed?

Likewise, if e.g. a size related property is constrained to be above some value v, will this library try to maximize that value? minimize it? arbitrarily pick the first solution it finds? is it uniform across all variables or does it enforce special preferences to some but not others...

Thanks!

Does not work when used in Polymer.

<link rel="import" href="../bower_components/polymer/polymer.html">
<script>
  GSS_CONFIG = {
    worker: "../bower_components/gss/dist/worker.js"
  }
</script>
<script src="../bower_components/gss/dist/gss.js"></script>
<polymer-element name="polymer-greeting"  attributes="">
  <template>
    <style>
      /* styles for the custom element itself - lowest specificity */
      :host { display: block; }
      /*
      style if an ancestor has the different class
      :host(.different) { }
      */
    </style>
    <style type="text/gss">
      h1[line-height] >= 16;
    </style>
    <h1>{{ greeting }}, {{ greeting }}!</h1>
    <span>Update text to change the greeting.</span>
    <input type="text" value="{{ greeting }}">
  </template>
  <script>
    Polymer('polymer-greeting', {
      greeting : '\'Allo'
    });
  </script>
</polymer-element>

The script "gss.js" is downloaded, but it does not detect <style type="text/gss">.

component_build wipes the files included in component.json.files (see vendor/)

@bergie can you check this one out? Kept noticing the files for the polyfills in vendor/ getting set to blank a .js file, they happen to be the only ones in listed as files in the component.json. Thought it was a TextMate2 bug, but looks like it's the grunt exec command during the build.

I'll manually copy back the contents of the polyfills files, let me know if you get same thing.

Take scrollbar into account on viewport measurements

When you have constraints based on viewport size, we need to take the possible scrollbars into account when measuring the viewport size. This is not an issue on OS X or mobile platforms where scrollbars don't take space, but on platforms like Windows and Chrome OS this is a problem.

Currently on Chrome OS elements sized by rules like:

.slide[width] == ::window[width];

get a little sideway scroll which is annoying. Demonstration with a position: fixed element:

screenshot 2013-11-15 at 10 46 44
screenshot 2013-11-15 at 10 46 49

(this screen shouldn't scroll sideways)

A quick workaround that is acceptable in some cases is to hide the scrollbar with CSS:

::-webkit-scrollbar {
  width: 0px;
  height: 0px;
}

But preferably this is something that the GSS engine would take into account in the measurement phase when:

  1. There are constraints using ::window[width] or ::window[height]
  2. There is enough content that a scrollbar would be shown (i.e. total height of page is greater than viewport height)

Here are some ways to measure the scrollbar:

Config for FOUC

Layout flash is annoying, minimize boilerplate with a config flag would be nice. Otherwise, must repeat:

    html = document.getElementsByTagName("html")[0];
    GSS.once("display", function() {
      classie.add(html, "app-ready");
      classie.remove(html, "app-not-ready");
    });

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.