Selectors
In order to apply constraints to elements, you first need to select and observe them from the DOM. GSS supports the following basic selectors. Live example.
Elements
GSS supports the *
selector meaning all elements of the page will be selected.
Classes
Using the element’s class attribute <div class='className'></div>
this selector will select
all elements that have the class className
.
ID
Combinators
Combinators are used to combine basic selectors to allow more fine grained selection of elements. Live example.
The following combinators can be use in GSS:
Union
For all div
elements and elements having the .className
class, a width
of 100 will be constrained. div
elements
having the .className
class will be selected only once.
All descendant elements
Select all elements having the className
class define that are descendants of a div
element.
Attribute selector
Select all div
elements that have the className
class.
All child elements
For each div
element, select its direct child’ element if the child element has the className
class.
Next sibling element
Select the direct succeeding sibling elements of all div
if those siblings have the className
class.
All direct sibling elements
Select the previous and next direct sibling elements of all div
if those siblings have the className
class.
All succeeding sibling elements
Select all succeeding sibling elements of div
that have the className
class.
All sibling elements
Select all preceeding and succeeding sibling elements of div
that have the className
class.
Performance consideration
For GSS selectors that are supported by CSS, GSS will use the CSS native selectors. For non CSS native selectors, GSS will filter the collection of elements selected by native CSS selectors. Performance wise, it is therefore preferable to use native selector as much as possible.
Combinators limitation
Combinators requires a selector on both side of the combination. For example the following is not currently supported:
You can use the *
to get the same results
Reverse Combinators
For parent-child selector, the reverse combinator !
allows you to reverse the selector relationship
to child-parent. For sibling selectors, the reverse combinator !
allows you to go up in the DOM for
the selection. Live example.
All parent elements
Select elements with the .className
class that are parents of a div
element.
Direct parent elements
Select elements with the .className
class that are direct parents of a div
element.
Previous sibling element
Select the direct previous sibling elements of div
elements having the className
class.
All preceeding sibling elements
Pseudo-classes
When using selectors, GSS creates a collection of matching elements and then iterates over those elements to apply the constraints you’ve defined. Pseudo-classes allows you to further select an element within that collection.
The following pseudo-classes are supported in GSS.
:next element in the collection
The div
selector will create a collection of matching div
elements. The pseudo-classes :next
in this example will select
the next div
in the collection relative to the current div which is represented by &
.
:previous element in the collection
Selects the previous element in the collection.
First element in the collection
Selects the first div
found and add a constraint of 100px on the size
.
Last element in the collection
Selects the last div found and add a constraint of 100px on the size
.
Special pseudo selectors
GSS provides the following special pseudo selectors:
Parent selector ^
As we’ve seen previously, GSS will iterate over all selected elements to apply contraints.
When using the ^
pseudo selector, you are asking GSS to refer to the parent ruleset element.
Live example.
You can chain pseudo parent selector. In the following, GSS will access the current className
parent’s parent which in
this case would be a section
element.
As previously mentionned it is important to understand that the parent pseudo selector will select
an element according to the ruleset scope and not the DOM. As you can see in the next live example, the div
are
constrained against their ruleset parent element and not their DOM parent. Live example.
this selector &
In this example, the line-height of the selected element will by 10px more than its own font-size.
::window selector
The ::window
selector gives you access to the visible part of the page in the browser. The ::window
width and height don’t take
into consideration scroll bars.
Scrolling the page will not re-calculate constraints using the ::window
so you need to keep this in mind when constraining elements
in relation to the ::window
pseudo selector.
In the next example, the gray div
will be centered with ::window
but as you can see scrolling don’t have any
effect on its position. Live example
Global scope selector $
The global scope allows you to select elements from the root of the DOM three when selecting elements within rulesets. The root element is the element in which you instantiate the GSS engine.
Selector within rulesets
Using selectors within rulesets is the equivalent of using the descendant combinator. In the following example,
a constraint on the .className
element will only be define if that element has a descendant element with an id equal to #elm
.
Live example.
Global combinator $
When using the $
combinator, the selector will search elements from the root of the document ignoring the nesting of rulesets:
Parent combinator ^
When using the parent ^
combinator, the selector will use the element selected in the parent ruleset to perform its search:
In this following example ‘^’ will move up to the current .container
element and will search its descendants
for an element with elm
id. Live example.
Selector splat
Selector splat enables you to select elements having a sequence number in their ID or class name. Live example
The splat sequence can start at the number you want:
You can chain splat selectors like this for ID or class names having multiple number sequences in them:
Selectors and the DOM
The collection of elements built from selectors is built according to the DOM elements order and not in the order in which you positionned them with GSS.
For example, if you have GSS constraints that positions all section
elements to appear before div
elements, the following example
will not take that positionning into account when using the :next
pseudo-class.
In this case, if some div
comes first in the DOM, they will be added to the collection of selected elements before section
elements. So
&:next
can return either a section
element or a div
element depending on the DOM order.
Depending on your intention, this can make total sense but keep in mind that these constraints will be applied base on the DOM order.
Selector specificity
Selector specificity is not supported in GSS.
“…constraints can be used to specify declaratively the desired layout of a web document. They allow partial specification of the layout, which can be combined with other partial specifications in a predictable way. They also provide a uniform mechanism for understanding layout and cascading.” Greg J. Badros
Let’s take the following example,
With CSS, the selector specificity would set the div
width to equal the #someElm
width
since the ID selector has a higher score than class and tag selectors.
With GSS, these three constraints will be evaluated and since later constraints overcomes previous ones, the width of the
div
in this example would be equal to the section
width. So if you want to give higher priority to #someElm
you can set a
higher strength on it:
Plural binding
When two selectors are used in a constraint, every element will be paired with element in another collection in order of appearance.
Let’s say you have the following DOM elements:
What happens if you do declare the following constraint on these elements:
GSS will do plural binding between these elements, which means it will pair elements together in order to contrain them together. Plural binding will give the equivalent of the following constraints:
Section with s3
id has no article to pair with, so its width will not be constrained.
By following the same logic, using the same selector on both sides of a constraint, makes every element only pair with itself:
Two selectors per expression
GSS limits to two the number of distinct selectors in a GSS expression. As for now the following is not supported:
This limitation only applies for distinct selectors. Example below works because #div1
and #div2
are re-used.
The workaround would be to use an intermediate variable or VFL expression:
Read next
If you come from the CCSS guide continue your learning of CCSS
Learn how to use CCSS constraints
GSS provides conditionnal statements to allow you to do responsive design. Read our @if @else guide to learn more.
With only CCSS constraints at your disposal, constraining common layout scenarios quickly becomes tedious. Read our VFL guide to learn how to more efficiently constrain your layout.