Access HTML attribute value in SASS - dom

Is it possible to access an HTML attribute value in SASS?
I have a line of code that says
<ul id="my_id" data-count="3">
where the 3 is the result of some jQuery stuff. I need the 3 to calculate some CSS. How can I save it as a SASS variable?
Alternatively, is there a way of counting the number of child elements of a certain parent element? Say I have this code:
<ul id="my_id" data-count="3">
<li>First list item</li>
<li>Second list item</li>
<li>Third list item</li>
</ul>
(As you might have guessed, the value of data-count matches the number of list items.) Can SASS count the list items and save that number as a variable?
Any ideas would be greatly appreciated.

Sass is just a CSS generator. It doesn't really interact with your HTML, so you can't use HTML attributes as Sass variables.
However, CSS can select based on attributes. So it will be more long-winded than you might like, but you can do something like
ul[data-count="3"]:after
content: "There were three items in that list!"
And I think if you're willing to limit yourself only to a subset of very recent browsers†, you can use the CSS calc() function along with attr() to use the attribute in CSS-based calculations. But that's pretty bleeding edge.
† To be perfectly honest, I have no idea which versions of which browsers have fully implemented this. I'm pretty sure Firefox has it, though I've not used it, and I have no idea about other browsers. It is certainly not well-supported, at any rate.

It seems like you are trying to get the number of items inside your unordered list in CSS (maybe to change their size according to the number of siblings?).
Indeed, you cannot use a data-attribute as a Sass variable. However there is a pure CSS way to apply conditional styles given the number of items in the parent. Plus, it is very easily written in Sass.
Let's say your maximum number of items in your list is 10 and you want to compute the size of li tags based on the number of li tags there is in your list.
#for $i from 1 through 10 {
li:first-child:nth-last-child(#{$i}),
li:first-child:nth-last-child(#{$i}) ~ li {
width: (100%/$i);
}
}
This will output the following CSS:
li:first-child:nth-last-child(1),
li:first-child:nth-last-child(1) ~ li {
width: 100%;
}
li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li {
width: 50%;
}
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
width: 33.33333%;
}
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {
width: 25%;
}
li:first-child:nth-last-child(5),
li:first-child:nth-last-child(5) ~ li {
width: 20%;
}
li:first-child:nth-last-child(6),
li:first-child:nth-last-child(6) ~ li {
width: 16.66667%;
}
li:first-child:nth-last-child(7),
li:first-child:nth-last-child(7) ~ li {
width: 14.28571%;
}
li:first-child:nth-last-child(8),
li:first-child:nth-last-child(8) ~ li {
width: 12.5%;
}
li:first-child:nth-last-child(9),
li:first-child:nth-last-child(9) ~ li {
width: 11.11111%;
}
li:first-child:nth-last-child(10),
li:first-child:nth-last-child(10) ~ li {
width: 10%;
}
Basically, this gives the li tags a width of:
100.0% when there is only one li tag
50.00% when there are 2 li tags
33.33% when there are 3 li tags
25.00% when there are 4 li tags
20.00% when there are 5 li tags
16.66% when there are 6 li tags
14.28% when there are 7 li tags
12.50% when there are 8 li tags
11.11% when there are 9 li tags
10.00% when there are 10 li tags
For a live example, please refer to this demo I did using the same trick. I hope it helps.

If you want to access an HTML attribute from CSS, you can use attr()
Check the doc

Related

Max image width for columns in gridelements

