I have a small project, where i first tried Zurb Foundation framework, heavily using SASS variables for customization, and i got one problem.
I use their block-grid extensively, and i need to change $block-grid-default-spacing: variable value to rem-calc(2), but only inside a #gallery element, and leave it at default value elsewhere.
If it helps, i use simple code for my gallery (with some irrelevant Smarty templating)
<section id="gallery-container" class="row">
<ul id="gallery" class="clearing-thumbs small-block-grid-2 medium-block-grid-3 large-block-grid-4" data-clearing>
{foreach from=$offer->photos->get() item=photo}
<li>
<img src="{$photo->image->thumb(true, 295, 230, 5)}" alt="{$offer->title->get()}"/>
</li>
{/foreach}
</ul>
</section>
From the docs on the Foudation page, I think they have a mixin that is available to create your own block-grid. The following was take from http://foundation.zurb.com/docs/components/block_grid.html:
.your-class-name {
#include block-grid(
// This controls how many elements will be on each row of the block grid. Set this to whatever number you need, up to the max allowed in the variable.
// Available options: 1-12 by default, and false.
$per-row: 3,
// This controls how much space is between each item in the block grid.
// Use a variable or any pixel or em values.
$spacing: $block-grid-default-spacing,
// This controls whether or not base styles come through, set to false to leave out.
$base-style: true
);
}
Using block-grid mixin turned out to be a great idea that solved my problem. That's how my code looked like in the end:
#gallery
#media #{$small-up}
+block-grid(2, rem-calc(3))
#media #{$medium-up}
+block-grid(3, rem-calc(3))
#media #{$large-up}
+block-grid(4, rem-calc(3))
Related
I'm completely new to SCSS and I'm trying to set a background color to all items of a selector.
My css selector is the following, and returns all items (of two seperate UL lists)
#g-showcase .g-menu-item
I set a color array as:
$colors: #fad941, #ffffff, #e02520, #a6a6a6, #c6c6c6, #e02520;
I would like to iterate over my selector results and set a unique color from my color array (which could be larger than the above).
I started playing with some code, but I tackled it incorrectly, as I'm iterating over colors and not over selector items. (Don't know how to do that :( )
#for $i from 1 through length($colors) {
#g-showcase li:nth-child(#{length($colors)}n+#{$i}) {
background: nth($colors, $i)
}
}
How could I achieve the desired result?
Thank you !
S.
The problem you have is - as far as SASS is concerned - it's ignorant to how many li items your HTML code has, it's a pre-processor that never really see's the DOM, so it wouldn't know when to stop generating CSS
I assume what your looking to do is have the ability to select which color each li item has set as it's background, rather than as you currently have it, which is applying colors in the order they appear in the color array.
To do this you could add some additional markup to you HTML to give the generated CSS and slightly tweak how your creating the array, using a map instead. You might be looking to avoid polluting your HTML will erroneous mark-up, but the below would work.
$colorz: (
foo: #f24162,
bar: #591240,
fee: #4c5573,
fum: #6fa0a6,
eye: #71d9d9
);
#each $pointer, $bgcolor in $colorz
{
#g-showcase li[pointer="#{$pointer}"] {
background: $bgcolor;
}
}
<ul id="g-showcase">
<li class="g-menu-item" pointer='bar'>The quick</li>
<li class="g-menu-item" pointer='foo'>Brown Fox</li>
<li class="g-menu-item" pointer='fee'>Jumped over</li>
<li class="g-menu-item" pointer="bar">the lazy</li>
<li class='g-menu-item' pointer="eye">dog</li>
</ul>
<ul id="g-showcase">
<li class="g-menu-item" pointer="fum">...and other exciting stories</li>
<li class="g-menu-item">that you hear from time-to-time</li>
</ul>
Note The above wont 'run' as it's sass, so there's a working version over on CodePen http://codepen.io/anon/pen/GJLXMq
Given the following HTML structure:
<div id="a">
A
<div id="b">
B
</div>
</div>
...and the following Singularity SCSS:
$grids: 6;
$gutters: .1;
$gutter-styles: 'split';
div#a {
#include grid-span(5,2)
}
div#b {
// #todo: position and width.
}
...I want to create a layout like this, where B is pulled left, out of its container A, by 1 column, and spans the 2 leftmost columns:
-----------
| A |
----- |
| B | |
----- |
| |
-----------
Of course I can do the math myself, but I feel like this should be possible using Singularity mixins and functions (after all, that's why I'm using a grid framework :-)) However, I can't get the dimensions and positioning of B correct.
Which Singularity mixins and/or functions do I use to set the width (column span) and position (negative margin-left) of div#b?
The answer highly depends on what flow you want inside the #A block.
Keeping the flow
The simpliest thing to do is to pull the #B block outside with a negative margin.
To do that, you should not use the grid-span() mixin. Instead, use the width and margin CSS properties. Values for those properties can be calculated with the column-span() and gutter-span() helper functions.
Those helper functions accept the $grid argument which stands for grid context. You should provide the grid context of the #A block, which is one column less than the main grid.
$grids: 6
$gutters: .1
$gutter-styles: 'split'
$a-columns-width: 5
#a
+grid-span($a-columns-width,2)
overflow: visible
#b
width: column-span(2, 1, $grid: $a-columns-width)
margin-left: - column-span(1, 1, $grid: $a-columns-width) - gutter-span($grid: $a-columns-width)
Please have a look at the demo: http://sassbin.com/gist/6676220/
Removing #B out of the flow
But the #B block is not taken out of the flow. It still occupies the whole width of the #A block, so you can't put anything to the right of #B.
If you need to put some text and stuff to the right of #B, you should consider using another approach. Absolute positioning is what comes to my mind.
The solution will be more complicated. If you want me to come up with one, please explain your task in more detail. Provide a graphical template, maybe.
You will also have to use some trick to prevent #A's content from being covered by #B.
Flat HTML structure makes things simple
Also, why do you need the nested structure (#B inside #A) in the first place? If you make the structure flat, it becomes plain simple to position the blocks:
#a
+grid-span(5,2)
#b
+grid-span(2,1)
margin-top: 4em
Demo: http://sassbin.com/gist/6676193/
#A's content appearing under #B is still an issue though.
PS If you're not satisfied with the answer, please explain the task in more detail and provide a graphical illustration of the desired page with all #A's contents.
Something like this seems like what you are looking for: http://sassmeister.com/gist/6663743
I have a question. So in a mixing I am making a reference to the parent selector "&". This works as long as the mixin is not nested. Is there a way to to detect if the mixing is being used in a non nested scenario, or to check if "&" is null?
This works when the mixin call is not nested
=myresponsiveMixin($media)
#if $media == small {
#media only screen and (max-width: $break-small)
#content
#else if $media == medium
#media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
#content
This works great when the mixin call is nested, but will not resolve '&' when not nested
=myresponsiveMixin($media)
#if $media == small {
#media only screen and (max-width: $break-small)
.classInHTMLToAllowMediaQueries &
#content
#else if $media == medium
#media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
.classInHTMLToAllowMediaQueries &
#content
So the question is, if there is a way to be able to check the value of parent selector "&", so I can cover all bases in a single mixin?
#mixin does-parent-exist {
#if & {
.exists & {
color: red;
}
} #else {
.doesnt-exist {
color: red;
}
}
}
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-script
You're trying a wrong solution to solve your issue.
Have a look at how this problem is addressed in powerful SASS frameworks. Let's take Susy by Eric Meyer as a great example.
Let's imagine you've got the following HTML:
<div class="container">
<div class="parent">
<div class="child">
Bla bla
</div>
</div>
</div>
When you call a mixin for the first time, you're doing it simply (the code is in the indented .sass syntax):
$total-columns: 8 // Declaring a varible that will be used by the mixin
.parent
+span-columns(4) // Span four of eight columns
But when you call that for a child element, the proportions would be crooked, because the parent is already proportioned:
.child
+span-columns(2) // This will fail. You want 2 of 8 columns,
// but due to nesting the math is crooked.
// It will be "2 of (4 of 8)".
To address the issue, you provide an optional argument: a context that is used to do the math:
.child
+span-columns(2, 4) // Now the mixin will take 2 parts of 4
// instead of 2 parts of four
The source code for this mixin is available on GitHub.
In short, it creates an optional argument like this (the code is in the CSS-like .scss syntax):
#mixin span-columns(
$columns,
$context: $total-columns
//...
) {
//...
width: columns($cols, $context /*...*/);
//...
}
See how $context has a default value? Thanks to the default value this argument can be omitted. In other words, $context is an optional argument.
When calling this mixin, if $context is not provided (e. g. span-columns(2)), then it is set equal to $total-columns. The $total-columns variable should be set prior to calling the mixin for the first time (see my example above).
Then the two arguments are used to calculate the width.
UPD 2013-03-30
I am not trying to figure out things in regards to columns... I have modifier my question to make it clearer.
First of all, my recommendation concerns not only grid columns. It's a universal technique you can adopt.
Secondly, now i see that you're trying to nest media queries.
Well, some media queries of different type can be combined in CSS3: e. g. print and width. But you can't put a min-width: 601px inside max-width: 600px, this just won't work!
There's an extensive answer here on StackOverflow describing why you should not nest media queries of the same type: https://stackoverflow.com/a/11747166/901944
Thirdly, you're trying to invent the wheel. There's already a fantastic mixin for crunching media queries: Respond To by Snugug. It's super easy to use and very effective.
Fourthly, the XY thing. Instead of asking about your crooked mixin, please describe the problem that you're trying to solve with it! Show us the actual HTML and explain what behavior you would like to achieve.
We will show you that it can be solved with a simple, elegant, semantic solution that does not require SASS hacking.
I have a grid set up of thumbnail images, currently 4 thumbs per row. To make sure they line up i have this snippet of code:
li:nth-child(5) { margin-left: 0;}
What I have tried to do is this but I am getting a syntax error:
$galleryGrid: 5;
li:nth-child($galleryGrid) { margin-left: 0;}
If I wanted to alter the nth-child to use another value, such as 10 (so I can have 8 thumbs in a row), I assumed this would work.
Is this not possible or am I just doing incorrectly?!
Thanks in advance for you help.
You need to use variable interpolation to allow nth-child to be a variable.
$galleryGrid: 5;
li:nth-child(#{$galleryGrid}) { margin-left: 0;}
Generates
li:nth-child(5){margin-left:0}
This markup is fine if you have absolute control over the images and layout to ensure that your elements always wrap in such a way that every 5th one begins a new row. If you cannot make such guarantees, setting negative margins on the parent element is a better way to go.
Can you guys please let me know what is the best way to disable the horiontal scroll bar?
I have div with width: 100% and height :280px. When we have long continuous text (without any spaces), we are getting a horizontal scrollbar displayed.
Btw I am using jscrollPane.
Any suggestions would be appreciated.
What I have found in jScrollPane - settings object documentation:
contentWidth - int (default undefined)
The width of the content of the scroll pane. The default value of
undefined will allow jScrollPane to calculate the width of it's
content. However, in some cases you will want to disable this (e.g. to
prevent horizontal scrolling or where the calculation of the size of
the content doesn't return reliable results)
So to get rid of horizontal bars, just set content width lower than the container width.
Example:
$('#element').jScrollPane({
contentWidth: '0px'
});
The answer from SÅ‚awek Wala (contentWidth: '0px') is a really magic wand :)
In IE8 unnecessary horisontal scrollbar appears often upon elastic containers. But that's only part of the trouble: when horisontal scrollbar appears the content overflows through both vertical gutter and scrollbar.
So, if one disables horisontal scrollbar just making it invisible (as the other answers suggest) then the second part of the trouble remains.
contentWidth: '0px' fixes the both symptoms.
However, knowncitizen was right, '0px' does something weird with the jScrollPane because contentWidth is an integer property (btw contentWidth: 'foo' gives us the same pretty result ).
To avoid unpredictable effects one can use any positive but small enough number like this: contentWidth: 1
This is quite outdated question. But in case someone has same issue as you and I:
as I haven't found any property or API call to achieve this, I used simple solution - disabled via CSS:
.jspHorizontalBar { display: none !important; }
Not very elegant way, but saved time of investigating or 'hacking' jScrollPane code.
Pass horizontalDragMaxWidth: 0 to the options.
None of the solutions worked for me here so here's what I did using nested divs:
JS
$('#scrollpane').jScrollPane();
HTML
<div id="scrollpane" style="max-height: 400px; width: 700px">
<div style="overflow:hidden; width: 650px">
Your long content will be clipped after 650px
</div>
</div>
I was able to accomplish this using CSS.
Since the parent should have the class horizontal-only, when we only want a horizontal bar, I added the class jspVerticalBar as a child so that when it appears ONLY under the horizontal-only class, it will not display it.
It will still work if you have set the vertical and horizontal on the same page.
div.horizontal-only .jspVerticalBar { display:none; }
After trying and failing with the other answers, we had to hack jScrollPane to make this work. In jquery.jscrollpane.js, line 171:
pane.css('overflow', 'auto');
// Hack: Combat size weirdness with long unbreakable lines.
pane.css('position', 'static');
// End hack
if (s.contentWidth) {
contentWidth = s.contentWidth;
} else {
contentWidth = pane[0].scrollWidth;
}
contentHeight = pane[0].scrollHeight;
// Hack: Continued.
pane.css('position', 'absolute');
// End hack
pane.css('overflow', '');
Not sure how safe it is but that works for us.
For me, the best solution was in to add left: 0 !important; for classes .customSelect and .jspPane in the CSS:
.customSelect .jspPane {
overflow-x: hidden;
left: 0 !important;
}