Font-size classes and nested html - html

I've got a problem with CSS inheritance. Here's a simplified version of my stylesheet, where I am trying to control font-sizes in nested divs for my web-app :
CSS:
.type-small {
font-size: 24px;
}
.type-large {
font-size: 48px;
}
.type-small .btn {
font-size: 24px;
height: 28px;
}
.type-large .btn {
font-size: 48px;
height: 82px;
}
When you look at this sample HTML, the innermost type-small isn't used to format the "Save" button. It looks like CSS is picking up the classes irrespective of which is deeper nested in the HTML.
HTML
<div class="type-small">
<div class="type-large">
<button class="btn">Refresh</button>
<div class="type-small">
<p>Sample info </p>
<button class="btn btn-inverse">Save</button>
</div>
</div>
</div>
Take a look at this JSFiddle for an interactive version. Is there any arrangement of the CSS that would make this work (at scale)?
http://jsfiddle.net/HA5zy/

The inheritance ( specificity ) of
.type-large .btn { /* line 29 */
font-size: 48px;
height: 82px;
}
is greater than
.type-small .btn { /* line 25 */
font-size: 24px;
height: 28px;
}
When you mention "CSS is picking up the classes irrespective of which is deeper nested in the HTML." well, it's not the way it works.
To make it short, because your 2 declarations have the same weight, the one written AFTER in your css file will take precedence and be applied.
You can correct your situation by giving more specificity to your declarations like so:
.type-small .btn, .type-large .type-small .btn { /* enhence the weight */
font-size: 24px;
height: 28px;
}
Take note that the use if !important is discouraged and will lead you to another kind of problem sooner or later, like having the oposite html construction where you'll have a .type-large inside a .type-small.
One other thing, this point was raised by user Lucky Soni, you should consider constructing with minimum markups. Meaning, your whole html could be reformated to something like this :
<button class="type-large btn">Refresh</button><br/>
<p class="type-small">Sample info </p><br/>
<button class="type-small btn">Save</button>
jsFiddled here
See http://www.w3.org/TR/CSS2/cascade.html#specificity for more details and a better comprehension of cascading style.
6.4.1 Cascading order
To find the value for an element/property combination, user agents
must apply the following sorting order:
Find all declarations that apply to the element and property in question, for the target media type. Declarations apply if the
associated selector matches the element in question and the target
medium matches the media list on all #media rules containing the
declaration and on all links on the path through which the style sheet
was reached.
Sort according to importance (normal or important) and origin (author, user, or user agent). In ascending order of precedence:
user agent declarations
user normal declarations
author normal declarations
author important declarations
user important declarations
Sort rules with the same importance and origin by specificity of selector: more specific selectors will override more general ones.
Pseudo-elements and pseudo-classes are counted as normal elements and
classes, respectively.
Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins.
Declarations in imported style sheets are considered to be before any
declarations in the style sheet itself.

Why use additional markup just to apply these simple classes?
Modify your markup like:
<div class="type-small">
<button class="type-large btn"></button>
</div>
CSS:
.type-small {
font-size: 24px;
}
.type-large {
font-size: 48px;
}
.type-small.btn {
font-size: 24px;
height: 28px;
}
.type-large.btn {
font-size: 48px;
height: 82px;
}
Fiddle: http://jsfiddle.net/z7nzv/1/

.type-small {
font-size: 24px;
}
.type-large {
font-size: 48px;
}
.type-small>.btn {
font-size: 24px;
height: 28px;
}
.type-large>.btn {
font-size: 48px;
height: 82px;
}
Just specify that the .btn is an immediate child of the .type-x with the '>'.