I have some grids, where i can choose the column width via flexform (33.3% - 33.3% - 33.3% or 25% - 50% - 25%, …)
I get the max-width of the columns by using CASE with the flexform-field value and the max-width of the page:
…
3 < lib.gridelements.defaultGridSetup
3 {
columns {
1 < .default
1.renderObj = COA
1.renderObj {
10 = LOAD_REGISTER
10.colMaxWidth.cObject = CASE
10.colMaxWidth.cObject {
key.data = field:parentgrid_flexform_style
default = TEXT
default.value =
col-1-2-1 = TEXT
col-1-2-1.value = {$maxContentWidth} / 4
col-1-2-1.prioriCalc = 1
col-4-3-3 = TEXT
col-4-3-3.value = {$maxContentWidth} / 10 * 4
col-4-3-3.prioriCalc = 1
col-1-1-1 = TEXT
col-1-1-1.value = {$maxContentWidth} / 3
col-1-1-1.prioriCalc = 1
}
20.textmedia.dataProcessing.20.maxGalleryWidth.stdWrap.data = register:colMaxWidth
30 = RESTORE_REGISTER
}
2 < .1
2 {
renderObj.10.colMaxWidth.cObject {
col-1-2-1.value = {$maxContentWidth} / 2
col-4-3-3.value = {$maxContentWidth} / 10 * 3
}
}
3 < .1
3 {
renderObj.10.colMaxWidth.cObject {
col-4-3-3.value = {$maxContentWidth} / 10 * 3
}
}
}
...
}
}
This will work fine. But I don’t know what to do, if using nested grids? Then I have to get the flexform-values of the parent gridelement.
Or what is your solution to calculate the max—image-width for grid-columns?
be careful with the calculated size. especially if you use responsive layouts. in responsive layouts columns could be wider on a smaller screen as columns may appaer beneath each other than side by side.
in general: you don't have an easy way to calculate the column width of stacked gridelements. you could do very complicated TS configuration, or you might use an userfunc to solve the computation in PHP.
Did you try to use gridelements together with fluidtemplates?
In the meantime I use this in all my defined grid-elements.
Don't do this on the server side, because the server will not get noticed, when a client changes its browser dimensions. The solution to your problem can easily be fixed by using some CSS. Lets assume you do not render the width directly, but use classes for a grid-system like bootstrap and your rendered gridelement HTML structure looks like this:
<div class="row">
<div class="columns column-2"></div>
<div class="columns column-8"><img src="someimage.jpg" width="800" height="400" /></div>
<div class="columns column-2"></div>
</div>
Your column CSS would probably look like this:
.row{
width: 100%;
}
.row:after{
content: '';
clear: both;
height: 0px;
visibility: hidden;
}
.columns{
float: left;
}
.column-2{
width: 33%;
}
.column-8{
width: 66%;
}
Now you want the images inside the columns to resize with the columns themselfes. A simple max-width: 100%; should do that like so:
.columns img{
max-width: 100%;
}
Since you are using registers anyway, you can include the already calculated register to calculate the amount on deeper levels of the nested structure.
Registers are working like a stack, so with each LOAD_REGISTER you will add a new value to the register stack of colMaxWidth, with each RESTORE_REGISTER you will remove that value in favor of the former value in the stack.
While this is not recommendable performancewise, you can still calculate nested amounts by including the register into the calculation as long as the result gets cached.
When you are on highly dynamic pages with more ore less uncacheable results, you should go for another solution though.
Why don't you use the image editor in TYPO3 V7 Media-Tab?
Screenshot of the image-editor — sorry, but in German

Adding costum styles to Typo3 RTE. Some are not saved

I add costum styles to the RTE with a CSS File:
RTE.default.contentCSS = EXT:netjapan/Resources/Public/css/rte.css
For some elements this works. For example for a ulElement:
ul.liststyle1 {
list-style: none;
padding-left: 17px;
}
When I select the ul in the RTE I can chose the Blockstyle liststyle1.
I want to do the same for p:
p.test {
font-size: 80%;
}
And when I select the p I can chose the Blockstyle test and the style is used. But when I save the Blockstyle is gone.
I added this Typoscript:
RTE.default {
removeTags = sdfield, strike
proc.entryHTMLparser_db.removeTags = sdfield, strike
}
So that p is not in the removeTags list. But it had no effect.
Anyone know how it comes that the Blockstyle is removed on the pElement?
I had simillar problem last week. Sometimes RTE is going crazy. I mean that there is no logical sense in it. Check this: marke the text and use the container style it will wrap it in div but there will be also <p> in it so you will have something like <div><p class="bodytext">text</p></div> - you can add style for that. At least this solved my problem

ng-class not evaluating the expression

I'm trying to implement ng-class in my angularJs application but for some reason expression in the ng-class is not getting applied, any thoughts?
<span>{{prod.item.count}}</span>
<div ng-class="{'show-error-box' : prod.item.length< 1}" class="hide-error-box">
prod is my controller alias in the view and item is the scope object in my controller
I want the class 'show-error-box' when the number of items is less than 1 otherwise apply the class hide-error-box. As I don't have any test data to test this with 0 length i'm replacing the expression with ng-class="{'show-error-box' : 0< 1}" in which case show-error-box should get applied, but it is not happening.
CSS:
.hide-error-box {
display:none;
}
.show-error-box {
float: left;
width: 100%;
background: #fff;
text-align: center;
padding: 10% 0;
height: 700px;
position: absolute;
}
ng-class does not serve as a replacement to "class". It will add any classes whose name is a key in your object if the associated value is true.
The only two options this div will have as a result are:
class="hide-error-box"
or
class="hide-error-box show-error-box"
To acheive the desired effect you would could put the opposite condition as a value of your hide class.
ng-class="{hide-error-box: prod.item.length >= 1, show-error-box: prod.item.length < 1}"
However, it is often recommended that you keep your templates as free from logic as possible. It may be worth considering placing this in a controller function:
HTML
<div class="{{getSizeClass()}}">
JS
this.getSizeClass = function() {
if (item.length >= 1) {
return 'hide-error-box'
}
return 'show-error-box'
}

class overrule when two classes assigned to one div

