Laravel mix - Change production CSS output options - laravel

I am trying to change the CSS output style in webpack.mix.js, however it only seems to affect the Development build. How do I apply outpoutStyle options to the Production build?
Here, is my code in the webpack.mix.js file, changing the value of "outputstyle" only affects the Development build.
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css', {
outputStyle : 'expanded'
})
.copy(`resources/images`, `public/images`, false);
laravel-mix: version 5.0.4
sass-loader: version 7.1.0
EDIT - Additional Information:
The problem I'm trying to solve is that my code works fine with a developer build, but then goes pear-shaped when I run a production build. I suspect it has something to do with how the production build takes something like this:
.selector-1 {
background-color: green;
color: red;
}
.selector-2 {
background-color: blue;
color: red;
}
and compiles it to this:
.selector-1 {
background-color: green;
}
.selector-1, .selector-2 {
color: red;
}
.selector-2 {
background-color: blue;
}
In my case, that's undesirable behavior and I believe it's causing scoping issues with my CSS Custom Properties. The compiled code is thousands of lines long so I haven't been able to pinpoint the exact problem - but I notice the development build doesn't do that and everything works fine.
Basically, I’ve got something like this, which I’m using for theming:
:root {
—theme-base: red;
}
.theme-green {
—theme-base: green;
}
everything works fine in Dev mode… but in Prod some of the elements are inheriting the wrong colour value.

So turns out the specific CSS you're trying to output is quite key. From private messaging you I found out it's to do with borders, and your original code is this:
.selector-1 {
border-top-width: 2px;
border-top-style: solid;
border-color: get-color(base, body);
}
In production mode that compiles to
.selector-1 {
border-color: var(--color-base-body)
}
.selector-1 {
border-top: 2px solid;
}
The problem is that if those border properties are in different class selectors, even though they're the same the browser doesn't know what to do with it. We need a way to have all of the relevant border properties in one selectors. Like so:
.selector-1 {
border: 2px solid get-color(base, body);
border-width: 2px 0 0;
}
That compiles to
.u-border-top-2 {
border: solid var(--color-base-body);
border-width: 2px 0 0;
}
...which renders correctly in the browser.
I'm not sure if this is a bug in sass-loader or if a new version fixes it - on first view it looks like the correct behaviour but the cases of borders not so much.

Related

sass variable not working in container query

SCSS variables don't seem to work when used in a container query. For example this code works just fine:
.parent {
container-type: inline-size;
background: yellow;
}
#container (max-width: 800px) {
.child {
background:green;
}
}
See pen: https://codepen.io/pwkip/pen/jOprKya
But when I try to use a sass-variable to define the breakpoint, it fails.
$width: 800px;
.parent {
container-type: inline-size;
background: yellow;
}
#container (max-width: $width) {
.child {
background:green;
}
}
See pen: https://codepen.io/pwkip/pen/BaPzVZW
What's the problem here? Any workaround?
I cannot find the definitive sass lang entry, but hash and curly brace is often used in #media queries.
#container (max-width: #{$width}) {
.child {
background:green;
}
}
In Brave it works in that codepen; and so do the following:
#container (max-width: ${width} ) {
As "A Boston" already pointed out the issue seems to be that you don't use the hash syntax like in his first example.
I use https://www.sassmeister.com/ quite often to check what it compiles to.
In your Codepen you forgot to add a semicolon after
$width: 800px;
^
According to: https://developer.mozilla.org/en-US/docs/Web/CSS/#container
#container queries are not supported for Firefox yet. Only Firefox Nightly supports it.
I've tested it in Chrome and it worked with the tweaks. Make sure your browser version is supported. My current Safari version did not work either (due to the version mismatch).

React-select elements being given "css-hash" classNamePrefixes