Change your third class to this: (Notice the addition of "button")
.type-small button.btn {

Add the !important attribute like this:
.type-small .btn {
font-size: 24px!important;
height: 28px!important;
}

Related

How can I use an element's data-etc attribute value for CSS property values?

I want to use multiple data attribute in single css. So is that possible.?
I had created css given blow, i want to use data-letters and data-color both in css but it is not working.
data-color will placed at background and data-letters will placed at content in css
body { font-family: sans-serif; }
[data-letters]:before {
content: attr(data-letters);
display: inline-block;
font-size: 32px;
width: 85px;
height: 80px;
line-height: 2.5em;
text-align: center;
border-radius: 50%;
background: #95A73B;
vertical-align: middle;
margin-right: 1em;
color: white;
margin-top: 20px;
}
<p data-letters="PB" data-color="#c0227a"></p>
TL;DR:
You can't. No browser supports using attr() for anything except only the content: property on ::before and ::after boxes:
https://developer.mozilla.org/en-US/docs/Web/CSS/attr
https://caniuse.com/mdn-css_types_attr_type-or-unit
Backstory:
CSS's attr() function theoretically allows you to use any element attribute from the DOM for any CSS property value.
However, as of early 2022 you can only use attr() with CSS's content: property, which only applies to the ::before and ::after pseudo-elements.
But you can concatenate multiple attributes within content: though, e.g.:
body { font-family: sans-serif; }
[data-letters]:before {
content: attr(data-letters) ' ' attr(data-color);
display: inline-block;
font-size: 32px;
line-height: 2.5em;
text-align: center;
border-radius: 50%;
background: #95A73B;
vertical-align: middle;
color: white;
}
<p data-letters="PB" data-color="#c0227a"></p>
...but this isn't what you're looking for.
Note that conceptually the attr() function in CSS returns an arbitrary text string value, rather than a "typed" value.
So a string "#aabbcc" is not the same thing as a CSS-color-typed value #aabbcc, which is one of the reasons why we can't do color: attr(data-color);.
Note that even if color: attr(data-color); was supported by browsers, it would be the equivalent of doing color: "#aabbcc" instead of color: #aabbcc, which is invalid, so it wouldn't work anyway even if it was supported.
Hence the need for typed values.
(I note that we can reuse arbitrary custom-properties with real properties regardless of their type, and custom-properties tend to feel like string values (but they aren't) and so it feels inconsistent - but let's just pretend this isn't a thing for now)
...I do agree it is surprising that support for this would be straightforward to implement, and has been an open issue for over 14 years now.
I speculate the reason why browsers don't (yet) support attr() for other properties is because you could just set an inline style="" attribute on the element to get the same end-result (well, except for ::before and ::after, of course, as those boxes don't map 1:1 to a DOM element).
If you want to track implementation progress:
Chrome / Chromium / Blink / Edge, since 2013.
Firefox / Gecko, since 2008.
Safari / Apple WebKit, since 2009
Alternatives
As mentioned, you can use an inline style="" attribute to set properties on a per-element basis; so if you use the inline style to set custom-properties then those custom-properties can be used by any ::before and ::after boxes' style rules without needing to set explicit style properties on their parent, like so:
body { font-family: sans-serif; }
[data-letters]:before {
content: attr(data-letters);
display: inline-block;
font-size: 32px;
line-height: 2.5em;
text-align: center;
border-radius: 50%;
background-color: var(--my-color);
vertical-align: middle;
color: white;
}
<p style="--my-color: #c0227a;" data-letters="PB"></p>
...though I agree this is inelegant and necessarily means duplicating values in both data- attributes and inside the style="" attribute (assuming you wanted to keep the data- attributes too).

css is prioritised by direction, requires !importrant?

I have this code:
[dir="ltr"] [icon-start] icon {
padding-right: 0.3em;
}
[dir="rtl"] [icon-start] icon {
padding-left: 0.3em;
}
.custom-icon {
padding: 0;
}
And when I do:
<div dir="ltr">
<div icon-start>
<icon class="custom-icon"></icon>
</div>
</div>
The icon element combines the first and the third rules to be padding of 0 0.3em 0 0
This is not the desired behavior. I want css to work normally as it always does, and have the last rule be the shot-caller.
2 possible solutions, that are not welcomed:
add =!important to .custom-icon - not welcomed, as I want to minimise the use of !important + I structured my code such that I don't need to use important.
add directional rules for .custom-icon. undesired because it bloats my bundle size (this needs to happen in like a 1000 places), it is not very friendly, and generally can be misunderstood.
Something like:
[dir="ltr"] .custom-icon, [dir="rtl"] .custom-icon {
padding: 0
}
Is there a way I can tell css to ignore [dir] rules in the priority structure?
Is there a way I can tell css to ignore [dir] rules in the priority structure?
No, you can't have one rule delete arbitrary other rules from the cascade.
You're going to have to match the specificity of the other rules if !important is not an option:
[dir] [icon-start] .custom-icon {
padding: 0;
}
(Technically, you'd also need the icon type selector to really match the specificity of the other rules, but since a class selector is more specific anyway the type selector is not necessary.)
Alternatively, you could exclude .custom-icon from the other rules so you don't have to worry about overriding them:
[dir="ltr"] [icon-start] icon:not(.custom-icon) {
padding-right: 0.3em;
}
[dir="rtl"] [icon-start] icon:not(.custom-icon) {
padding-left: 0.3em;
}

Changing line spacing between Bandsintown events

I am using the Bandsintown widget for one of my own sites (Not Wordpress, etc.) and can't figure out how to increase the line spacing between events. Is it even possible? Too keep inline with the overall formatting of the site, I'd like there to be a bit more space between each. Thanks
.bit-events a {
color: #39B082;
text-decoration: none;
}
.bit-events th,
.bit-events td {
padding: 0!important;
font-family: "font_1";
}
#bit-events th.bit-date {
width: 100px;
}
#bit-events th.bit-date,
#bit-events th.bit-venue,
#bit-events th.bit-location,
#bit-events th.bit-tickets {
color: #39B082;
font-size: 16px;
text-transform: uppercase;
height: 20px;
}
#bit-events td.bit-description-links,
#bit-events th.bit-description-links,
#bit-events {
color: #121212;
}
You likely want to add a relative line-height to your css:
CSS - Line Spacing
#bit-events * {
line-height: 2rem;
}
You can use > for direct descendants, * for all descendants of your container, or specify them individually https://stackoverflow.com/a/21410191/4541045
Otherwise, a border-width may be what you're looking for.
Here's an example of its usage http://www.w3schools.com/cssref/pr_border-width.asp
To find out the value to change and to edit a live copy, you can play with a browser's inspector tool.
Normally this is accessible through some menu, and may be available when right-clicking in a webpage
https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector
https://developer.chrome.com/devtools

