How can i use SGS without every nested div spawning it’s own smaller grid? I get that it’s more powerful than that but for this case, specifically I’d like to set the width of deeply buried paragraph container to span 5 columns of the original .main-wrap div container’s grid.
for example if i do this to my paragraph which is nested 4 containers deep,
p.mynested_para {
#include grid-span(5, 1) /* i want this to refer to the .main container’s grid */
}
it comes out tiny! i’ve been looking through documentation but haven’t found how to do this yet.
You have to provide a context: how many columns are available for this element.
There are two ways:
1. In the grid-span mixin
The grid-span mixin accepts up to four arguments:
Number of columns to occupy.
Index of the column to start with.
Number of columns in the context.
Gutter ratio of the context.
So what you need to do is:
#include grid-span(5, 1, 8)
...where 8 is the number of columns available in the current context.
2. Using the layout mixin
If you have multiple elements to span in one context, it is tedious to mention the context for every of them.
So instead of this:
.foo { #include grid-span(5, 1, 8); }
.bar { #include grid-span(1, 6, 8); }
.baz { #include grid-span(2, 7, 8); }
You can do this:
#include layout(8) {
.foo { #include grid-span(5, 1); }
.bar { #include grid-span(1, 6); }
.baz { #include grid-span(2, 7); }
}
Documentation
Read about these features in more detail here:
https://github.com/at-import/Singularity/wiki/Spanning-The-Grid#context-overrides
Related
I have an ng-repeat in an angular app that could have anywhere between 2 to 5 items and a 20 column susy grid. I want the items to total the full width of the grid so if there are 2 I want:
.card:nth-child(1) {
#include span(10 of 20); }
.card:nth-child(2) {
#include span(10 of 20 last); }
and if I have 5 cards I want:
.card:nth-child(n+1):nth-child(-n+4) {
#include span(4 of 20); }
.card:nth-child(5) {
#include span(4 of 20 last); }
And I need it to work for anything dynamically in between.
Any idea how I can get something like this to work?
It is not possible, since Sass is a preprocessor and won't have knowledge of the DOM.
Is it possible to break out/return early of a Sass mixin? I'd like to do something like this:
#mixin foo($bar: false) {
#if $bar {
// return early without applying any of the styles below
}
color: red;
}
Edit: Please keep in mind that this example is the simplest thing I could come up with that illustrates my problem. In the real world, my code is much more complex and the use case for this is clear.
Sass doesn't really have the concept of "break", but an #if/#else will get you pretty close:
#mixin foo($bar: false) {
#if $bar {
color: green;
}
#else {
color: red;
}
}
From the Lead Sass developer at https://github.com/nex3/sass/issues/378:
The issue is that the more seldom-used control structures exist in
Sass, the harder it is for something with only passing familiarity
with the language to read stylesheets that use those control
structures. That's why it started out with the bare minimum set of
structures needed to do anything: because in many cases it makes sense
to skew towards a smaller surface area of the language rather than
optimal semantics for writing complex code.
I still thinking that #if/#else statements is the easiest and best solution to deal with your problem in Sass but I've created two different breakout mixins to help you and as a challenge:
Play with this mixin first
Breakout mixin without #includes (link)
#include breakout($styles)
$style should be a list of styles separated by spaces, here are the allowed values:
Styles
Common CSS styles separated by spaces and without colon or semicolons, lists of values should be wrapped by brackets:
#include breakout(
color blue // <property> <value>
width (100 * 20px) // <property> <operation with values>
border (1px solid #fff) // <property> <list of values>
box-shadow (0 0 10px 4px #0000FF , 0 0 20px 30px #008000) // <property> <nested list of values>
)
Breaks
Breaks are styles that are compiled if its condition is true, also when the condition is true the mixin ends without returns all styles after the break value
$foo: true;
#include breakout(
break (false color red) // break (<condition> <property> <value>
break ((3 < 2) border (1px solid #fff)) // breaks also support list and nested lists
break ($foo width 10px) // This breaks is compiled because condition is true
color blue // This style isn't compiled because the $foo break ends the mixin
)
Note that the order of the mixin argument list is important because it determines the compiled and not compiled styles if a break condition is true
Breakout mixin with #includes (link)
This mixin is similar to the above but it introduces mixin values for $styles, break-mixin mixin and #content into the breakout mixin to allow use of #includes.
Mixins
If you want to use other mixins into breakout mixin you need to add some code into $styles and add each mixin into a break-mixin mixin.
#include breakout(
mixin foo // mixin <name of the mixin declared into break-mixin arguments>
mixin bar // mixin name should match break-mixin argument
mixin foobar
) {
#include break-mixin(foo) { // Here your mixin or mixins for mixin foo }
#include break-mixin(bar) { #include mixin1; #include mixin2; #include mixin3}
#include break-mixin(foobar) { #include foobar}
}
Mixin breaks
Now you can also use mixin into breaks. Here the order is still important:
$foo: true
#include breakout(
mixin foobar
mixin bar
break ($foo mixin foo) // This breaks is compiled because condition is true
color blue // This style isn't compiled because the $foo break ends the mixin
) {
#include break-mixin(foo) { // Here your mixin or mixins for mixin foo }
#include break-mixin(bar) { #include mixin1; #include mixin2; #include mixin3}
#include break-mixin(foobar) { #include foobar}
}
So for your specific case copy the Breakout mixin without #includes (link) to your scss file or use it as a partial and then add this to your code;
#include breakout(
break ($bar property value) // The break out statement
color red // If $bar != false this will be compiled if not it won't
);
I'm surprised that the #error statement has not been mentioned yet. According to the documentation (emphasis mine):
When writing mixins and functions that take arguments, you usually want to ensure that those arguments have the types and formats your API expects. If they aren't, the user needs to be notified and your mixin/function needs to stop running.
That said, #error may not be suitable for every situation, because it will stop the Sass compilation completely. This makes it unfit for mixins where breaking out is an expected end intended scenario.
Example from the Sass documentation:
#mixin reflexive-position($property, $value) {
#if $property != left and $property != right {
#error "Property #{$property} must be either left or right.";
}
$left-value: if($property == right, initial, $value);
$right-value: if($property == right, $value, initial);
left: $left-value;
right: $right-value;
[dir=rtl] & {
left: $right-value;
right: $left-value;
}
}
.sidebar {
#include reflexive-position(top, 12px);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Error: Property top must be either left or right.
}
I have a 2 column grid and two divs which I both want to span a single column starting in the first column. I want these to stack on top of each other but they are being overlayed on top of each other. Here is the scss:
#first {
background: red;
height: 30px;
#include grid-span(1, 1);
}
#second {
background: red;
height: 30px;
#include grid-span(1, 1);
}
I've fixed it by inserting an additional div between these two divs and using #include clearfix; or alternatively I can fix it by using #include isolate-span(2,1,'both'); on the second div.
Is there a more 'best practice' way of clearing a row like this?
As discussed in this similar question, Singularity doesn't clear your floats for you when you're using Isolation output (isolation being when each float is isolated from one another's position, as opposed to float where they are not).
The short version of that answer is to use the CSS clear property, as explained very well in the Mozilla Developer Docs
Im trying singularity for the first time, and I'm trying to recreate a grid I have. Simple one.
This is a simple structure, for the test:
<header>
header
</header>
<main>
main content
</main>
<aside>
aside
</aside>
<footer>footer, nav, social icons etc</footer>
So in a 12 col grid, the header is full width, the main is 9 cols width, the aside is 3 cols width and the footer is full 12 cols.
Anyway, the inconsistency is this: the header, the aside, and the footer have float:right, but the main is float:left, so it gets out of the flow of the document.
This is the grid:
/* grid */
$grids: 3;
$grids: add-grid(5 at 500px);
$grids: add-grid(7 at 768px);
$grids: add-grid(12 at 1024px);
$gutters: 1/3;
This is the rest:
html, body {
margin: 0;
padding: 0;
height: 100%;
background: #e1e1e1;
color: #333;
}
.container {
min-height: 100%;
margin: 0 auto;
#include background-grid;
}
/* main layout */
header {
#include grid-span(3, 1);
background: red;
#include breakpoint(1024px) {
#include grid-span(12, 1);
}
}
main {
#include grid-span(3, 1);
background: green;
#include breakpoint(1024px) {
#include grid-span(7, 2);
}
}
So the issue is that, it does not respect the flow and it overlaps with the header, like this http://imageupload.maxmendez.net/images/incon.png. The green main, should be below the header.
In order to fix that, I had to do this:
main {
#include grid-span(3, 1);
background: green;
#include breakpoint(1024px) {
#include grid-span(7, 2, $options: 'right');
}
}
Adding options right, seems to clear to the right and fix my issue. Is there a reason that im overlooking as to why the mai is floating left?
Still havent tested in IE, but im worried about compatibility.
It seems as if you are unfamiliar with what the clear property does or how it works. When using the Isolation output method, you need to clear your own floats, something you may not have been exposed to with more traditional Float output method based grid systems/frameworks. A good place to read up on them is MDN's Clear section.
In the example you've provided, header spans the whole grid width. Because the last item in a grid is floated right, the header is likewise floated right. This is to hide any percentage rounding issues with the last item in a row and have them all line up to the right edge. Otherwise, all grid items are floated to the left. Because this item is floated right, in order to clear it's border edge (not have it overlap), we need to tell the next item in the DOM (your main element) to clear items floated right. This will push it below header, creating a new row. Because footer is full width and is therefore floated right, and your aside is also floated right, there is only enough room on the main/aside row for an item of width 100%-width(aside). Because footer is too wide for that remaining area, it drops to the next row without needing to clear its float. That being said, this will only not overlap with main because main and aside are the same height; if main becomes taller than aside, footer will overlap it. To prevent this, you should tell footer to clear things floated to the left, which main is.
While this all sounds fairly complicated, don't be worried about cross-browser compatibility. We have tested Singularity extensively across all browsers, including IE, and it works fine.
If after all of this you are still uncomfortable with the Isolation output method, you can switch to the Float output method. The two have very different mental models; Isolation is about discretely positioning elements in relation to each other whereas Float is more akin to walking across a row on your grid. Keep in mind that if you switch to Float you will then need to use the push and pull mixins to nudge things around the grid.
Hope this helps!
Is it possible to override the default gutter value for a container with base values e.g. like that:
$total-columns: 12;
$column-width: 60px;
$gutter-width: 20px;
$grid-padding: 10px;
So that you would be able to minimize the gutter from 20px to e.g. only 5px, or any other desired value, on demand.
.example{
#include squish(1,1);
li{
#include span-columns(2,10);
#include nth-omega(5n);
}
}
Is it possible via a mixin, would i have to place another container/layout or should i stick with plain CSS to solve that task? Thanks
Update:
To be more specific, i don't look for an exact sizing of the gutter (as far as i read so far, due to rounding, it would be difficult anyway), i just want to minimize the gutter and enlarge the column width indirectly.
https://dl.dropbox.com/u/8578/Boxes.png
At the moment i have squished 3 columns before and after the contained 7 columns and their gutters. So far the columns and its images are too small in width. Therefor i wanted to size down the gutter width and enlarge the column width indirectly.
The Susy settings look that way:
$total-columns: 24;
$column-width: 3%;
$gutter-width: 1%;
$grid-padding: 0;
A container width i haven't set so far since the container is inside a wrapper for the whole page.
.wrapper {
#include container;
overflow-x: hidden;
width:100%;
max-width: 100%;
}
The specific selector for the image matrix shown in the screenshot is the following:
.projects {
#include squish(3,3);
li {
#include span-columns(2,14);
#include nth-omega(7n);
}
}
You need any more details? So would you still recommend to use the with-grid-settings mixin to solve that problem? And is the set-container-width mixin really necessary? Thought if i set up things relative no absolute values should be necessary? Thanks Ralf
Update 2:
Ufff i tried the suggested little secret's approach mentioned in the comments beneath. But so far i was unable get a clean display, more like a messy chaotic "patchwork"... ;) Kind of confusing over all. Basically the articles author recommended 2 steps. First he added -100% margin-right for the content containing element and in the next step pushed the objects back into their places. My last setup in a long line of tries looks like that right now but still no solution in sight.
.example{
#include squish(3,3);
#include with-grid-settings($gutter: 0.1%){
margin-right: -100%;
li{
#include span-columns(6,18);
#include nth-omega(3n);
#include pre(9);
}
}
}
The margin-right i've placed within the with-grid-settings mixin in the containing element for "li" like suggested. But the question is where to place the pre mixin and especially which numbers it should contain (has the number to take the squish number in consideration too)? Is it the same value for all li or is a for loop necessary to push the images to individually to their horizontal positions ? And is the mixin order within the li element correct? Does it matter where it is placed? At the end or inbetween span-columns and nth-omega? Over all i am still confused. Grids, image matrices and Susy still keep my brain spinning. :/
Update 3:
Thanks! I finally got it working. In the end i would have two questions about my solution:
.test{
#include with-grid-settings($gutter: 0.1%){
li{
margin-right: -100%;
float:left;
#include span-columns(6,18);
#include nth-omega(3n);
$count:0;
#for $i from 1 through 9 {
&:nth-child(#{$i}) {
$count: $count + 1;
#include push($count);
#if $count == 2{ $count: 0;}
}
}
}
}
}
Would there be a more elegant way for the layout of the for loop? And second why is it possible that this version as well as a version when i comment out the $count: $count + 1; statement lead to the same visual result? Actually commented out there isn't a second and third count up for the push variable. Any idea why that works anyway without the $count: $count + 1;? Thanks!
Update 4:
I played around a little bit more and as it turns out the following version works like a charm. It seems the $count variable isn't necessary at all, as well as the incremental growing of the value contained within the push/pre mixin. A simple 0 did the trick.Thanks again for the help!!!
.test{
#include with-grid-settings($gutter: 0.5%){
li{
margin-right: -100%;
#include span-columns(6,18);
#include nth-omega(3n);
#for $i from 1 through 9
{
&:nth-child(#{$i})
{
#include push(0);
}
}
}
}
}
Update 5
I already mentioned in my last comment beneath that the example shown in update 4 hasn't worked as good as it supposed to work at the first look. I tried now to completely rebuild the suggestion from the Palantir article. Underneath is the scss parts for the 7x4 as well as the 3x3 matrix shown in the video: https://dl.dropbox.com/u/8578/matrix.mov
.7x3{
#include with-grid-settings($gutter: 0.25%){
li{
margin-right: -100%;
#include trailer(1);
#include span-columns(2,14);
#include nth-omega(7n);
$y: 0;
#for $x from 1 through 28
{
&:nth-child(#{$x}){
margin-left: ($y * columns(2,14)) + ($y * gutter(14));
$y: $y + 1;
#if $y > 6{
$y: 0;
}
}
}
}
}
}
.3x3{
#include with-grid-settings($gutter: 1%){
li{
margin-right: -100%;
#include trailer(1);
#include span-columns(6,18);
#include nth-omega(3n);
$j: 0;
#for $i from 1 through 9
{
&:nth-child(#{$i}){
margin-left: ($j * columns(6,18)) + ($j * gutter(18));
$j: $j + 1;
#if $j > 2{
$j: 0;
}
}
}
}
}
}
At the first look the matrices look broken but if you take a closer look at the inspector within the video, it appears that each element is pushed to its correct horizontal position in both matrices. Only problem is that each li is contained in separate lines. This is the closest version i was able to get. :/ Right now i am out of ideas how to put those pieces together to get to a proper matrix. I tried more or less ever possibility with float as well as display properties. But no luck. Anyone has a hint perhaps?
You can use with-grid-settings() (reference docs) to wrap your code:
Since you don't want to change the actual container width, we can leave that alone. It's up to you if you want the .projects padding (from squish()) to be influenced, but I'm going to assume you don't. Here it is, just changing the $gutter-width for the lis:
#include with-grid-settings($gutter: .5%) {
li {
#include span-columns(2,14);
#include nth-omega(7n);
}
}
That's it. If you do want anything else to use the adjusted settings, simply move them inside the mixin.