I've been trying to customize React-select elements but they are all getting these "css-xxx" prefixes as such :
class="user-select css-b62m3t-container"
I dont know where thats coming from (could be Next.js) and I have been asked to modify theses elements using classes but not using those hashes. I've tried this (user-select is my AsyncSelect className):
.user-select {
.control {
border-radius: 0.375rem !important;
border: 1px solid #d2ddec;
}
.control:focus {
border-radius: 0.375rem !important;
border: 1px solid #d2ddec;
}
}
and this aswell :
.user-select {
&__control {
border-radius: 0.375rem !important;
border: 1px solid #d2ddec;
&--is-focused {
border-radius: 0.375rem !important;
border: 1px solid #d2ddec;
}
}
as described here How to style react-select options but I have not managed to modify these css properties other than by giving the "css-hash" class names in my scss file.
I would appreciate if you guys could help me understand where these hashes are coming from and what am I doing wrong.
Thanks in advance !
Those hash classes are CSS-in-JS classes created by #emotion, and part of the core library. You use the style override functions to create additional component styles or add additional classes to individual components.

gulp-clean-css cleaning / removing duplicated css when using #extend

I'm having a weird problem with #extend on scss. when i extend some %placeholder that have repetitive properties, the gulp-clean-css merge them, and I don't want that to happen.
Here's an example:
foo.scss
%one {
font-size: 16px;
width: 95%;
}
%two {
font-size: 1rem;
width: calc(100% - 10px);
}
.foo {
#extend %one;
#extend %two;
}
.foo2 {
font-size: 16px;
font-size: 1rem;
}
foo.min.css
.foo{font-size:1rem;width:calc(100% - 10px);}
.foo2{font-size:16px;font-size:1rem}
Why does this happen?
If it helps, this is mine gulp-task:
gulp.task('scss', function(){
console.log('start task scss');
gulp.src(folderStyles)
.pipe(sass.sync().on('error', sass.logError))
.pipe(rename({ suffix: '.min' }))
.pipe(cleanCSS({compatibility: 'ie9', noAdvanced: true}))
.pipe(gulp.dest(folderStyles));
logEnv();
});
Is there any other better plugin to use?
I don't want it to remove duplicated properties. If you ask me why, it's because of old browsers support than might not support rem or calc, or other "new fancy propertie" ;)
Thank you :)
I played around with this, and I think your setting is incorrect for 'noAdvanced':
Instead of:
.pipe(cleanCSS({compatibility: 'ie9', noAdvanced: true}))
Use:
.pipe(cleanCSS({compatibility: 'ie9', advanced: false}))
According to the docs:
advanced - set to false to disable advanced optimizations - selector &
property merging, reduction, etc.
https://github.com/jakubpawlowicz/clean-css#how-to-use-clean-css-api
This isn't going to leave you with 1 .foo selector with two font-size declarations tho, it's just not going to merge the two, so you'll end up having:
.foo {
font-size:16px;
width:95%
}
.foo {
font-size:1rem;
width:calc(100% - 10px)
}
.foo2{
font-size:16px;
font-size:1rem
}
This answers your issue however kind of defeats the purpose of using something like clean-css. I'm curious as to why you would want to leave both font-size declarations in your CSS when the first one will be overridden anyway.

Using #include vs #extend in Sass?