How to not display css padding when span element is empty

I've been trying to solve the following problem.
If you run this code you will notice blue and red elements.
How can I hide the 'red element' when there is no text to display (span is empty). And I would like to do the same thing with 'blue element' when there is no text inside it shouldn't be visible.
The reason why is displayed is padding, but I would like to have padding because it looks nice.
I am sure you guys are best of the best and find solution.
Regards!
.myClassDer {
font-size: 34px;
color:white;
background: blue;
color: white;
border-radius: 25px;
padding: 7px;
width: auto;
height: auto;
}
.myClassDie {
font-size: 34px;
color:black;
background: red;
color: white;
border-radius: 25px;
padding: 7px;
width: auto;
height: auto;
}
<span class="myClassDer">here</span>
<span class="myClassDie"></span>
If you don't require support for IE8, you can use pseudo-state :empty (here for more examples ) to reset padding for all instances of .myClassDie without content, using the following code.
.myClassDie:empty
{
padding:0;
}
Updating your working example, it becomes:
.myClassDer
{
font-size: 34px;
color:white;
background: blue;
color: white;
border-radius: 25px;
padding: 7px;
width: auto;
height: auto;
}
.myClassDie
{
font-size: 34px;
color:black;
background: red;
color: white;
border-radius: 25px;
padding: 7px;
width: auto;
height: auto;
}
.myClassDie:empty
{
padding:0;
}
<span class="myClassDer">here</span>
<span class="myClassDie"></span>
<span class="myClassDie">ClassDie but with content</span>
In which I inserted two <span class="myClassDie"> to show you the behaviour with and without content.
Due to effective invisibility of "empty" case, if you want a more compact solution, you can collapse the two separate rules into only one, simply setting:
.myClassDie:not(:empty)
{
font-size: 34px;
color:black;
background: red;
color: white;
border-radius: 25px;
padding: 7px;
width: auto;
height: auto;
}
In this case, only if .myClassDie is not empty, you'll apply all properties.
This is equivalent for this specific case, but if you want to see this DIV also if empty, limiting only to reset padding (for example because it has fixed size or borders), you must use first solution, not the more compact one.
Little precisation about :empty pseudo-class
Previous examples run correctly only if empty elements are effectively empty, this means that this code <span class="myClassDie"></span> is correctly targeted, but this one (that contains a whitespace) <span class="myClassDie"> </span> isn't.
In general, this could be an issue because often code is dynamically generated or otherwise contains white spaces due to code indentation.
In the past, Mozilla introduced its proprietary pseudo-class :-moz-only-whitespace, but no other browser currently supports this yet.
W3 also tried to solve this kind of problems, initially with analogue :blank pseudo-class (again with no browser support) in "Selectors Level 3", but this did not have expected success.
So, since beginning of 2018, W3 modified its definition to represent empty user input, rather than empty elements and contemporarily modified :empty definition to consider also white-spaces, but currently this last feature is not implemented too in different browsers.
Empty pseudo class only checks for empty text
.myClassDie:empty{
padding:0;
}
But for whitespaces use blank pseudo class
.myClassDie:blank{
padding:0;
}
There is a css pseudoclass empty which you could use here:
.myClassDie:empty {
display: none;
}
Your updated JSFiddle
You can do the trick with the CSS3 pesudo-class :empty
span:empty{
padding:0;
}
Note: using above selector you will not have to worry about which span
has value and which one has not. it will reset padding for those span
which are blank (empty).
I guess you could use above piece of code to hide the empty span's padding.
span:empty {
padding: 0;
}
you can you :empty also read the below like.
https://developer.mozilla.org/en-US/docs/Web/CSS/pseudo-classes
.myClassDie:empty {padding:0;}

