Here is the SASS code part:
#main-nav{
>ul{
blahblah
}
}
So I want to know the exact mean of the string ">ul" means? I cannot find it in the SASS manual.
Furthermore, can it be translated to stylus?
This the CSS syntax to select the child of an element. See this reference for more on how it works:
This selector matches all elements that are the immediate children of
a specified element. The combinator in a child selector is a
greater-than sign (>). It may be surrounded by whitespace characters,
but if it is, Internet Explorer 5 on Windows will incorrectly treat it
as a descendant selector. So the best practice is to eschew whitespace
around this combinator.
#main-nav {
> ul {
color: red;
}
}
The same in CSS:
#main-nav > ul { color: red }
About > selector you can read here http://net.tutsplus.com/tutorials/html-css-techniques/the-30-css-selectors-you-must-memorize/ (#8)
Related
I switched my Sass compiler from libsass/sassc 3.6.2 to Dart Sass 1.44.0 and now I get this error. I have no idea what that means. Is it a bug?
Error: Invalid parent selector "[type=button]"
╷
312 │ ┌ &a:link,
313 │ │ &a:visited
314 │ │ {
│ └────^
╵
This is the code:
#{$buttonInputs},
div.buttons a,
span.buttons a,
a.button
{
// (some lines omitted...)
&a:link,
&a:visited
{
color: $buttonColor;
text-decoration: none !important;
}
}
And this definition in an imported file:
$buttonInputs: "button, input[type=button], input[type=color], input[type=image], input[type=reset], input[type=submit]";
Why is there a difference between both Sass compilers? And how do I get rid of the error to continue my work?
#AmauryHanser had a good point in the comments on the initial question.
For every type listed in the enclosing selector, and every use of the & in the nested selector, the compiler is going to combine them (exactly as written, no added spaces). Notice how things like button from the enclosing selector list and a from the nested selector become mashed together into a single element buttona because there was no space between & and a:link in the nested selector:
//compiler output
buttona:link, buttona:visited {
color: grey;
text-decoration: none !important;
}
input[type=button]a:link, input[type=button]a:visited {...omitted for brevity...}
input[type=color]a:link, input[type=color]a:visited {...}
input[type=image]a:link, input[type=image]a:visited {...}
input[type=reset]a:link, input[type=reset]a:visited {...}
input[type=submit]a:link, input[type=submit]a:visited {...}
div.buttons aa:link,div.buttons aa:visited {...}
span.buttons aa:link,span.buttons aa:visited {...}
a.buttona:link, a.buttona:visited {...}
It's possible your previous compiler was processing the & operator more intelligently, or just didn't care to report errors on the non-sensical rules that were being produced.
I would recommend:
a) Removing a from your nested selector rules so the :linked and :visited pseudo-classes apply directly on whatever is coming from the enclosing selector
#{$buttonInputs},
div.buttons a,
span.buttons a,
a.button
{
&:link, // a removed
&:visited
{
color: $buttonColor;
text-decoration: none !important;
}
}
or
b) Putting a space between & and a so a:visited and a:link are treated as DOM descendants of whatever the enclosing selector is.
#{$buttonInputs},
div.buttons a,
span.buttons a,
a.button
{
& a:link, // space added
& a:visited
{
color: $buttonColor;
text-decoration: none !important;
}
}
but I would also say that the list of elements coming from the enclosing selector rule is not suitable for the nested selector rule, since a doesn't make sense as a child of input nor does :visited make sense as a pseudo-class of input.
I am new to scss. What is the meaning of *= in the below code ?
div[class*="SnackbarItem-contentRoot"] {
width: 600px;
&[class*="SnackbarItem-variantError"]{
background-color: $orange;
color: $white;
}
}
*= is not SCSS features, it is an attribute selectors used in CSS.
For example, this will select all a element with href attribute whose value contains at least one occurrence of example and apply font size to 2em
a[href*="example"] {
font-size: 2em;
}
In our case, *= means get all div with class whose value contains at least one occurrence of "SnackbarItem-contentRoot"
However &, a parent selector invented by Sass that’s used in nested selectors.
&[class*="SnackbarItem-variantError"] means get all div with class whose value contains at least one occurrence of "SnackbarItem-contentRoot"
Your can find more information about attribute selectors here
> This is CSS Attribute Selector.
It is used to select all html elements whose Attribute or class Attribute is "className" or html Attribute name.
where * means 'All' and '=' match Attribute value.
e.g - it select all div whose className is 'SnackbarItem-contentRoot'
div[class*="SnackbarItem-contentRoot"] {
background: yellow;
width:600px;
}
So, you can use this selector in css as well as in scss file.
Let's assume our html looks something like this:
<a>
<span class="title">Foo</span>
<span class="black-color-important">Bar</span>
Baz
</a>
Let's say .black-color-important stays always black. .title has a color assigned.
On hover, the normal text in the link and the title should switch colors to the $primary-color.
My SCSS for it looks like this:
a:hover, a:hover .title {
color: $primary-color;
}
Is there a better way? Or with other words is there a way, that I don't have to retype a:hover?
(If it would help, I don't care if it's a:hover > .title or a:hover .title in my case the .title would always be a direct child, but I tried to keep the question as open as possible)
Note: this is just an abstract example, not the real use case for it.
If the state of child element depends of its parent state, than you can't write styles without retyping the parent in scss.
But if you want to set a regular styles to a child, you can use BEM methodology and don't retype parent name.
div.parent
div.parent__child
.parent {}
.parent__child {}
I have a question. So in a mixing I am making a reference to the parent selector "&". This works as long as the mixin is not nested. Is there a way to to detect if the mixing is being used in a non nested scenario, or to check if "&" is null?
This works when the mixin call is not nested
=myresponsiveMixin($media)
#if $media == small {
#media only screen and (max-width: $break-small)
#content
#else if $media == medium
#media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
#content
This works great when the mixin call is nested, but will not resolve '&' when not nested
=myresponsiveMixin($media)
#if $media == small {
#media only screen and (max-width: $break-small)
.classInHTMLToAllowMediaQueries &
#content
#else if $media == medium
#media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
.classInHTMLToAllowMediaQueries &
#content
So the question is, if there is a way to be able to check the value of parent selector "&", so I can cover all bases in a single mixin?
#mixin does-parent-exist {
#if & {
.exists & {
color: red;
}
} #else {
.doesnt-exist {
color: red;
}
}
}
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-script
You're trying a wrong solution to solve your issue.
Have a look at how this problem is addressed in powerful SASS frameworks. Let's take Susy by Eric Meyer as a great example.
Let's imagine you've got the following HTML:
<div class="container">
<div class="parent">
<div class="child">
Bla bla
</div>
</div>
</div>
When you call a mixin for the first time, you're doing it simply (the code is in the indented .sass syntax):
$total-columns: 8 // Declaring a varible that will be used by the mixin
.parent
+span-columns(4) // Span four of eight columns
But when you call that for a child element, the proportions would be crooked, because the parent is already proportioned:
.child
+span-columns(2) // This will fail. You want 2 of 8 columns,
// but due to nesting the math is crooked.
// It will be "2 of (4 of 8)".
To address the issue, you provide an optional argument: a context that is used to do the math:
.child
+span-columns(2, 4) // Now the mixin will take 2 parts of 4
// instead of 2 parts of four
The source code for this mixin is available on GitHub.
In short, it creates an optional argument like this (the code is in the CSS-like .scss syntax):
#mixin span-columns(
$columns,
$context: $total-columns
//...
) {
//...
width: columns($cols, $context /*...*/);
//...
}
See how $context has a default value? Thanks to the default value this argument can be omitted. In other words, $context is an optional argument.
When calling this mixin, if $context is not provided (e. g. span-columns(2)), then it is set equal to $total-columns. The $total-columns variable should be set prior to calling the mixin for the first time (see my example above).
Then the two arguments are used to calculate the width.
UPD 2013-03-30
I am not trying to figure out things in regards to columns... I have modifier my question to make it clearer.
First of all, my recommendation concerns not only grid columns. It's a universal technique you can adopt.
Secondly, now i see that you're trying to nest media queries.
Well, some media queries of different type can be combined in CSS3: e. g. print and width. But you can't put a min-width: 601px inside max-width: 600px, this just won't work!
There's an extensive answer here on StackOverflow describing why you should not nest media queries of the same type: https://stackoverflow.com/a/11747166/901944
Thirdly, you're trying to invent the wheel. There's already a fantastic mixin for crunching media queries: Respond To by Snugug. It's super easy to use and very effective.
Fourthly, the XY thing. Instead of asking about your crooked mixin, please describe the problem that you're trying to solve with it! Show us the actual HTML and explain what behavior you would like to achieve.
We will show you that it can be solved with a simple, elegant, semantic solution that does not require SASS hacking.
I have an outer div with a variable height (and max-height) that's set with a specific pixel amount by JavaScript, containing two divs within.
The 1st div is intended to hold a variable amount of content, e.g. a list of links. It has no height set.
The 2nd div is intended to hold a fixed amount of content, and has a specific height set.
Right now, the max-height isn't working. The 1st div keeps growing, even with overflow: auto; set, and pushes the 2nd div below it outside the bounds of the outer div. How can I make it so that when the 1st div gets too large for the outer div to contain both it and the fixed-height 2nd div, the 1st div will start to scroll?
Example page: http://thevastdesign.com/scrollTest.html
Thanks for any help. I'd appreciate a CSS solution the most, even if it requires some hacks. It only has to work in Firefox 3+, IE8, and IE7.
Ideas?
You cant really do that without JS. Your max-height on the outer-div isnt going to control the height of one of your inner divs to invoke its scrolling. That inner div is always going to be the height you set (pixels, auto, etc..). You can either make the entire outer div scroll as needed by using overflow: auto or you can set a max height on the first inner div and set the overflow.
Given your setup, I would do the following (class names are implied by your question, not taken from the linked source):
div.outer {
position: relative;
max-height: $length(y);
overflow: hidden;
}
div.innerFixed {
position: absolute;
bottom: 0;
height: $length(y);
overflow: hidden; /* just in case, to keep things from
blowing out into all manner of crazy */
}
div.innerFlex {
max-height: $length(y);
overflow: auto;
}
These rules don't address box properties, which will have an impact on the height values that you apply. The combined height values (with box values included) of .innerFixed and .innerFlex should equal the height value of the container.
If you want to get all Zen and flip the vertical composition, you do that by swapping bottom for top on .innerFixed and assigning margin-top or padding-top to .innerFlex.
Something else I noticed is that you've got
div.outer { float: left; }
...But given what you need from that element (and to set the right content priority) I would instead suggest that you put your big column first in the source order and apply
div.mainContent {
float: right;
width: $length(x);
}
div.outer { /* i.e., the column that started the discussion */
margin-right: length(x);
}
with the understanding that the margin-right of the latter is somewhat greater than the width of the former (greater to account for the gutter between the two elements). Try it, you'll like it.