SASS - Set margin to 0 without affecting width - css

I am completely new to SASS.
This is the SASS code I have
#mixin set-width-and-margin($label-width: 150px, $value-margin-left: 20px){
.label-class {
width: $label-width;
}
.input-class {
margin-left: $label-width + $value-margin-left;
}
}
.form-1 {
#include set-width-and-margin();
}
.form-2 {
#include set-width-and-margin(100px);
}
It outputs the following CSS code.
.form-1 .label-class {
width: 150px;
}
.form-1 .input-class {
margin-left: 170px;
}
.form-2 .label-class {
width: 100px;
}
.form-2 .input-class {
margin-left: 120px;
}
I want to add another class .form-3 and set the margin-left value to 0 without affecting the width.
This is the desired CSS output.
.form-3 .label-class {
width: 150px;
}
.form-3 .input-class {
margin-left: 0;
}
The only solution I know is this.
.form-3 {
.label-class {
width: 150px;
}
.input-class {
margin-left: 0;
}
}
While it does work I want to know if there is a better solution for this.

You can just simply call your mixin with two parameters. You can overwrite $value-margin-left to -150px so that the resulting margin-left is 0px.
.form-3 {
#include set-width-and-margin(150px, -150px);
}
If that isn't nice enough, the alternative is to overwrite the margin left after you call your mixin (or, remake your function to accomodate this more cleanly).
.form-3 {
#include set-width-and-margin(150px);
.input-class {
margin-left: 0px;
}
}

Related

Break line of code with many :not in scss

Maybe it is a silly question but how can I break this line of code (with a lots of :not) so it won't be that long:
input {
&:not(.ant-calendar-input):not(.ant-time-picker-panel-input):not(.ant-calendar-picker-input):not(.ant-time-picker-input) {
width: 100%;
height: 100px;
}
I tried this but it doesn't work:
input {
&:not(.ant-calendar-input),
&:not(.ant-time-picker-panel-input),
&:not(.ant-calendar-picker-input),
&:not(.ant-time-picker-input) {
width: 100%;
height: 100px;
}
Your original SCSS is equivalent to the following SCSS:
input {
&:not(.ant-calendar-input) {
&:not(.ant-time-picker-panel-input) {
&:not(.ant-calendar-picker-input) {
&:not(.ant-time-picker-input) {
width: 100%;
height: 100px;
}
}
}
}
}
Which looks a bit nicer as SASS:
input
&:not(.ant-calendar-input)
&:not(.ant-time-picker-panel-input)
&:not(.ant-calendar-picker-input)
&:not(.ant-time-picker-input)
width: 100%
height: 100px

how to use multiple selector or nested selector in scss mixin

I want to get css code like this
.img-wrapper {
width: 100px;
height: 100px;
overflow: hidden;
}
.img-wrapper image {
width: 100px;
}
I want to use mixin in scss like this
#mixin fixed-img($width, $height) {
width: $width;
height: $height;
overflow: hidden;
...
}
.img-wrapper {
#include fixed-img(100px , 100px);
}
Can I get the the above css output by using only one mixin
use the parent selector & inside the mixin and define the rule for the nested img element
#mixin fixed-img($width, $height) {
width: $width;
height: $height;
overflow: hidden;
& img {
width: $width;
}
}
.img-wrapper {
#include fixed-img(100px , 100px);
}
Note that instead of
& img {
width: $width;
}
You may avoid to use the SASS variable and use inherit keyword (or also 100%)
& img {
width: inherit;
}

how to dry up sass mixin code with before and after blocks?

