On a site I'm developing w/ Bootstrap/SASS (SCSS) I'd like to have a Bootstrap button group (.btn-group) become a vertical group (.btn-group-vertical) using media selectors, rather than JavaScript. However, the well-known issues that #extend will not work inside a media selector, has left me befuddled. E.g., this raises an error:
.navGroup {
#extend .mt-1;
#extend .btn-group;
#include media-breakpoint-down(xs) {
#extend .btn-group-vertical;
}
}
If I were developing from scratch I'd rewrite .btn-group and .btn-group-vertical to simply #include a mixin, so that I could do something like:
.navGroup {
#extend .mt-1;
#include media-breakpoint-up(xs) {
#include btn-group-include();
}
#include media-breakpoint-down(xs) {
#include btn-group-vertical-include();
}
}
I would rather not change the original bootstrap _buttonGroup.scss file, since it will be overwritten at the next release/update. So I'm currently needing to copy and past the whole .btn-group-vertical definition:
.navGroup {
#extend .mt-1;
#extend .btn-group;
#include media-breakpoint-down(xs) {
flex-direction: column;
align-items: flex-start;
/* etc. for 70 lines */
}
}
Is there a way to easily convert an existing class definition into a mixin within Sass that would solve such a problem?
You could try using the flex classes. Sorry, I don't know the markup for the navGroup.
<div class="d-flex flex-column">
<div class="p-2">Flex item 1</div>
<div class="p-2">Flex item 2</div>
<div class="p-2">Flex item 3</div>
</div>
You can apply these per breakpoint. Checkout https://getbootstrap.com/docs/4.0/utilities/flex/
I have built the following in Singularity
A 1/3 broad image next to a 2/3 broad image and in the next line the other way around. The images are served with picturefill. But my problem is when i narrow the viewport down from the containers max-width towards the breakpoint (750px) where the images switch from a two "column" layout to a one column it differ in height even the source files have the exact same physical height in pixel. They differ sometimes a few pixel, sometimes only one.
the reduced setup behind is the following (left out retina markup and 2 breakpoints inbetween):
<section class="pro-main" role="main">
<section class="pro-thirds">
<article class="pro-samples imgparent">
<a class="p-ov-liner" href="#">
<span data-picture data-alt="onethird">
<span data-src="/img/projekte-gpfinestsolution-zweidrittel-659x324.jpg"></span>
<span data-src="/img/projekte-gpfinestsolution-eindrittel-341x347.jpg" data-media="(min-width: 750px)"></span>
<noscript><img src="/img/projekte-gpfinestsolution-zweidrittel-659x324.jpg" alt="img1"></noscript>
</span>
<div class="bottombox"></div>
</a>
</article>
<article class="pro-samples imgparent">
<a class="p-ov-liner" href="#">
<span data-picture data-alt="twothird">
<span data-src="/img/projekte-gplab-zweidrittel-659x324.jpg"></span>
<span data-src="/img/projekte-gplab-zweidrittel-704x347.jpg" data-media="(min-width: 750px)"></span>
<noscript><img src="/img/projekte-gplab-zweidrittel-659x324.jpg" alt="twothird"></noscript>
</span>
<div class="bottombox"></div>
</a>
</article>
<article class="pro-samples imgparent">
<a class="p-ov-liner" href="#">
<span data-picture data-alt="twothird">
<span data-src="/img/projekte-gplab-zweidrittel-659x324.jpg"></span>
<span data-src="/img/projekte-gplab-zweidrittel-704x347.jpg" data-media="(min-width: 750px)"></span>
<noscript><img src="/img/projekte-gplab-zweidrittel-659x324.jpg" alt="twothird"></noscript>
</span>
<div class="bottombox"></div>
</a>
</article>
<article class="pro-samples imgparent">
<a class="p-ov-liner" href="#">
<span data-picture data-alt="onethird">
<span data-src="/img/projekte-gpfinestsolution-zweidrittel-659x324.jpg"></span>
<span data-src="/img/projekte-gpfinestsolution-eindrittel-341x347.jpg" data-media="(min-width: 750px)"></span>
<noscript><img src="/img/projekte-gpfinestsolution-zweidrittel-659x324.jpg" alt="img1"></noscript>
</span>
<div class="bottombox"></div>
</a>
</article>
</section>
</section>
breakpoint and singularity settings are as follows:
// Baseline breaks
$baseline675: 675px 849px;
$baseline850: 850px 1074px;
$baseline1075: 1075px 1199px;
$baselineMAX: 1200px;
// Container breaks
$container600: 600px;
$container750: 750px;
$container850: 850px;
$container990: 990px;
$container1100: 1100px;
$container1200: 1200px;
// Singularity
$grids: 6;
$grids: add-grid(9 at 675px);
$grids: add-grid(12 at 850px);
$grids: add-grid(15 at 1075px);
$grids: add-grid(18 at 1200px);
$gutters: 1/3;
$output:'isolation';
the styling:
.pro-main,
.pro-thirds {
#extend %clearfix;
}
.pro-samples {
#include trailer(0.5);
&:last-child {
#include trailer(2);
}
#include switch-baseline(850px 1074px) {
&:nth-child(4n+1) {
#include isolation-span(4, 1, 'right', $gutter:.5);
}
&:nth-child(4n+4) {
#include isolation-span(4, 9, 'right', $gutter:0);
}
&:nth-child(4n+2) {
#include isolation-span(8, 5, 'right', $gutter:0);
}
&:nth-child(4n+3) {
#include isolation-span(8, 1, 'right', $gutter:.5);
}
&:last-child {
#include trailer(2);
}
}
#include breakpoint(1075px 1199px) {
&:nth-child(4n+1) {
#include isolation-span(5, 1, 'right', $gutter:.5);
}
&:nth-child(4n+4) {
#include isolation-span(5, 11, 'right', $gutter:0);
}
&:nth-child(4n+2) {
#include isolation-span(10, 6, 'right', $gutter:0);
}
&:nth-child(4n+3) {
#include isolation-span(10, 1, 'right', $gutter:.5);
}
&:last-child {
#include trailer(2);
}
}
#include breakpoint(1200px) {
&:nth-child(4n+1) {
#include isolation-span(6, 1, 'right', $gutter:.5);
}
&:nth-child(4n+4) {
#include isolation-span(6, 13, 'right', $gutter:0);
}
&:nth-child(4n+2) {
#include isolation-span(12, 7, 'right', $gutter:0);
}
&:nth-child(4n+3) {
#include isolation-span(12, 1, 'right', $gutter:.5);
}
&:last-child {
#include trailer(2);
}
}
}
Between the height of the one third and two third images at max width are physically identical also they are aligned at the bottom line. on smaller viewports they differ. and if i remove the gutter with pictures in it the heights still differs. e.g.
#include breakpoint(1075px 1199px) {
&:nth-child(4n+1) {
#include isolation-span(5, 1, 'right', $gutter:0);
}
&:nth-child(4n+4) {
#include isolation-span(5, 11, 'right', $gutter:0);
}
&:nth-child(4n+2) {
#include isolation-span(10, 6, 'right', $gutter:0);
}
&:nth-child(4n+3) {
#include isolation-span(10, 1, 'right', $gutter:0);
}
&:last-child {
#include trailer(2);
}
}
If i use, instead of the picturefill markup, just empty article tags and add those two properties to the scss from above the height stays exactly the same on all article elements no matter if they are 1/3 or 2/3.
background:red
height:10em;
with gutter:
and without:
Does anyone have an idea what might cause that varying difference in height over the viewports? Me for myself am completely out of ideas. :(
Best regards Ralf
The reason for the difference in images' heights
The reason for the difference in images' heights is mathematical.
For simplicity, let's have a look at the following column system:
#include add-grid(4);
#include add-gutter(0.1);
The above definition means: four columns of identical width, and between them three (4 - 1) gutters. Each gutter has the width equal to 0.1 width of any column.
Now, given that the width of the container is 1000 px, what will be the width of every column and every gutter?
Let's say that a column is x px wide. Then a gutter will be 0.1x px wide. We can assemble an equation:
4x + 3*(0.1x) = 1000
Let's solve it:
4x + 0.3x = 1000
4.3x = 1000
x = 1000 / 4.3
x = 232.56
Every column is ~232.56px wide! And every gutter is 232.56 * 0.1 = 23.256px wide.
Now, let's say we've got two images: 250x250 px and 750x250 px, and we put them into these columns.
The first image will occupy one column and zero gutters. It's width and height will both be equal to 232.56 px.
The second image will occupy three columns and two gutters between those columns. It's width will be equal to 232.56 * 3 + 23.256 * 2 = 744.192px. The height of the second image will be equal to 250 * 744.192 / 750 = 248.064px.
As you can see, the images' heights don't match, and this is expected.
A solution for the problem
You could use a compound grid to compensate for the difference in heights. This is way more difficult to calculate.
A simpler solution is to slice your images to match your existing grid!
General recommendations for your grid layout.
You use a lot of grid definitions for different breakpoints but across all of them (except for the mobile view), you have the same layout.
You don't have to redefine grids for every breakpoint. In fact, your responsive layout can be reduced to this definition:
+add-grid(3);
+add-gutter(0.5);
For the mobile layout, don't apply any spans. For the layouts starting with the smallest breakpoint, apply the spans and you're good to go.
Note that you can still apply multiple breakpoints for other styles, e. g. container width.
For the isolation spanning to work with multiple rows, apply clearing for the first child in every row:
&:nth-child(3n+1) { clear: both; }
Note: this should be done AFTER applying a Singularity span mixin, e. g.:
&:nth-child(3n+1) {
+grid-span(1,1);
clear: both;
}
You can use the common grid-span mixin instead of the specific isolation-span. Isolation is the default spanning technique for the grid-span mixin.
Don't override direction and gutters for every mixin call unless you're trying to position elements off the declared grid.
Don't use varying gutter sizes for adjacent elements, otherwise it will ruin the math.
Don't apply duplicate styles under every media query. Ideally, every CSS rule should be declared only once. You can create more specific media query rules if necesary instead of duplicating styles.
UPD: Oh, and remember that you can declare columns and guttters in the following format:
+add-grid(235 235 235 235);
+add-gutter(20);
This is identical to +add-grid(4); +add-gutter(0.085); but makes comprehending the numbers much easier.
Is it possible to specify an overlapping grid element to be rendered in front or behind its siblings?
My code below will render the .l-branding div behind the .l-header. I need .l-branding before .l-header in the source order so it renders above .l-header (slideshow) on mobiles.
HTML:
<div class="l-container">
<div class="l-branding">
<!-- logo -->
</div>
<div class="l-header">
<!-- image slider -->
</div><!-- end .l-header -->
<navigation class="l-navigation" role="navigation">
<!-- navigation -->
</navigation>
</div><!-- end .l-container -->
SCSS:
I can use position:absolute; and z-index:10 for the $tab & $desk breakpoints but would like to know if there is a better way.
///////////////////////////////////////////////////////////
//
// HEADER
//
///////////////////////////////////////////////////////////
.l-header-wrap {
#include clearfix;
}
.l-header {
#include grid-span(4,1);
#include breakpoint($tab) {
#include grid-span(12,1);
min-height:$vert-spacing-unit * 5;
}
#include breakpoint($desk) {
#include grid-span(18,1);
}
}
///////////////////////////////////////////////////////////
//// BRANDING
///////////////////////////////////////////////////////////
.l-branding {
#include grid-span(4,1);
#include breakpoint($tab) {
#include grid-span(11,1);
//position: absolute;
//top:1em;
}
#include breakpoint($desk) {
#include grid-span(17,1);
}
}
///////////////////////////////////////////////////////////
//// NAV
///////////////////////////////////////////////////////////
.l-navigation {
#include grid-span(4,1);
#include grid-background;
#include breakpoint($tab) {
#include grid-span(12,1);
//margin-top:-100px;
//position: absolute;
//bottom:0;
}
#include breakpoint($desk) {
#include grid-span(18,1);
//margin-top:-100px;
}
}
You cannot do this with singularity per se, but it can be done with normal CSS. The answer is what you've already done, absolute positioning and z-index. A quick preview of what it would look like is here on CodePen.
I'm not entirely sure if even Flexbox will solve this issue, I believe this is something that just needs to be solved using position and z-index as that's what you're asking to do.
I am having some trouble with the semantic grid mixin. I'm am sorry if I am missing something obvious, but I seek you help. I have the following code:
index.html
<header>
<a id="logo" href="#">Logo Link</a>
<div id="search">
<span class="prefix">#</span>
<input type="text">
</div>
</header>
app.scss
header { #include outerRow();
#logo { #include column(8); }
#search { #include column(4); #include innerRow(collapse);
span { #include column(3); }
input { #include column(9); }
}
}
This works correctly with the screen wide, but the prefix stretches to full width in narrow mode. I am a newbie in this adventure, but I believe it recalculates on it own for narrow screens, or do I have to a #media for this to work properly?
to new to post images so here are links:
Wide (correct) - http://imgur.com/dtsGtxM
Narrow (foofed) - http://imgur.com/jX4D1NU
edit: Well the solution seems to be:
span { #include column(3); #include mobileColumn(1); }
input { #include column(9); #include mobileColumn(3); }
although I don't fully understand it. Still not sure whether calling for a new nested row in the column is acceptable, as below, but it seems to work:
#search { #include column(3); #include innerRow(collapse);
Foundation has a default breakpoint at 768px using media queries.
So, when viewing on the larger device it uses the column() mixin and then on smaller screen size it uses the mobileColumn() mixin.
Also, setting a div (in your case #search to be a column and an inner row is going to produce unexpected results. You should wrap your columns in a separate inner row container:
<header>
<a id="logo" href="#">Logo Link</a>
<div id="search">
<div class="inner-row">
<span class="prefix">#</span>
<input type="text">
</div>
</div>
</header>
and
header { #include outerRow();
#logo { #include column(8); }
#search { #include column(4);
span { #include column(3); }
input { #include column(9); }
}
.inner-row { #include innerRow(collapse); }
}
http://foundation.zurb.com/old-docs/f3/media-queries.php
I'm desperately trying to get a site mocked up with Susy. I fear I may just be missing something obvious but when I nest items in my Susy grid each column percentage width and margin seem to be slightly overshooting such that they add up beyond 100% and wrap to the next line. In the following example the #main_headernav is set to span 8 of 12 columns and each li within should fill 2 of 8 columns. Each li has a computed style as below which adds up to more than 100% and causes the last item to wrap
width: 22.58065%;
float: left;
margin-right: 3.22581%;
This is is the offending example:
<header id="main_header">
<img id="main_banner" src="images/test_banner.png" alt="Test">
<nav id="main_headernav">
<ul>
<li>About</li>
<li>Blog</li>
<li>Shop</li>
<li>Contact</li>
</ul>
</nav>
</header>
And SASS:
$total-columns : 12;
$column-width : 60px;
$gutter-width : 20px;
$grid-padding : $gutter-width;
//Set border-box sizing - also alters SUSY grid math
//#include border-box-sizing;
// Main Container
#main_container {
#include container;
}
#main_header {
#include span-columns(12 omega);
#main_banner {
#include span-columns(12 omega,12);
}
#main_headernav {
#include span-columns(8 omega,12);
li {
#include span-columns(2,8);
}
}
}
Ok so I knew it would be my problem :)
Of course it is necessary to use the nth-omega mixin on every 4th li child to avoid the extraneous margin and prevent wrapping.
And it only took 2 hours of staring at the same screen :)