In Sass, I can't quite discern the difference between using #include with a mixin and using #extend with a placeholder class. Don't they amount to the same thing?
Extends do not allow customization, but they produce very efficient CSS.
%button
background-color: lightgrey
&:hover, &:active
background-color: white
a
#extend %button
button
#extend %button
Result:
a, button {
background-color: lightgrey;
}
a:hover, button:hover, a:active, button:active {
background-color: white;
}
With mixins, you get duplicated CSS, but you can use arguments to modify the result for each usage.
=button($main-color: lightgrey, $active-color: white)
background-color: $main-color
border: 1px solid black
border-radius: 0.2em
&:hover, &:active
background-color: $active-color
a
+button
button
+button(pink, red)
Results in:
a {
background-color: lightgrey;
border: 1px solid black;
border-radius: 0.2em;
}
a:hover, a:active {
background-color: white;
}
button {
background-color: pink;
border: 1px solid black;
border-radius: 0.2em;
}
button:hover, button:active {
background-color: red;
}
Please follow this consecutive set of code examples to see how you can make your code cleaner and more maintainable by using extends and mixins effectively: http://thecodingdesigner.com/posts/balancing
Note that SASS unfortunately does not allow using extends inside media queries (and corresponding example from the above link is wrong). In the situation where you need to extend based on media queries, use a mixin:
=active
display: block
background-color: pink
%active
+active
#main-menu
#extend %active // Active by default
#secondary-menu
#media (min-width: 20em)
+active // Active only on wide screens
Result:
#main-menu {
display: block;
background-color: pink;
}
#media (min-width: 20em) {
#secondary-menu {
display: block;
background-color: pink;
}
}
Duplication is inevitable in this case, but you shouldn't care too much about it because web server's gzip compression will take care of it.
PS Note that you can declare placeholder classes within media queries.
Update 2014-12-28: Extends produce more compact CSS than mixins do, but this benefit is diminished when CSS is gzipped. If your server serves gzipped CSS (it really should!), then extends give you almost no benefit. So you can always use mixins! More on this here: http://www.sitepoint.com/sass-extend-nobody-told-you/
A good approach is to use both - create a mixin that will allow you lots of customisation and then make extends for common configurations of that mixin. For example (SCSS Syntax):
#mixin my-button($size: 15, $color: red) {
#include inline-block;
#include border-radius(5px);
font-size: $size + px;
background-color: $color;
}
%button {
#include my-button;
}
%alt-button {
#include my-button(15, green);
}
%big-button {
#include my-button(25);
}
This saves you from calling the my-button mixin over and over. It also means you don't have to remember the settings for common buttons but you still have the ability to make a super unique, one-off button should you choose.
I take this example from a blog post I wrote not long ago. Hope this helps.
In my opinion extends are pure evil and should be avoided. Here is why:
given the scss:
%mystyle {color: blue;}
.mystyle-class {#extend %mystyle}
//basically anything not understood by target browser (such as :last-child in IE8):
::-webkit-input-placeholder {#extend %mystyle}
The following css will be generated:
.mystyle-class, ::-webkit-input-placeholder { //invalid in non-webkit browsers
color: blue;
}
When a browser doesn’t understand a selector, it invalidates the entire line of selectors. This means that your precious mystyle-class is no longer blue (for many browsers).
What does this really mean? If at any time you use an extend where a browser may not understand the selector every other use of the extend will be invalidated.
This behavior also allows for evil nesting:
%mystyle {color: blue;}
#mixin mystyle-mixin {#extend %mystyle; height: 0;}
::-webkit-input-placeholder {#include mystyle-mixin}
//you thought nesting in a mixin would make it safe?
.mystyle-class {#extend %mystyle;}
Result:
::-webkit-input-placeholder, .mystyle-class { //invalid in non-webkit browsers
color: blue;
}
::-webkit-input-placeholder {
height: 0;
}
Tl;dr: #extend is perfectly ok for as long as you never use it with any browser spesific selectors. If you do, it will suddenly tear down the styles wherever you have used it. Try to rely on mixins instead!
Use mixins if it accepts a parameter, where the compiled output will change depending on what you pass into it.
#include opacity(0.1);
Use extend (with placeholder) for any static repeatable blocks of styles.
color: blue;
font-weight: bold;
font-size: 2em;
I totally agree with the previous answer by d4nyll. There is a text about extend option and while I was researching this theme I found a lot of complaints about extend, so just have in mind that and if there is a possibility to use mixin instead of extend, just skip extend.

Sass: Create mixin for input fields

I'm new to Sass so I need help with the creation of a mixing for my input fields.
However, if anyone knows of an already made mixin for this or if Compass has one that accomplishes this, please let me (us) know.
I currently have the following CSS rules in my .scss file:
input[type="text"],
input[type="password"],
input[type="email"],
input[type="search"],
input[type="url"],
textarea,
select { ... }
input[type="text"]:hover,
input[type="text"]:focus,
input[type="password"]:hover,
input[type="password"]:focus,
input[type="email"]:hover,
input[type="email"]:focus,
input[type="search"]:hover,
input[type="search"]:focus,
input[type="url"]:hover,
input[type="url"]:focus,
textarea:hover,
textarea:focus,
select:hover,
select:focus { ... }
Now, as we know HTML5 provides a nice new set of input types, but right now I don't need to add input types like date, month or week, that's why I don't have them listed "yet".
So in the case I need to add them in the future, I'll update that list you see above.
However, my problem is that I feel I'm repeating myself all over here, plus, the work of selecting items, copying, pasting and editing every time for every new input type I add to the list is just plain dumb and I almost sure Sass' mixins can be of help with this. The problem is that creating a mixin for this is honestly very confusing to me.
I've looked around here and the web for something similar but haven't been able to find anything.
Any help with this is greatly appreciated.
Ok, I eventually found the Sass mixing library Bourbon.
They have an 'add-on' for HTML5 input types (here's a link to the .scss file they created), but it doesn't have the :hover or :focus pseudo elements. So I added them.
I honestly don't know if what I did is the best way to write this mixin, but the thing works marvelously:
//************************************************************************//
// Generate a variable ($all-text-inputs) with a list of all html5
// input types that have a text-based input, excluding textarea.
// http://diveintohtml5.org/forms.html
//************************************************************************//
$inputs-list: 'input[type="email"]',
'input[type="number"]',
'input[type="password"]',
'input[type="search"]',
'input[type="tel"]',
'input[type="text"]',
'input[type="url"]',
// Webkit & Gecko may change the display of these in the future
'input[type="color"]',
'input[type="date"]',
'input[type="datetime"]',
'input[type="datetime-local"]',
'input[type="month"]',
'input[type="time"]',
'input[type="week"]';
$unquoted-inputs-list: ();
#each $input-type in $inputs-list {
$unquoted-inputs-list: append($unquoted-inputs-list, unquote($input-type), comma);
}
$all-text-inputs: $unquoted-inputs-list;
// You must use interpolation on the variable:
// #{$all-text-inputs}
//************************************************************************//
// #{$all-text-inputs}, textarea {
// border: 1px solid red;
// }
// :hover and :focus pseudo elements
// Added by Ricardo Zea
// http://ricardozea.net
// #ricardozea
// Tracking: http://stackoverflow.com/questions/13180807/sass-create-mixin-for-input-fields
$inputs-list-hf:'input[type="email"]:hover',
'input[type="number"]:hover',
'input[type="password"]:hover',
'input[type="search"]:hover',
'input[type="tel"]:hover',
'input[type="text"]:hover',
'input[type="url"]:hover',
'input[type="color"]:hover',
'input[type="date"]:hover',
'input[type="datetime"]:hover',
'input[type="datetime-local"]:hover',
'input[type="month"]:hover',
'input[type="time"]:hover',
'input[type="week"]:hover',
'input[type="email"]:focus',
'input[type="number"]:focus',
'input[type="password"]:focus',
'input[type="search"]:focus',
'input[type="tel"]:focus',
'input[type="text"]:focus',
'input[type="url"]:focus',
'input[type="color"]:focus',
'input[type="date"]:focus',
'input[type="datetime"]:focus',
'input[type="datetime-local"]:focus',
'input[type="month"]:focus',
'input[type="time"]:focus',
'input[type="week"]:focus';
$unquoted-inputs-list-hf: ();
#each $input-type-hf in $inputs-list-hf {
$unquoted-inputs-list-hf: append($unquoted-inputs-list-hf, unquote($input-type-hf), comma);
}
$all-text-inputs-hf: $unquoted-inputs-list-hf;
// You must use interpolation on the variable:
// #{$all-text-inputs-hf}
//************************************************************************//
// #{$all-text-inputs-hf}, textarea {
// border: 1px solid red;
// }
As you can see I copied and pasted the original mixing and added the prefix -hf and of course the :hover and :focus to the new rules.
And in my .scss file I added this #import:
#import "html5-input-types"; (no need for the underline _ or file extension .scss)
And in the 'Forms' section of my .scss file I added these rules:
/*Normal state*/
#{$all-text-inputs},
textarea,
select { ... }
/*:hover and :focus states*/
#{$all-text-inputs-hf},
textarea:hover,
textarea:focus,
select:hover,
select:focus { ... }
I know I have textarea and select outside the mixin file (html5-input-types.scss), not sure yet if I'm including them in it or not, gotta think about it.
Anyway, this worked for me pretty well and although I will still need to update the html5-input-types.scss if anything changes in the future, at least I'm handling these input fields way more efficiently than before.
Hopefully what I did here helps someone else.
And if any of you has a suggestion to improve the mixin, by all means let me (us) know.
Thanks.
In case anyone comes across this for the same reason I did. Why not let SASS do the work?
CodePen
$form-background: #f8f8f8;
$form-color: #000;
$form-border: 1px solid lighten($form-color, 50%);
$form-focus-background: darken($form-background, 10%);
$form-focus-color: #999;
$form-focus-border: 1px solid $form-color;
%input-styles {
width: 15em;
min-height: 30px;
margin: 0 0 15px 15px;
background: $form-background;
color: $form-color;
border: $form-border;
transition: .2s ease-in-out;
transition-property: color, background-color, border;
}
%input-styles--focus {
background-color: $form-focus-background;
color: $form-focus-color;
border: $form-focus-border;
}
#mixin input-styles($styles, $focus_styles) {
$types: 'email', 'number', 'radio', 'password', 'search', 'tel',
'text', 'url', 'color', 'date', 'datetime',
'datetime-local', 'month', 'time', 'week';
#each $type in $types {
input[type="#{$type}"] {
#extend #{$styles};
&:focus {
#extend #{$focus_styles};
}
}
}
select,
textarea {
#extend #{$styles};
&:focus {
#extend #{$focus_styles};
}
}
}
#include input-styles('%input-styles', '%input-styles--focus');

Resources