Writing browser specific hack in Less (for <IE9) - css

I want to do something like this (Source - CSS Tricks Article):
#veinte { color/*\**/: blue\9; }
in Less for IE7 and IE8 but it gives errors.
The below works:
#diecinueve { color: blue\9; }
but there are some elements that I dont want to be called in IE9. e.g. I have something in IE9 with :before elements but because IE8 doesnt support it, I want to give it a padding only in IE8.
But this
#veinte { color/*\**/: blue\9; }
gives errors in Less. I tried this
#veinte { color~"/*\**/": blue\9; }
but that also doesnt work. Does anyone know how to do this in Less?

Property name interpolation is possible with Less v1.6.0 and above. Hence this hack can be implemented as shown below:
#hack: ~"/*\**/";
#veinte {
color#{hack}: blue\9;
}
Compiled CSS:
#veinte {
color/*\**/: blue\9;
}

Are you including Modernizr or another shiv script that adds classes directly to the HTML element?
Thus something like this:
.selector {
...rules...
.lte8 & {
... < IE9 styles ...
}
}
Might suit your needs. (see: nesting selectors, using the &)
Otherwise, since you're being hacky anyway, why not just reference a different .less compiled output sheet in a conditional comment?

You can try this one: background-position:~"-150px 0px\9" width:~"300px\9";
example:
.test{
width:~"300px\9";
}

Related

Placeholder mixin Less

At the moment I try to create a small less mixin to add styles to placeholders.
The values are passed through an object. My solution now looks like this:
.placeholder(#rules){
&::-webkit-input-placeholder, &:-moz-placeholder,
&::-moz-placeholder,&:-ms-input-placeholder{
#rules();
}
}
I try to use this mixin like this:
input{
.placeholder({color:green})
}
So less generates:
input::-webkit-input-placeholder, input:-moz-placeholder,
input::-moz-placeholder, input:-ms-input-placeholder{
color: green;
}
The code evens has been generated like I want it, but the wished effect not entered. But when I cut the code and fill it in devtools it works.
Does anybody find a mistake. I don't get it
From css-tricks.com:
That would be nice, but the problem is that when a browser doesn’t understand a selector, it invalidates the entire line of selectors (except IE 7).
So you'll have to seperate the placeholder selectors:
.placeholder(#rules){
&::-webkit-input-placeholder{
#rules();
}
&:-moz-placeholder{
#rules();
}
&::-moz-placeholder{
#rules();
}
&:-ms-input-placeholder{
#rules();
}
}

How to apply IE Fixes for LESS CSS

how to use ie 9 hack in less css?
ie 9 hack \0/
compiler error
Following characters are exceptions and not encoded: ,, /, ?, #, &, +, ', ~, ! and $.
how to encode this characters ?
You cannot... either use Modernizr like #Blender suggested or in your markup append ie9 class using:
<!--[if IE 9]><script>document.documentElement.className += " ie9";</script><![endif]-->
and use ie9 specific rules in LESS:
.ie9 & { /* IE9 rules */ }
You can apply some hacks css with this following answer : Writing browser specific hack in Less (for <IE9)
#hack: ~"/*\**/";
#veinte {
color#{hack}: blue\9;
}
Compiled CSS:
#veinte {
color/*\**/: blue\9;
}

SASS 3.2 Media Queries and Internet Explorer Support

