I am using the Bourbon modal reset. Its close button comes with the following styling:
.modal-close {
#include position(absolute, ($modal-padding /2) ($modal-padding /2) null null);
#include size(1.5em);
background: $modal-background;
cursor: pointer;
&:after,
&:before {
#include position(absolute, 3px 3px 0 50%);
#include transform(rotate(45deg));
#include size(0.15em 1.5em);
background: $modal-close-color;
content: '';
display: block;
margin: -3px 0 0 -1px;
}
&:hover:after,
&:hover:before {
background: darken($modal-close-color, 10%);
}
&:before {
#include transform(rotate(-45deg));
}
}
This makes it look like a grey × in the upper right of the modal. However, I would like to change it to look like a button that says "Save and Close". I'm wondering what the best method of overriding these styles is. On properties like margin, I can simply set it to whatever I want. However on #include position(....);, I am not really sure how I can reset that to none, initial, or unset. What is the best method for doing something like this? I don't want to simply remove the properties in the original refill file; I would like to keep a separate _modalOverride.scss, so I can include it where I want, but keep the original in tact. How can I override these "custom" #include properties?
Refills was designed to be overwritten so I'd just do the following to the HTML:
...
<div class="modal-close" for="modal-1">Close and Save</div>
...
and for the Scss:
...
.modal-close {
#include position(absolute, ($modal-padding /2) ($modal-padding /2) null null);
#include size(8em 1.5em);
background: tomato;
cursor: pointer;
}
...
But if you want to do an overwrite file it might be a bit trickier. You could do something like this in a file that comes after the modal.scss:
.modal-close {
position: inherit;
&:after,
&:before {
background: transparent;
}
&:hover:after,
&:hover:before {
background: transparent;
}
}
Related
I'm writing a library and I'd like to style all buttons.
HTML
<div>
<p>Buttons</p>
<button>Button</button>
<button class="r1">Button</button>
</div>
<div>
<p>File inputs</p>
<input type="file" />
<input type="file" class="r1" />
</div>
SCSS
button,
input[type=file]::file-selector-button {
background: #81ecec;
border: 2px solid #00cec9;
&.r1{
background: red;
}
}
This code processes to:
button.r1,
input[type=file]::file-selector-button.r1 {
background: red;
}
[This is invalid and does not work]
Is there a mixin or method I can use so that I can place the classes on only the parent selector, without this getting out of hand? I intend to have multiple classes (primary, secondary, large, small) and I don't want to write:
button.r1,
input[type=file].r1::file-selector-button{
...
}
button.large,
input[type=file].large::file-selector-button{
...
}
button.small,
input[type=file].small::file-selector-button{
...
}
I can't figure out a good way of targeting the parent input[type="file"]
This codepen has the first example in it, and as it isn't valid CSS the background: red doesn't take effect:
https://codepen.io/EightArmsHQ/pen/VwxwPGM/139933ae274200149b84afdb726478c5?editors=1100
Attempt 1
At the moment I am using a mixin like so:
#mixin button{
background: var(--button-primary);
color: #fff;
text-decoration: none;
border: none;
display: inline-block;
padding: 4px 8px;
}
#mixin button-r1{
border-radius: 3px;
}
button,
.button,
input[type="submit"],
input[type="reset"]{
#include button;
&.r1{
#include button-r1;
}
}
input[type=file]{
&::file-selector-button{
#include button;
}
&.r1::file-selector-button{
#include button-r1;
}
}
The benefit is that I don't need to repeat the same styles over and over, however I feel like there must be a better way of creating a mixin that interpolates a class somehow.
Attempt 2
Using the classname as an argument works well, however I lose the ability to nest the rules, which is a shame and one of my favourite parts of SCSS.
#mixin buttonAndFileInputs($classname: "") {
button#{$classname},
.button#{$classname},
input[type="submit"]#{$classname},
input[type="reset"]#{$classname},
input[type="file"]#{$classname}::file-selector-button {
#content;
}
}
#include buttonAndFileInputs {
background: var(--button-primary);
color: #fff;
}
#include buttonAndFileInputs(".r1") {
border-radius: 3px;
}
I'm not 100% clear on what you're trying to do
But I think if you edit your codepen to this scss
button,
input[type=file] {
background: #81ecec;
border: 2px solid #00cec9;
&.r1{
background: red;
}
}
::file-selector-button {
background: inherit;
border: inherit;
}
that will get what you're looking for
Edit to add explanation:
This will make the file-selector-button follow the background and border properties of the input[type=file].
This means that the file-selector-button will match the rest of the input background.
EDIT:
I was just overthinking it. Now I've added more variables to the mixin like this to make all the colour correct:
#mixin CustomBtn($border-color, $transparent: transparent, $text-color, $bg-hover-color, $text-hover-color)
I've got a WordPress page where I use SCSS mixins to simplify the use of different colours on buttons. Most of the buttons have the same border colour and a text colour with a transparent background on them all so I created this mixin to deal with that:
#mixin CustomBtn($primary-color, $text-hover-color, $transparent: transparent) {
border: 2px solid $primary-color;
border-radius: 2px;
background-color: $transparent;
background-image: none;
color: $pri-color;
font-weight: 600;
padding: 1rem 2rem 1rem 1.5rem;
&:hover {
background-color: $primary-color;
color: $text-hover-color;
}
}
And here is the css where I output it:
.btn_custom {
&-black a {
#include CustomBtn($black, $white);
}
&-white a {
#include CustomBtn($white, $black);
}
&-blue a {
#include CustomBtn($light-blue, $white, $light-blue);
}
&-negative a {
#include CustomBtn($brown, $white);
}
}
This is all great but now the client wants to have a button that uses a coloured background, ex. a button with blue background-colour and white text. I want to do this mixin in the best way possible and not repeat my code, but I can't seem to figure out how to make this mixin work with a coloured background in the way I want it to (maybe I'm doing it wrong tho...)
Should I maybe use a conditional statement for the $transparent variable?
I'm new to Sass, so if this isn't the best way of doing this type of thing, I apologise!
So, I've got a mixin for button style, like so:
#mixin button ($bg, $color, $padding, $display: inline, $radius: 0, $transition: 0.2s) {
background: $bg;
#if $radius > 0 {
#include border-radius($radius)
}
color: $color;
#if $display != inline {
display: $display;
}
#if $padding > 0 {
padding: $padding;
}
text-decoration: none;
#include transition(all, $transition, linear);
&:hover {
#if lightness($bg) > 50% {
background: darken($bg, 10%);
} #else {
background: lighten($bg, 10%);
}
}
}
and a button, like so:
.btn {
#include button(#095d94, #fff, 10px, inline-block);
}
But, now I need another button with a different background colour. So what I'm wondering is: is there a way to extend a class, and also just change an argument of the mixin that that class includes, without having to do this:
.btn2 {
#extend .btn;
background: #bad78d;
&:hover {
background: darken(#bad78d, 10%);
}
}
Is it possible to feed in another background colour? Something like,
.btn2 {
$bg: #bad78d; //i know this doesn't work
#extend .btn;
}
or like,
.btn2 ($bg: #bad78d) {
#extend .btn; //this one doesn't even make sense, but I think I'm explaining what I need... ish.
}
I think you have two options here.
Also you try to keep it dry, there is nothing too wrong about repading sometimes. So if your mixin is not too huge it'll be ok to this:
.btn {
#include button(#095d94, #fff, 10px, inline-block);
}
.btn2 {
#include button(#bad78d, #fff, 10px, inline-block);
}
But This will only be required if the difference between .btn and .btn2 is big.
If you just want to change certain properties, you may also just use the classig cascading.
.btn,.btn2 {
#include button(#095d94, #fff, 10px, inline-block);
}
.btn2 {
background-color:#bad78d;
...
}
Succinctly, By using Susy's at-breakpoint responsive mixin, is there a way or function to include an external CSS file in the body of the breakpoint call?
Something like this:
.page {
border: 1px dashed #000;
height: 650px;
#include container;
.content {
color: red;
text-align: center;
border: 1px dashed red;
height: 400px;
#include span-columns(4 omega, 6);
.main {
color: green;
border: 1px dashed green;
text-align: center;
#include span-columns(1, 2);
}
.secondary {
color: blue;
border: 1px dashed blue;
#include span-columns(2, 3);
}
}
#include at-breakpoint(800px 8 250px) {
#include container;
.content {
#include span-columns(1, 1);
}
//IMPORT or INCLUDE CSS FILE HERE somehow...
} //end of breakpoint
}
I was hoping it was possible, because that'd be a whole lot cleaner than writing all the CSS rules I wish to be applied right there inline. Let me know if it's possible or what's the best practice in this case.
Thank you!
Sure. This isn't really a question about Susy, so much as a question about Sass. The same answers are true for working in the context of any wrapping mixin.
You can only import files at the root level (for now, at least) — but that's not your only option. I've seen people write all their site styles inside mixins, and then simply include those mixins as needed:
#mixin medium-layout {
// your medium css
}
.page {
#include at-breakpoint($medium) {
#include medium-layout;
}
}
You can use as many mixins as you like, call them whatever you want, and put them in other files (as long as you #include those files before calling the mixins).
I use a different approach. Rather than nesting everything under a .page selector, with big groups for each breakpoint, I break things up into modules, and keep the breakpoint styles attached to each module as needed.
// _main.scss
.main {
color: green;
#include at-breakpoint($medium) { /* changes to main */ }
}
// _secondary.scss
.secondary {
color: blue;
#include at-breakpoint($medium) { /* changes to secondary */ }
}
From a mobile-first perspective, where breakpoint styles may need to override or build on existing styles, this keeps all the related code in one place.
I am using compass to generate sprite images. And I have MANY sprite icons, and it is generating too much CSS code (too many class selectors for the background image). So lets analyze the compass sprite code:
as you can see here http://compass-style.org/help/tutorials/spriting/
#import "my-icons/*.png";
#include all-my-icons-sprites;
Will generate:
.my-icons-sprite,
.my-icons-delete,
.my-icons-edit,
.my-icons-new,
.my-icons-save { background: url('/images/my-icons-s34fe0604ab.png') no-repeat; }
.my-icons-delete { background-position: 0 0; }
.my-icons-edit { background-position: 0 -32px; }
.my-icons-new { background-position: 0 -64px; }
.my-icons-save { background-position: 0 -96px; }
If you see I use this way: <div class="my-icons-sprite my-icons-delete"></div>
I want Compass to generate this code:
.my-icons-sprite { background: url('/images/my-icons-s34fe0604ab.png') no-repeat; }
.my-icons-delete { background-position: 0 0; }
.my-icons-edit { background-position: 0 -32px; }
.my-icons-new { background-position: 0 -64px; }
.my-icons-save { background-position: 0 -96px; }
Else each new image, it'll add for background and background position. Causing too many selectors.
Is there a configuration for that?
Thanks
Have you tried this snippet for Compass?
$icons: sprite-map("icons/*.png");
i{
background: $icons;
display: inline-block; // or block
}
#each $i in sprite_names($icons){
.icn-#{$i}{
background-position: sprite-position($icons, $i);
#include sprite-dimensions($icons, $i);
}
}
This example uses the <i></i>-tag with a class containing the prefix icn- combined with the filename of the separate .png-files in your icons-folder. Like this:
<i class="icn-delete"></i>
The generated CSS looks like this:
i {
background: url('/path/to/generated/spritemap/my-icons-xxxxxxxxxxx.png');
display: inline-block;
}
.icn-delete {
background-position: 0 0;
height: 32px; // assuming the width is 32px
width: 32px; // assuming the height is 32px
}
.icn-edit{
background-position: 0 -32px;
height: 32px; // assuming the width is 32px
width: 32px; // assuming the height is 32px
}
.icn-new {
background-position: 0 -64px;
height: 32px; // assuming the width is 32px
width: 32px; // assuming the height is 32px
}
...
..
.
Still, I haven't quite figured out how to use this in combination with Compass' Magic Selectors.
Magic Selectors works very nice when you need different states (:hover, :active, :target). All you have to do is name your files like this: filename_state.png (delete_hover.png, delete_active.png etc). Compass' Magic Selectors then automatically generates css for :hover, :active and :target (delete:hover, delete_hover and delete-hover). This way you are quite free to choose how you would represent a state-change.
If you, in my first example, has filenames with the postfix for hover/ active states, the snippet only writes CSS like this:
.icn-edit_hover {
background-position: -32px -32px;
height: 32px;
width: 32px;
}
I'd really like to have it print this:
.icn-edit:hover, .icn-edit_hover, .icn-edit-hover{
background-position: 0 -32px;
height: 32px;
width: 32px;
}
like the traditional Compass' Magic Selectors does. Any idea?
In my opinion, it seems like the best of both worlds (less HTML and CSS) would be to have this code (using an attribute selector for the image):
HTML
<div class="my-icons-delete"></div>
CSS
[class^="my-icons-"] { background: url('/images/my-icons-s34fe0604ab.png') no-repeat; }
.my-icons-delete { background-position: 0 0; }
.my-icons-edit { background-position: 0 -32px; }
.my-icons-new { background-position: 0 -64px; }
.my-icons-save { background-position: 0 -96px; }
Unfortunately, I do not know how to get Compass to export like that. However, unless you are using Compass dynamically rather than just to build your back end static css, you could just change it once generated.
For anyone looking to the answer to ScottS question.
How can I use a css selector for anything starting with a baseclass
Try this:
http://codepen.io/Acts7/pen/nwsEb
I'm pasting the code below.
the spriteGen mixin requires two parameters
1) the baseclass you want to use (in ScottS case --- "myicons"
2) the second parameter is the folder location
Also DONT forget the "." before #{$mySpriteBaseClass}.
Otherwise you get >> myicons-home_icon{background-position:...}
(notice no . for class name selector)
// _custom.scss
// ---------------------------------------------------------
// Sprite Generation
--------------------- */
#include spriteGen('sprites','sprites');
// _mixins.scss
// ---------------------------------------------------------
// Sprite Generation Mixin with options
#mixin spriteGen($mySpriteBaseClass:'.spritebc',$mySpriteFolder:'sprites'){
$mySprites:$mySpriteFolder + "/*.png";
$spritefoldername-map: sprite-map($mySprites,
$spacing: 10px,
$layout: vertical
);
// if using base class as starter for sprite name class
[class^="#{$mySpriteBaseClass}"]{
/*// if using a separate base class
.#{$mySpriteBaseClass}{*/
// TODO:
// Add if/else to set width globally
// or let spriting assign it per each
//width: 48px;
//height: 48px;
display: inline-block;
vertical-align: middle;
background: $spritefoldername-map no-repeat;
}
#each $sprite in sprite_names($spritefoldername-map) {
// if using sprite base class as prefix to full sprite class name
.#{$mySpriteBaseClass}-#{$sprite} {
/*// if using separate base class and sprite name class
.#{$sprite} {*/
background-position: sprite-position($spritefoldername-map, $sprite);
#include sprite-dimensions($spritefoldername-map, $sprite);
}
}
}
What's wrong with the current output?
You can already assign my-icons-delete/edit/new/save only, this is semantic enough - it already says it's an icon and it's a delete icon.
This is what I'm currently doing, it requires Sass 3.3 though:
$icons: sprite-map('icons/*.png');
.icon {
background: $icons;
display: inline-block;
vertical-align: middle;
}
#each $i in sprite_names($icons) {
$underscore: str-index($i, _);
#if ($underscore < 1) {
.icon--#{$i} {
background-position: sprite-position($icons, $i);
#include sprite-dimensions($icons, $i);
}
} #else {
$prefix: str-slice($i, 0, $underscore - 1);
$postfix: str-slice($i, $underscore + 1);
.icon--#{$prefix}:#{$postfix} {
background-position: sprite-position($icons, $i);
}
}
}
I'm using BEM here so it assumes you'll use this like <i class="icon icon--star></i>, so if if you have a "star.png" and "star_hover.png" images it'll generate .icon--star and .icon--star:hover class names.