I have the following scss code.
#if $position == bottom {
&:after {
height: $triangle-width;
width: $triangle-width;
content:"";
position:absolute;
margin-top: -$triangle-width/2 -$stroke-width;
}
}
#if $position == top {
&:before {
height: $triangle-width;
width: $triangle-width;
content:"";
position:absolute;
margin-bottom: -$triangle-width/2 -$stroke-width;
}
}
As you can see, there is some code which is duplicated. I was wondering if there is a way to dry it up. I tried to put it into a own class but that didn't seem to work somehow. Any ideas? I could make a mixin in a mixin but that seems ab it too much overhead in my opinion. What do you think?
Usually the best way to make things DRY is to break the common parts out into mixins and build those up into larger mixins. This is exactly how Compass and most other frameworks do this. See the Compass list mixins for example.
#mixin base-triangle($triangle-width) {
height: $triangle-width;
width: $triangle-width;
content:"";
position:absolute;
}
#mixin triangle($position, $triangle-width: 4, $stroke-width: 4) {
#if $position == bottom {
&:after {
#include base-triangle($triangle-width);
margin-top: -$triangle-width/2 -$stroke-width;
}
}
#if $position == top {
&:before {
#include base-triangle($triangle-width);
margin-bottom: -$triangle-width/2 -$stroke-width;
}
}
}
.foo {
#include triangle("top", 8px, 8px);
}
.bar {
#include triangle("bottom");
}
Compiles to:
.foo:before {
height: 8px;
width: 8px;
content: "";
position: absolute;
margin-bottom: -12px;
}
.bar:after {
height: 4;
width: 4;
content: "";
position: absolute;
margin-top: -6;
}
The best way to use this sort of mixin is to leave the :before or :after out of the mixin, and just use the mixin in the pseudo class of choice directly. This cleans up the mixin, as well as removes any ties to if/else logic.
Mixin Example:
#mixin yourMixinName($position, $size, $stroke) {
position: absolute;
width: $size;
height: $size;
margin-#{$position}: -($size / 2) - $stroke;
content: '';
}
Usage Example:
.test {
&:before {
#include yourMixinName(top, 20px, 20px);
}
}
.test-2 {
&:after {
#include yourMixinName(bottom, 20px, 20px);
}
}
These SASS variables are just some random variables, to be used in this example.
$position : top ;
$triangle-width : 100px;
$stroke-width : 100px;
SASS mixin to clearly encapsulate logic in one place. And IF-ELSE are left out, so that it can be used at more than one place.
#mixin before_after($margin-side,$before-after){
&:#{$before-after} {
height: $triangle-width;
width: $triangle-width;
content:"";
position:absolute;
margin-#{$margin-side}: -$triangle-width/2 -$stroke-width;
}
}
You can combine mixin with IF-ELSE statement.
p{
#if $position == top {
#include before_after(bottom,before);
}#else{
#include before_after(top,after);
}
}
Or you can use it without any IF-ELSE too.
p{
#include before_after(bottom,before);
}
div{
#include before_after(top,before);
}
PS : The edit are made to add extra few text lines so that #Sean Stopnik can understand what is going on in here.
And my answer is supposed to provide just a base, on which the person who asked the question can build his own solution. Not to document each and every variable use and spoon-feeding.
Just a response to Sean Stopnik comments
Please provide meaningful comments only, that helps to improve the
answer.
Or If you have anything else to add to improve the answer.
If you have better answer then post it.
Don't spam comment box, Because when people come looking for answer
then they read comments too, to get better understanding of the
answer.
And you are basically wasting everybody's time.

Can I create more "media min-width" cases for Bootstrap 3?

