At the moment, my usual approach to supporting right-to-left (RTL) languages in a template is to simply add a .rtl class to the body tag, then go through all my existing left-to-right CSS and add left/right overrides as appropriate.
For example, my site menu might be positioned like so by default as below:
.site-nav {
position: absolute;
left: 0;
top: 0;
}
...and then manually overridden for RTL languages this way (using some template logic at a CMS level to add the .rtl class to body):
.rtl .site-nav {
left: auto;
right: 0;
}
My issue is that this seems labour-intensive and not very effecient. I was wondering what solutions others might have come up with to make this simpler.
As an aside, I'm using a Compass environment to generate my CSS. But I don't know how to escape back from the current nesting to write a .rtl modifier adjacent to the current element's default styles. This in theory would be extremely useful, however, but I simply don't know if it's possible to perform a lookup all the way back to the body element or not whilst within a deeply-nested Sass rule.
Add your .rtl-class whereever you want to change the textflow. Even when you don't want to change it (for "normal" languages).
Don't use the class in your default css-file.
Add a css-file which only includes
.rtl {
left: auto;
right: 0;
}
whenever you have a rtl-language. In case you want all your divs to behave that you you could replace .rtl with div as well.
Related
I have a angular project which use a library called smDateTimeRangePicker , it include the code below:
Link Here
.action {
height: 30px;
margin-bottom: 0;
position: absolute;
bottom: 0;
width: 100%; }
However, in my project, there is a code which also include action class
<div flex class="action cell">
And it is impacted by the CSS above, how to avoid it?
This question considered about these points below:
There is a way that can avoid the CSS impact between project and library.
The library uses a bad practice, it must avoid impacting project. It is a bug for the library and must be fixed.
This impact usually happens, so I need to change my project to avoid the conflict
Rename your project action class to something else is the cleanest way. Else you have to resort to fixes that are considered bad practice like !important, however these still get the job done.
this happens to me quite frequently, so to solved it I just add one parent class to my page or that particular section
<div class="my-unique-class">
---
<div class="action">
---
</div>
---
</div>
.my-unique-class .action {
height: 30px;
margin-bottom: 0;
position: absolute;
bottom: 0;
width: 100%;
}
You can avoid such kind of situation by increasing specificity of your css rules.
There are multiple ways to do so:
Include all third party CSS files before your custom file so that css rules with same priority (In Your Case) can override the rule in third party CSS file.
Above solution should work in most of the cases, but there are chances that Third party CSS might come with higher priority orders, so you can increase weight of your css by adding class at your parent tag as:
.parent > .action {
/ * Some CSS Code */
}
<section class="parent">
<div flex class="action cell"></div>
</section>
MDN has great article about CSS Specificity here
If you can't change your class name, you could make your styles unique to your element by doing:
.action.cell {
/*your styles here*/
}
By leaving out the space between action and cell you are saying that both classes are on the same element. Also, make sure you are loading your stylesheet after the 3rd party stylesheet so that your styles are being applied over theirs.
When you have a CSS rule, you can use !important before semicolon:
background: black !important ;
It marks your rule as "important" and it cannot be changed with any CSS file.
Only inline CSS can overwrite it:
style="background: blue !important"
I have a button that is displayed in a lot of pages of my website (With an automated javascript Widget).
I want this CSS :
.app.programEditor .col-2 .actions .widget.bt-flat.programs > .bt-flat-icon {
}
to be applied, and not this one :
.app.programEditor .actions .widget.bt-flat > .bt-flat-icon {
left: 145px !important;
top: 19px !important;
But instead, what happens, is the two css are applied, and as a result I get the second element that overwrites what I want to do with the first CSS ( A blank css with no rules )
Please I really need your help
The root cause of your problem is the poorly written rule that uses !important. This is an excellent example of why not to use !important. If at all possible, try to understand why !important was thought to be needed there, and see if you can remove it.
But if you are left fighting against an important rule, your only choice is to fight fire with fire, and toss back an !important of your own, in a rule designed to take precedence either because it is more specific (in this case, your override rule has seven classes, to the original rules's six, so it is more specific), putting it later in the file if it has the same specificity, or if you have no other choice use the various tricks available to jack up the specificity.
Having said that, overall this CSS seems to be poorly structured, verbose, and inefficient.
.app.programEditor .actions .widget.bt-flat > .bt-flat-icon {
First, if .app is a class applied to your entire application, it is probably not necessary. If .actions only occurs within .app.programEditor, then the latter is not necessary at all. If .bt-flat can only apply to widgets, then instead of widget.bt-flat you can just write .bt-flat. If .bt-flat-icon can only occur within .bt-flat, as seems likely, then .widget.bt-flat may not be necessary. And so on. In general, instead of writing down every single class in the HTML hierarchy in your CSS rules, try to limit selectors to those necessary to unique select the element you want. In this case, for example, it is possible your rule could be written as simply as (just an example):
.programEditor .actions .widget > .bt-flat-icon {
Second, the magic numbers 145 and 19 are a massive code smell. They are probably connected to other magic widths and heights elsewhere in the CSS, and would have to be changed if those change. What do the 145 and 19 mean? Perhaps they are actually a percentage of some underlying dimension. In other words, maybe some element is 160 pixels wide, and we want to place the icon to the upper right. In that case, instead of hard-wiring the 145, you can either use a percentage, or specify a right property, or use the transform property perhaps, so no matter how the width changes--such as with the introduction of .col2--the icon remains in the right place with the original rule.
You can simply change it to position:static this is just a demo. Otherwise, if you understand concept of Specificity very well, then there was no need for this question.
$('#change').click(function() {
$('.one').css("position", "static");
$('.one').text("Position changed to Static")
});
.container {
width: 90%;
margin: 50px auto;
position: relative;
border: 1px solid #000;
display: block;
height: 200px;
overflow: hidden;
}
.one {
width: 150px;
height: 150px;
background: tomato;
position: absolute;
left: 118px!important;
top: 30px!important;
display: block;
color:white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="container">
<div class="one">
Positioned using absolute or relative</div>
</div>
<button id="change">Change CSS</button>
If many rules exist, the first one takes precedence, but if the last one is more specific, it will override the first one. BUT if the first one is less specific AND has !important that one will take precedence. :) To make matters more complicated, if both rules has !important the most specific rule will take precedence.
So the easy solution here, if you cannot change the already existing rule, just add !important to the code you can edit. If that doesn't work, try to get your code processed earlier in the code than the other one.
.app.programEditor .col-2 .actions .widget.bt-flat.programs > .bt-flat-icon {
left: 40px !important;
top: 40px !important;
}
I'm trying to override a particular widget's style using UiBinder. What am I overlooking?
<ui:style>
/*************
* Note #1
*************/
.btnVote {
display: inline-block;
width: 50px;
height: 50px;
background: #fff;
margin: 5px;
text-align: center;
outline: none;
cursor: pointer;
}
/*************
* Note #2
*************/
.btnVote-up-hovering, .btnVote-down-hovering {
background: #ddd;
}
.btnVote-up-disabled, .btnVote-down-disabled {
border-shadow: inset 0 1px 3px #aaa;
}
.lblName {
line-height: 50px;
font-size: 40px;
padding: 5px 10px;
}
.clear {
clear: both;
overflow: auto;
}
.floatLeft {
float: left;
}
</ui:style>
<g:HTMLPanel styleName="{style.clear}">
<g:FlowPanel styleName="{style.floatLeft}">
/*************
* Note #3
*************/
<g:PushButton ui:field="btnVoteUp" stylePrimaryName="{style.btnVote}">
(+)
</g:PushButton>
<g:PushButton ui:field="btnVoteDown" stylePrimaryName="{style.btnVote}">
(-)
</g:PushButton>
</g:FlowPanel>
<g:FlowPanel styleName="{style.floatLeft}">
<g:Label ui:field="lblName" stylePrimaryName="{style.lblName}"/>
</g:FlowPanel>
</g:HTMLPanel>
Note 1: This rule is being applied and works fine
Note 2: This other rules seem to be getting ignored (they don't take effect)
Note 3: The default naming for the widget is being reset, hence Note 1 works fine. The base class is set to GOGXR1SCFI instead of gwt-PushButton
Why aren't they other rules working? When I hover the widget, the class GOGXR1SCFI-up-hovering is indeed set to the widget, but no accompanying CSS.
Thanks for your help.
Update
Something I ran into that gave me a hard time for a while: when you use the #external keyword, you must place a semi-column at the end of the #external statement, as in:
<ui:style>
#external .btnVote;
.btnVote {
...
}
</ui:style>
<g:FlowPanel styleName="{style.btnVote}"/>
One thing you could do is to create your CSS using ClientBundle, define all the different states there, then handle the various states manually. This way you don't need to define classes as #external, and GWT will optimize the CSS for you (shorten the names, only ship what gets used, etc.). This is especially beneficial for custom widgets and such.
The easiest way to deal with this is to write #external .btnVote, .btnVote-up-hovering, .btnVote-down-hovering, .btnVote-up-disabled, .btnVote-down-disabled at the top of your <style> section.
The original GWT widgets do not work well with CSS resources (like the one you have in your UiBinder). They depend on a primary style name that they append things like "up-hovering" to. This is terrible for CSS resources and UiBinders because when you type "up-hovering" it becomes things like SDLFJKS.
The button styles do NOT get obfuscated (so you can read "up-hovering"). Your UiBinder styles DO get obfuscated. You can never make them match as long as obfuscation is going on.
So, the #external keyword tells UiBinder and CssResource not to obfuscate certain styles. Now, when you use {style.btnVote-up-hovering}, that will actually come through to the final HTML, which is where these old-fashioned GWT styles will be applied.
I suspect you have CSS stylenames being obfuscated by GWT in your UIBinder. Reference - garbled css name when styling within UiBinder
Chose the approach you find easier to integrate in your proces. Cheers :)
I've been educating myself. Reading this:
The engine evaluates each rule from right to left, starting from the rightmost selector (called the "key") and moving through each selector until it finds a match or discards the rule. (The "selector" is the document element to which the rule should apply.)
For example:
ul li a {...}
#footer h3 {...}
* html #atticPromo ul li a {...]
Now, some example code SASS outputs for me:
#content #blog {
/* ... */
}
/* line 85, ../sass/screen.scss */
#content #flickr {
/* ... */
}
#content #flickr div p {
/* ... */
}
This seems a bit awkward.. am I doing something wrong? Is this a communication problem between me and Sass? Are we losing it?
Edit:
Some SCSS code:
#flickr {
#include columns(5,8);
background: url('../img/ipadbg.png') no-repeat;
#ipod-gloss {
z-index: 999;
position: relative;
}
div {
margin-top: -80px;
margin-right: 20px;
h2 {
color: $white;
font-size: 24px;
}
p {
margin-top: 40px;
}
}
}
Side Bonus!: The article says browsers (or at least Firefox) search the selectors from right to left. I couldn't understand why this is a more efficient why. Any clues?
You have to find your compromise between maintainability (nesting makes it easier to find your way around in the stylesheet) and rendering performance.
A rule of thumb says you should try to restrict yourself to a three-level nesting and you should avoid to nest IDs if it's not necessary.
However, I think nesting too much is not the biggest issue. As soon as I became aware of the power of mixins, I used them a lot.
For example, this is my often used button mixin:
#mixin small-button($active-color: $active-color, $hover-color: $button-hover-color, $shadow: true)
display: inline-block
padding: 4px 10px
margin:
right: 10px
bottom: 10px
border: none
background-color: $button-color
color: $font-color-inv
+sans-serif-font(9px, 700)
text-align: center
text-transform: uppercase
cursor: pointer
#if $shadow
+light-shadow
&:hover
text-decoration: none
background-color: $hover-color
&:last-child
margin-right: 0
a
color: $font-color-inv
&, &:hover
text-decoration: none
&.disabled
+opacity(0.75)
&:hover
background-color: $button-color
&.active
background-color: $active-color
&.disabled:hover
background-color: $active-color
You see, quite a bit code. Applying such mixins to many elements on your page will result in a big CSS file which takes longer to be interpreted.
In the old fashioned CSS-way you would give each button element e.g. the class .small-button. But this method pollutes your markup with unsemantic classes.
Sass provides a solution though: selector inheritance via the #extend directive.
If you set defaults for your parameter of the mixin, you can also provide a simple class, which uses the mixins with your default:
// Use this mixin via #extend if you are fine with the parameter defaults
.small-button
+small-button
And then you can just inherit from this class in various contexts:
#admin-interface
input[type=submit]
#extend .small-button
The resulting CSS statement aggregates all usages of .small button into one rule with comma-separated selectors:
.small-button, #admin-interface input[type=submit] {
display: inline-block;
...
}
Concluding, a naive usage of Sass can effect your CSS performance. Used wisely, however, it is maintainable thanks to well-structured and DRY code, it leads to proper separation of markup and styling (semantic classes only) and allows for smart and performant CSS code.
SASS is only a language that compiles down to CSS. If you're concerned with SASS' performance in terms of how it runs in the browser, then SASS doesn't enter the equation -- it'll be compiled and served to the browser as regular CSS.
From what I can see of your usage of SASS, there's a couple of things I could suggest:
You don't have to nest everything.
The ability to nest rules inside each-other in SASS is a language feature, but you don't have to do it if it doesn't make sense to do so.
In terms of your general CSS usage:
If the nesting gets too severe/unwieldly, consider using classes where it makes sense.
When it's necessary to use the hierarchy of DOM elements, consider using the [child combinator]: .foo > .bar.
IDs are meant to be unique, thus should always only reference a single element. Most of the time, they can be CSS rules unto themselves -- #content #flickr would become just #flickr, for instance -- and browsers will optimise the lookup for a single ID. The only time you would need something like #id1 #id2 is if #id2 needs to appear in different contexts on different pages.
If your selector contains things like #id div p, that div is either superfluous or serving a specific purpose.
If it's superfluous, change the rule to #id p, which selects any <p> that occurs as a descendant of #id.
If it serves a specific purpose, consider classing the <div> with a class name that describes its purpose -- perhaps <div class="photos-list">. Then your CSS could become .photos-list p, which is far more maintainable and reusable.
Short question is: is the following (an id under another id) not recommended for bloating up the CSS file size?
#product-box #product-photo { width: 200px }
details:
Sometimes in SASS, we might have
#product-box
margin-top: 20px
#product-photo
width: 200px
this way, it means it is "nested" -- that is, #product-photo's style of width 200px is only true within #product-box, and the CSS generated from the SASS is
#product-box { margin-top: 20px }
#product-box #product-photo { width: 200px }
but here we have a redundant #product-box before #product-photo, because #product-photo by itself can uniquely identify the element already.
As a result, the CSS file can become bloated. I wonder if it is recommended to un-indent #product-photo in the SASS file, so that it doesn't need to be nested?
I think we could have a .photo class inside #product-box instead... is it true? But in some cases, we might have 2 photos, or 2 li inside a #product-box, and so using a class cannot uniquely identify an element. If we use jQuery, it is true we can say $('#product-box li:eq(2) to get to any element, but it may introduce bug if somebody add another li without knowing the jQuery code depends on it. Having an id will prevent such bug from happening.
if you're selecting an element by its id, you don't need to have a nested selector - the id has to be uique everytime. if you have a class that has a different style depending on it's parent, you have to use such a nestes selector (but, if a class has the same style in every case, you can drop the parent-selector, too).
example:
#product-box #product-photo { width: 200px }
is the same as
#product-photo { width: 200px }
you could also use a class for that:
.photo { width: 200px }
but: if a photo has a different size in some cases, you have to do something like this:
#product-box .photo { width: 200px }
#another-box .photo { width: 150px }
or, alternatively, define a "default" and a special case:
.photo { width: 200px } // the default
#another-box .photo { width: 150px } // special size for photos inside #another-box
note: i have no idea how to do this in sass (i have no idea what sass is), but i hope this is helping you anyway.
note2: you shouldn't worry about this small effect on the css file-size until you have realy, realy, realy much traffic on your site - it's much more important that everything is readable and easy to understand, otherwise you will get in hell if you have to change something in the future (also, if you wan't to decrease you filesize as much as possible, why do you use such long ids? for breaking that down, wouldn't it be the best to use #a #b #c #d... and so on?)