I recently implemented this technique with SASS 3.2 using #content blocks on a project I've been working on, and I've just gotten to the point where I need to include support for older browsers such as IE7 and 8.
Example:
.overview {
padding: 0 0 19px;
#include respond-to(medium-screens) {
padding-top: 19px;
} //medium-screens
#include respond-to(wide-screens) {
padding-top: 19px;
} //medium-screens
}
They both don't support media queries, and I've often handled this in the past by serving up all styles to these browsers when I had my media queries separated into separate partial files such as _320.scss, _480.scss and in my IE stylesheet loading them like so:
#import 320.scss;
#import 480.scss;
etc.
Which would load all styles, and always assign IE7 - 8 a 940px (or whatever the max width is) layout and styles. By nesting styles in SASS 3.2 inline like this, it eliminates the need for separate partial stylesheets, but totally screws up how I load styles for IE.
Any ideas or solutions on how to combat this? I could use a polyfill such as respond.js to force IE to use media queries, but would prefer to just serve up a non-flexible site to IE.
Any ideas on either how to best organize these files, or a better solution?
You can generate a separate stylesheet for IE<9 that contains everything your normal sheet has, but with flattened media queries based on a set width.
Full explanation here http://jakearchibald.github.com/sass-ie/, but basically you have this mixin:
$fix-mqs: false !default;
#mixin respond-min($width) {
// If we're outputting for a fixed media query set...
#if $fix-mqs {
// ...and if we should apply these rules...
#if $fix-mqs >= $width {
// ...output the content the user gave us.
#content;
}
}
#else {
// Otherwise, output it using a regular media query
#media screen and (min-width: $width) {
#content;
}
}
}
Which you'd use like this:
#include respond-min(45em) {
float: left;
width: 70%;
}
This would be inside all.scss, which would compile down to all.css with media queries. However, you'd also have an additional file, all-old-ie.scss:
$fix-mqs: 65em;
#import 'all';
That simply imports all, but flattens media query blocks given a fake width of 65em.
I use LESS for a lot of my work, but on larger projects, with many people working across files, I don't like using breakpoint files, such as 1024.less.
My and my team use a modular approach, such as header.less which contains all the code for just the header, including the associated breakpoints.
To get round IE problems (we work in a corporate environment), I use this approach:
#media screen\9, screen and (min-width: 40em) {
/* Media queries here */
}
The code inside the media query is always executed by IE7 and less. IE9 and above obeys the media queries like a proper browser should. The problem is IE8. To solve this, you need to make it behave like IE7
X-UA-Compatible "IE=7,IE=9,IE=edge"
I've found this doesn't always work if set in the metatags in the HTML, so set it using the server headers.
See the gist here:
https://gist.github.com/thefella/9888963
Making IE8 act like IE7 isn't a solution that works for everyone, but it suits my needs.
Jake Archibald has the best technique I've seen to date for achieving this. This technique automatically creates a separate stylesheet for IE, with all the same styles inside of your media queries but without the media query itself.
I also campaigned to get this technique built into the popular breakpoint extension for Sass, if you're interested in using that!
If you wanted to keep everything under one roof and only have a single http request for your older browser visitors you could do something like this
Setting up your initial respondto mixin
// initial variables set-up
$doc-font-size: 16;
$doc-line-height: 24;
// media query mixin (min-width only)
#mixin breakpoint($point) {
#media (min-width: $point / $doc-font-size +em) { #content; }
}
this will create a min-width media query and output your px value ($point) as an em value.
From this you'd need to create this mixin
#mixin rwdIE($name, $wrapper-class, $IE: true) {
#if $IE == true {
.lt-ie9 .#{$wrapper-class} {
#content;
}
.#{$wrapper-class} {
#include breakpoint($name) {
#content;
}
}
}
#else if $IE == false {
.#{$wrapper-class} {
#include breakpoint($name) {
#content;
}
}
}
}
Here if you pass a piece of Sass(SCSS) like this
#include rwdIE(456, test) {
background-color: #d13400;
}
it will return this code
.lt-ie9 .test {
background-color: #d13400;
}
#media (min-width: 28.5em) {
.test {
background-color: #d13400;
}
}
This will give you the you the IE and 'new browser' CSS in one file. If you write -
#include rwdIE(456, test, false) {
background-color: #d13400;
}
You will get -
#media (min-width: 28.5em) {
.test {
background-color: #d13400;
}
}
I hope this helps, I've got this on a codepen here too - http://codepen.io/sturobson/pen/CzGuI
There is a CSS3 Mixin I use that has a variable for IE filters. You could do something similar by having a global variable, $forIE or something, wrap the media query mixin within an if and then generate the stylesheet with or w/o the queries.
#if $forIE == 0 {
// Media Query Mixin
}
Or use the #if to import a 3rd scss (_forIE.scss?) that will override things with your IE specific styles.

Declare a global CSS property ? Is this possible?