Boostrap 3 comes with this:
#media (min-width: 1200px)
.container {
width: 1170px;
}
#media (min-width: 992px)
.container {
width: 970px;
}
#media (min-width: 768px)
.container {
width: 750px;
}
Can I freely add more min-width cases? what considerations should I have?
I want to have more cases between 1200px and, say, 1920px... because in a 1920px I end up having a container of 1170px and that sucks because it could be, say, 1300px
It's not as simple as that. Bootstrap 3 comes with 4 classes:
xs (extra small) 0-768
sm (small) 768-992
md (medium) 992-1200
lg (large) >1200
And the container class is linked to this classes, so if you want to have other stepps between this width's you must start with adding a new class for example: xxs (extra extra small) 0-384 (witch is not implemented in bootstrap right now), you have to add this classes:
.col-xxs-1, .col-xxs-2, .col-xxs-3, .col-xxs-4,
.col-xxs-5, .col-xxs-6, .col-xxs-7, .col-xxs-8,
.col-xxs-9, .col-xxs-10, .col-xxs-11, .col-xxs-12 {
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
position: relative;
}
#media (max-width: 384px) {
.col-xxs-1,
.col-xxs-2,
.col-xxs-3,
.col-xxs-4,
.col-xxs-5,
.col-xxs-6,
.col-xxs-7,
.col-xxs-8,
.col-xxs-9,
.col-xxs-10,
.col-xxs-11 {
float: left;
}
.col-xxs-1 {
width: 8.333333333333332%;
}
.col-xxs-2 {
width: 16.666666666666664%;
}
.col-xxs-3 {
width: 25%;
}
.col-xxs-4 {
width: 33.33333333333333%;
}
.col-xxs-5 {
width: 41.66666666666667%;
}
.col-xxs-6 {
width: 50%;
}
.col-xxs-7 {
width: 58.333333333333336%;
}
.col-xxs-8 {
width: 66.66666666666666%;
}
.col-xxs-9 {
width: 75%;
}
.col-xxs-10 {
width: 83.33333333333334%;
}
.col-xxs-11 {
width: 91.66666666666666%;
}
.col-xxs-12 {
width: 100%;
}
.col-xxs-push-1 {
left: 8.333333333333332%;
}
.col-xxs-push-2 {
left: 16.666666666666664%;
}
.col-xxs-push-3 {
left: 25%;
}
.col-xss-push-4 {
left: 33.33333333333333%;
}
.col-xxs-push-5 {
left: 41.66666666666667%;
}
.col-xxs-push-6 {
left: 50%;
}
.col-xxs-push-7 {
left: 58.333333333333336%;
}
.col-xxs-push-8 {
left: 66.66666666666666%;
}
.col-xxs-push-9 {
left: 75%;
}
.col-xxs-push-10 {
left: 83.33333333333334%;
}
.col-xxs-push-11 {
left: 91.66666666666666%;
}
.col-xxs-pull-1 {
right: 8.333333333333332%;
}
.col-xxs-pull-2 {
right: 16.666666666666664%;
}
.col-xxs-pull-3 {
right: 25%;
}
.col-xxs-pull-4 {
right: 33.33333333333333%;
}
.col-xxs-pull-5 {
right: 41.66666666666667%;
}
.col-xxs-pull-6 {
right: 50%;
}
.col-xxs-pull-7 {
right: 58.333333333333336%;
}
.col-xxs-pull-8 {
right: 66.66666666666666%;
}
.col-xxs-pull-9 {
right: 75%;
}
.col-xxs-pull-10 {
right: 83.33333333333334%;
}
.col-xxs-pull-11 {
right: 91.66666666666666%;
}
.col-xxs-offset-1 {
margin-left: 8.333333333333332%;
}
.col-xxs-offset-2 {
margin-left: 16.666666666666664%;
}
.col-xxs-offset-3 {
margin-left: 25%;
}
.col-xxs-offset-4 {
margin-left: 33.33333333333333%;
}
.col-xxs-offset-5 {
margin-left: 41.66666666666667%;
}
.col-xxs-offset-6 {
margin-left: 50%;
}
.col-xxs-offset-7 {
margin-left: 58.333333333333336%;
}
.col-xxs-offset-8 {
margin-left: 66.66666666666666%;
}
.col-xxs-offset-9 {
margin-left: 75%;
}
.col-xxs-offset-10 {
margin-left: 83.33333333333334%;
}
.col-xxs-offset-11 {
margin-left: 91.66666666666666%;
}
}
And also the container class you wrote:
#media (min-width: 384px)
.container {
width: 372px;
}
As you can see, it is very complicated, and it's recomanded not to use bootstrap if you want to customize it very very much.
when you need to use different break-points for container class, you may face 2 scenarios:
Scenario 1:
You know the breaking point. In this case, you can modify the SASS or LESS files, or simply create a customized version at http://getbootstrap.com/customize/#container-sizes
Scenario 2:
The breaking point is variable. In this case you use the class .container-fluid . This class can be (and is usually) used with container class in order to have some control of content inside, but the same way, you can create full screen layouts with a .semi-container class which is a somewhere between the .container class and the full width of the screen. Example:
<div class="container-fluid"><!-- full width -->
<div class="semi-container container-fluid"><!-- max-width -->
<div class="container"><!-- container -->
</div>
</div>
</div>
and then the CSS for .semi-container would be
.semi-container{max-width:1300px} /* or whatever you need */
Of course you can create more breakpoints etc. As long as you're not altering the bootstrap stylesheet it you won't affect the framework.
In reality you need to make cases for 320, 480, 600 etc... More than that.
In truth the bootstrap grid is only a starting point. I mean, come on - you can expect that everything under 768 deserves one rule.
As comprehensive as it is, bootstrap is still only supposed to be a starting point.
I've done tons of things like:
#media (max-width:480px) {
col-xs-4 {
width: 49.999%;
}
}
Anyone who tells you you can't needs a smack - just make sure to test what you've done.
Since your example only targets .container you're pretty safe. All the percentage based widths under it should work as expected.

How to access specific class attribute in less mixin?

I have .aClass
.aClass {
width: 20px;
height: 20px;
}
In .anotherClass I would like to calculate a width value based on the value of the width attribute in .aClass.
.anotherClass {
width: .aClass.width
}
The above example does not work.
I couldnĀ“t find anything in the less docs. Is there any way to do this?
Declare variable at the top of code
#width: 10px
Then,
.aClass {
width: #width;
height: 20px;
}
.anotherClass {
width: #width;
}

Resources