How to add * with smaller font size in html

I have the text
Coupon*
in font size 30px. However I want to make the * not in 30px but smaller. How can I achieve this?
http://jsfiddle.net/LkLGE/
Thanks
To keep the asterisk aligned on the top, you can put the character in a <sup> tag and reduce its font-size:
<div class="text">Coupon<sup>*</sup></div>
.text {
font-size: 30px;
}
.text sup {
font-size: .5em;
}
JSFiddle example
As an alternative to <span> based answers <sup or <sub> or <small> might be a better starting point from a semantic standpoint.
<sup> is superscript and will raise the *.
<sub> is subscript and will lower the *.
<small> might require adding some css *, but shouldn't already have a position change. See http://www.w3.org/TR/html5/text-level-semantics.html#the-small-element
Fiddle to show it in action: http://jsfiddle.net/6jmKT/
Coupon<span style="font-size:any size that you want">*</span>
I'm not sure about your case, but sometimes you want to do this in many places. Sometimes, you'll have a "new" or "special" item and you'll add a class with javascript to denote this.
Think about if you have to change this somewhere and how many places you might need to edit this span. Of course you could find-and-replace, but try THIS FIDDLE out and see what you think. CSS content() is pretty amazing for stuff like this.
HTML
<div class="thing special">
<!-- where special might be added by javascript -->
Coupon
</div>
CSS
.thing {
font-size: 30px;
color: blue;
}
.special:after {
display: inline-block;
/* so you can use "block" like stuff on it - (margin-top etc) */
/* this way you wouldn't have to change it in the html in a ton of places. just one - here. */
content: "*";
font-size: 15px;
color: red;
/* just for specific positioning */
vertical-align: top;
margin-left: -8px;
margin-top: 5px;
}
OR
sup is totally cool too - I think...
HTML
<p>Coupon<sup class="star">*</sup></p>
CSS
p {
font-size: 30px;
}
p .star {
font-size: 15px;
color: red;
}
When in doubt, put it in a span - FIDDLE
#myspan {
font-size: 10px;
}
This FIDDLE is a bit reductio ad absurdum, but it was fun!
You can use span and you can use <sup> tag:
EXAMPLE
<div class="text">Coupon<span class="star"><sup>*</sup></span></div>
.text {
font-size: 30px;
}
.star {
font-size: 12px;
}
http://jsfiddle.net/LkLGE/4/
The most robust way is to use the small element. If you wish to tune its effect to some specific size reduction, it is best to use a class attribute on it. Example:
<style>
.ast { font-size: 70% }
</style>
...
Coupon<small class=ast>*</small>
However, the asterisk “*” is rather small in many fonts, so size reduction easily makes it too small. If you think you need to reduce its size, you probably need a different font.