I have a very wierd question, I dont know wether if its possible in css or not
Suppose I have say 3 different css classes as shown below, as you can see I have a common property of all these classes, I want to declare this color somewhere else and pass a reference to it here, so if next time I want to change the color I can simply change at one place rather than changing in all the 5 classes.
I know that you can use body{}, or a wrapper for this but that would affect the colors of the entire site right ? Is there a way to do this ?
Is this even possible ?
.abc {
color:red;
}
.abc2 {
color:red;
}
.abc3 {
color:red;
}
.abc4 {
color:red;
}
.abc5 {
color:red;
}
The bad news: you can't do it in CSS.
The good news: you can write in a meta-CSS language like LESS, which then processes a LESS file to pure CSS. This is called a "mixin".
In LESS:
#errorColor: red;
.error-color {
color: #errorColor;
}
#error-1 {
.error-color;
}
.all-errors {
.error-color;
}
More info: http://lesscss.org/#-mixins
if you want to declare all of them at a time, you can use:
.abc, .abc2, .abc3, .abc4, .abc5 {
color:red;
}
Or you can declare an additional class & add to all the .abc, .abc2.... & make its color:red;.
This can not be done with CSS, but that is still a very popular thing to do by using a CSS preprocessor such as LESS, SASS, SCSS, or Stylus.
A preprocessor will let you define a variable (say $red = #F00). It will replace the variable in your CSS document with the variable value for you, allowing you to write very DRY and module CSS.
This functionality is referred to as "CSS variables", which is part of the future spec, but not yet implemented on any browsers.
For now, the best way to do this in pure CSS is to declare an additional class for the desired "global", and then add that class to all relevant items.
.abc_global { color: red; }
.abc1 { /* additional styling */ }
.abc2 { /* additional styling */ }
<div class="abc1 abc_global"></div>
<div class="abc2 abc_global"></div>
With LESS
You are able to define that red color once:
.myRedColor {
color:red;
}
Now you can call that red on any CSS styles. Even NESTED styles! It's a wicked tool!
.abc1 {
.myRedColor;
}
.abc2 {
.myRedColor;
}
.abc3 {
.myRedColor;
}
.abc4 {
.myRedColor;
}
NESTED EXAMPLE:
.abc {
.itsEasyAsOneTwoThree{
.myRedColor;
}
}
Now all of our "itsEasyAsOneTwoThree" classes that are properly nested inside of an "abc" class will be assigned the red style. No more remembering those long #867530 color codes :) How cool is that?!
You can also use PostCSS with the plugin postcss-preset-env and support custom properties/variables, then use the :root selector to add global css variables.
:root {
--color-gray: #333333;
--color-white: #ffffff;
--color-black: #000000;
}

How to combine this css?

.box_content ::selection {
background:#CCCC33; /* Safari */
}
.box_content ::-moz-selection {
background:#CCCC33; /* Firefox */
}
Anyone know if I can combine those like this?
.box_content ::selection .box_content ::-moz-selection {
background:#CCCC33;
}
Or maybe like:
.box_content ::selection, .box_content ::-moz-selection {
background:#CCCC33;
}
The second one is correct. You can use a comma to separate css selection rules.
So given:
selector-rule1, selector-rule2 {
style-x;
style-y;
}
This will apply style-x & style-y to anything that matches either selector-rule1 or selector-rule2.
Just to explain why your first example won't work, its because spaces imply ancestor-descendant relationships, so if you have:
selector-rule4 selector-rule4 {
style-z;
}
Then style-z will be applied to anything that matches selector-rule4 if it is also an an ancestor of something that matches selector-rule3.
More info on selectors here.
Your second example should work fine.
You need to use a comma to group the selectors:
.box_content ::selection, .box_content ::-moz-selection {
background:#CCCC33;
}
Your second example can’t work because a browser has to ignore the complete rule:
When a user agent cannot parse the
selector (i.e., it is not valid CSS
2.1), it must ignore the selector and the following declaration block (if
any) as well.
Opera and Webkit can’t parse the Gecko proprietary selector and Gecko can’t parse the regular ::selection. So the rule will never be applied.

Resources