I was creating a <div> tag in which I wanted to apply two classes for a <div> tag which would be a thumbnail gallery. One class for its position and the other class for its style. This way I could apply the style, I was having some strange results which brought me to a question.
Can two classes be assigned to a <div> tag? If so, which one overrules the other one or which one has priority?
Multiple classes can be assigned to a div. Just separate them in the class name with spaces like this:
<div class="rule1 rule2 rule3">Content</div>
This div will then match any style rules for three different class selectors: .rule1, .rule2 and .rule3.
CSS rules are applied to objects in the page that match their selectors in the order they are encountered in the style sheet and if there is a conflict between two rules (more than one rule trying to set the same attribute), then CSS specificity determines which rule takes precedence.
If the CSS specificity is the same for the conflicting rules, then the later one (the one defined later in the stylesheet or in the later stylesheet) takes precedence. The order of the class names on the object itself does not matter. It is the order of the style rules in the style sheet that matters if the CSS specificity is the same.
So, if you had styles like this:
.rule1 {
background-color: green;
}
.rule2 {
background-color: red;
}
Then, since both rules match the div and have exactly the same CSS specificity, then the second rule comes later so it would have precedence and the background would be red.
If one rule had a higher CSS specificity (div.rule1 scores higher than .rule2):
div.rule1 {
background-color: green;
}
.rule2 {
background-color: red;
}
Then, it would take precedence and the background color here would be green.
If the two rules don't conflict:
.rule1 {
background-color: green;
}
.rule2 {
margin-top: 50px;
}
Then, both rules will be applied.
Actually, the class that defined last in the css - is applied on your div.
check it out:
red last in css
.blue{ color: blue; }
.red { color: red; }
<div class="blue red">blue red</div>
<div class="red blue">red blue</div>
vs
blue last in css
.red { color: red; }
.blue{ color: blue; }
<div class="blue red">blue red</div>
<div class="red blue">red blue</div>
If you asking about they have same property then as per the CSS rule it's take the last statement.
<div class="red green"></div>
CSS
.red{
color:red;
}
.green{
color:green;
}
As per the above example it's take the last statement as per css tree which is .green.
The class that is defined last in the CSS have priority, if nothing else applies.
Read up on CSS priority to see how it works.
Many classes can be assigned to an element, you just separate them with a space
<div class="myClass aSecondClass keepOnClassing stayClassySanDiego"></div>
Because of the cascade in CSS, the overwriting rules closest the to bottom of the document will be applied to the element.
So if you have
.myClass
{
background: white;
color: blue;
}
.keepOnClassing
{
color: red;
}
The red color will be used, but not the background color as it was not overwritten.
You must also take into account CSS specificity, if you have a more specific selector, this one will be used:
.myClass
{
background: white;
color: blue;
}
div.myClass.keepOnClassing
{
background: purple;
color: red;
}
.stayClassySanDiego
{
background: black;
}
The second selector here will be used as it is more specific.
You can take a look at it all here.

How to: Fixed Table Header with ONE table (no jQuery)

I know, there are at least 3 dozen questions like this on stackoverflow and still, I could not make this happen:
A simple table where thead is sticked/fixed at the top, and the tbody is scrolled.
I tried so much in the past days and now I ended up here crying for help.
A solution should work in IE8+ and newest FF, Chrome & Safari.
The difference to other "possible duplicates like this one is that I don't want to use two nested tables or jQuery (plain javascript is fine though).
Demo of what I want:
http://www.imaputz.com/cssStuff/bigFourVersion.html.
Problem is it doesn't work in IE, and I would be fine to use some JS.
Ok i got it:
You need to wrap the table in two DIVs:
<div class="outerDIV">
<div class="innerDIV">
<table></table>
</div>
</div>
The CSS for the DIVs is this:
.outerDIV {
position: relative;
padding-top: 20px; //height of your thead
}
.innerDIV {
overflow-y: auto;
height: 200px; //the actual scrolling container
}
The reason is, that you basically make the inner DIV scrollable, and pull the THEAD out of it by sticking it to the outer DIV.
Now stick the thead to the outerDIV by giving it
table thead {
display: block;
position: absolute;
top: 0;
left: 0;
}
The tbody needs to have display: block as well.
Now you'll notice that the scrolling works, but the widths are completely messep up. That's were Javascript comes in.
You can choose on your own how you want to assign it. I for myself gave the TH's in the table fixed widths and built a simple script which takes the width and assigns them to the first TD-row in the tbody.
Something like this should work:
function scrollingTableSetThWidth(tableId)
{
var table = document.getElementById(tableId);
ths = table.getElementsByTagName('th');
tds = table.getElementsByTagName('td');
if(ths.length > 0) {
for(i=0; i < ths.length; i++) {
tds[i].style.width = getCurrentComputedStyle(ths[i], 'width');
}
}
}
function getCurrentComputedStyle(element, attribute)
{
var attributeValue;
if (window.getComputedStyle)
{ // class A browsers
var styledeclaration = document.defaultView.getComputedStyle(element, null);
attributeValue = styledeclaration.getPropertyValue(attribute);
} else if (element.currentStyle) { // IE
attributeValue = element.currentStyle[vclToCamelCases(attribute)];
}
return attributeValue;
}
With jQuery of course this would be a lot easier but for now i was not allowed to use a third party library for this project.
Maybe we should change a method to archieve this goal.Such as:
<div><ul><li>1</li><li>2</li></ul></div> //make it fixed
<table>
<thead>
<tr><th>1</th><th>2</th></tr>
</thead>
<tfoot></tfoot>
<tbody></tbody>
</table>
Of course, this is not good to sematic.But it is the simplest way without js or jq.
Don't you think so?