How can I combine the same CSS properties for different elements? - css

I have two elements: tooltip and tooltip-line.
There is common properties for each elements:
[tooltip]::after, [tooltip-line]::after {
position: absolute;
opacity: 0;
visibility: hidden;
/* Other common properties */
}
Next, I have different properties for each element.
[tooltip-line]::after { /* One line tooltip */
content: attr(tooltip-line);
white-space: nowrap;
}
[tooltip]::after { /* Multiline tooltip */
content: attr(tooltip);
width: 200px;
white-space: normal;
}
Is this a correct usage? Including similar classes. Or should I copy all properties to each declaration block?

Here's a different approach which might be slightly more scalable. Using CSS custom variables, we can override any default class values by resetting them in the multiline class. Finally, I would make the attributes containing the tooltip content identical—and valid data attributes—if possible.
.tooltip::after {
--tooltip-white-space: nowrap;
content: attr(data-tooltip-content);
white-space: var(--tooltip-white-space);
}
.tooltip.multiline::after {
--tooltip-white-space: normal;
}
.container {
width: 250px;
border: 1px solid red;
}
<div class="container">
<div class="tooltip" data-tooltip-content="my tooltip content should not wrap no matter what"></div>
<div class="tooltip multiline" data-tooltip-content="my multliline tooltip content should wrap"></div>
</div>
jsFiddle

It's absolutely right to divide the css in multiple blocks.
One of the first thing to know while writing code in any language is NOT to repeat yourself.

Related

Change the size of the number input spinner?

On a number input it has a spinner which has several css properties but I can't seem to find a way to change the size of the spinner itself. I am talking about <input type='number'>. I tried finding something that would change the size but I haven't been able to find anything. The other issue I guess is that every browser on possibly every OS is going to have a potentially different implementation of the spinner itself. When I say spinner I am talking about the highlighted part of this image.
I cannot use the JQuery UI spinner because the large app I am developing uses JQuery UI 1.8 which did not include the spinner. Upgrading causes issues.
Not ideal, but try playing around with the CSS transform property:
For example,
input[type=number]
{
transform: scale(2);
}
This increases the size of the entire input, but maybe this (in conjunction with setting font-size, line-height, height, width) can produce a desired effect.
This CSS seems to work in Chrome by replacing the spinners with a static image (of a spinner) and then control the size and position of the image within the element and making it invisible by default until the user hovers over it:
* Spin Buttons modified */
input[type="number"].mod::-webkit-outer-spin-button,
input[type="number"].mod::-webkit-inner-spin-button {
-webkit-appearance: none;
background: #0F0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAKUlEQVQYlWNgwAT/sYhhKPiPT+F/LJgEsHv37v+EMGkmkuImoh2NoQAANlcun/q4OoYAAAAASUVORK5CYII=) no-repeat center center;
width: 3em;
border-left: 1px solid #0f0;
opacity: 0; /* shows Spin Buttons per default (Chrome >= 39) */
position: absolute;
top: 0;
right: 0;
bottom: 0;
}
input[type="number"].mod::-webkit-inner-spin-button:hover,
input[type="number"].mod::-webkit-inner-spin-button:active{
box-shadow: 0 0 2px #0CF;
opacity: .7;
}
Plain ole HTML...
No library or images required.
HTML
<!-- Score Control Container -->
<div class = "Score-Control">
<div class = "Score-Value-Container">
<div id="RoundScore" class="Score-Value">
10
</div>
</div>
<div class = "Score-UpDown">
<div class = "Score-Button-Container">
<div class = "Score-Button " onclick="IncrementScore();">
▲
</div>
</div>
<div class = "Score-Button-Container">
<div class = "Score-Button " onclick="DecrementScore();">
▼
</div>
</div>
</div>
</div>
CSS
.Score-Control {
width: 200px;
}
.Score-Value-Container{
position:relative;
display: table;
overflow: hidden;
height:80px;
background-color:#aaa;
width:66%;
float:left;
font-size: 44px;
vertical-align: middle;
text-align: center;
}
.Score-Value {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.Score-UpDown{
position:relative;
height:80px;
background-color: burlywood;
width:34%;
float:right;
}
.Score-Button-Container {
display: table;
height: 50%;
width: 100%;
overflow: hidden;
background-color:green;
}
.Score-Button {
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 27px;
}
JavaScript
function IncrementScore() {
var RoundScore = document.getElementById("RoundScore").innerHTML;
if (RoundScore < 10) {
RoundScore++
document.getElementById("RoundScore").innerHTML = RoundScore;
}
}
function DecrementScore() {
var RoundScore = document.getElementById("RoundScore").innerHTML;
if (RoundScore > 1) {
RoundScore--
document.getElementById("RoundScore").innerHTML = RoundScore;
}
}
Code in JSFiddle
You could make an input field with two buttons for up and down and style them then the way you like.
<input type="text" name="something">
<span class="goUp"></span>
<span class="goDown"></span>
js:
var inputField = $('input[name="something"]');
$('.goUp').click(function() {
inputField.val(inputField.val() + 1);
});
$('.goDown').click(function() {
inputField.val(inputField.val() - 1);
});
you then should also check, that the input has only numbers inside, so that your +/- 1 really works.
The “size of the spinner” is a vague concept, but the <input type=number> element seems to obey at least width, height, and font property settings. Example:
<input type=number value=42 min=0 max=99
style="font: 24pt Courier; width: 3ch; height: 3em">
Whether such settings are useful and whether they should work is a different issue. It can be argued that the implementation of such elements is expected to be a browser-dependent nice, useable widget suitable for the browsing conditions, rather than something that authors should mess around with. But in practice, the widget is largely affected by CSS settings, and this might be a good thing in practice, e.g. because the input box tends to be too wide by default. (We could expect browsers to set it according to min and max values, but this just doesn’t happen at present.) The risk is that by setting the width, you might conflict with the implementation. The code above expects the up and down arrows to take a width of one character at most, but this guess might some day be wrong.

Why element has various height depending on whether it has content or not [duplicate]

This question already has answers here:
Why my inline-block divs are not aligned when only one of them has text? [duplicate]
(4 answers)
Closed 8 years ago.
I am curious to know why following elements have various heights:
<i class="icon"></i>
<i class="noicon"></i>
i {
display: inline-block;
width: 1em;
height: 1em;
}
i.icon:before { content: 'Ω'; }
i.noicon:before { content: ''; }
That case may be illustrated by http://jsfiddle.net/pJw9d/ (hover the symbols with pointer to view the difference in sizes).
PS: I know how to fix such problem (e.g., by using non-breaking space ( or \00a0), or by defining CSS positions), but I would like to know why it behaves that way.
Try adding "vertical-align" to your css attributes for i:
i {
display: inline-block;
width: 1em;
height: 1em;
background: green;
vertical-align: top; //add this
}
Updated Fiddle
As #anddoutoi correctly pointed, that behavior is explained in W3C Recommendations:
If the box does not have a baseline, align the bottom margin edge with the parent's baseline.
That fiddle demonstrates, that it is not that empty element's size increases, but that it is risen for the baseline height.
Such jumps can be avoided either
by replacing the empty content with non-breaking space, e.g.:
i.noicon:before { content: '\00a0'; }
or by defining the vertical-align property.
Hi Please let me know this is what you need?
html
<div><i class="icon"></i><i class="noicon"></i></div>
<div><i class="icon"></i></div>
css
body {
font-size: 2em;
}
div {
float:left;
}
i {
display: block;
width: 1em;
height: 1em;
background: green;
float:left;
}
i.icon:before {
content:'Ω';
}
i.icon:hover:before {
content:'';
}

Simple CSS3 transition

I can't get transition to work with this code
Changing text-align for left to right. Very simple code.
<style>
/* Default State */
div {
background: green;
width: 1000px;
height: 100px;
line-height: 100px;
color: white;
text-align: left;
transition: all 10s;
-webkit-transition: all 10s;
}
/* Toggled State */
input[type=checkbox]:checked ~ div {
text-align: right;
}
</style>
<label for="toggle-1">Do Something</label>
<input type="checkbox" id="toggle-1">
<div>Control me</div>
Also what if i need to display none to block
The text-align property cannot be animated in CSS, as you can see here. Although this cannot be animated with plain CSS, you can use the jQuery library, as I do in the example below:
$("input[type=checkbox]").click(function (e) {
if ($(this).prop("checked")) {
var spanItem = document.getElementsByTagName("span").item(0).clientWidth;
alert(spanItem);
$("span").animate({
width: $(this).textWidth()
}, 500);
}
});
The code above is a sample from what I've written in this JSFiddle.
Text-align isn't supported by CSS Transition (like maximgladkov said). There are lots of alternatives though.
https://developer.mozilla.org/en-US/docs/CSS/CSS_animated_properties
On a small sidenote; you might want to wrap your labels around your input elements.
I think text-align property cannot be animated.
But you can add another element with position: absolute and animate it's left or right property.

How can I use the less pre-processor to handle different styles with two divs one after the other?

I have the following HTML:
<div class="float-left inline orderby">
<div class="arrow up" style="margin-bottom: 2px; margin-left: 2px"></div>
<div class="arrow down" style="margin-left: 2px;"></div>
<input type="checkbox" data-ng-model="inverse" style="margin-left: 0px; margin-right: 10px;">
</div>
I'm trying to use the less pre-processor to create my CSS.
How can I use less to create CSS to remove the styles from this example. In particular I am not sure how to handle the difference between the 1st and 2nd DIV
You mean you want to remove the inline styles?
.orderby .arrow, .orderby input {
margin: 0;
&.up {
/* styles for first div */
}
&.down {
/* styles for second div */
}
}
It's a little unclear exactly what your question is. I can read it two ways:
(1) You cannot remove css set with style with LESS
If you actually have a style property on your html elements, then that cannot be directly affected by LESS at all (so it cannot be "removed" by LESS). Additionally, the only way to overcome those styles with LESS is by using the exact same solution you would have available with CSS, the !important attribute (which I despise, but the facts are the facts when it comes to what is available for CSS styling). So this would remove the margins imposed by the style for all direct children in your div (as your example has):
.orderby > * {
margin: 0 !important;
}
But perhaps you want to know how...
(2) You can move the code from the style to the LESS
In which case, it is something like this:
LESS
.orderby {
.arrow {
margin-left: 2px;
&:first-child { /* or could use &.up */
margin-top: 2px;
}
}
input {
margin-left: 0;
margin-right: 10px;
}
}
CSS Output
.orderby {
.arrow {
margin-left: 2px
&:first-child { /* or could use &.up */
margin-top: 2px;
}
}
input {
margin-left: 0;
margin-right: 10px;
}
}

Avoiding copying CSS styles that stay the same for different divs

#world1 {
background: url(/images/home/1.jpg) 0 0 no-repeat;
float: left;
width: 2%;
height: 4%;
position: absolute;
top: 0%;
left: 0%;
z-index: -1;
margin-top: -20px;
margin-left: -20px;
}
#world1:hover {
background-position: 0 -40px;
cursor: pointer;
I have many (about 100) of these #world(number) divs on a single page. The only thing that changes are the top and left values and the background jpg source. Everything else is the same so clearly it is a huge amount of code. Is there some way I can avoid copying the content that remains the same between all divs and only change the absolute position and background source of each individual div?
Thanks
Also give the div a class, for example: class="worlds".
And put all the generic styling in that class
.world { generic styling }
#wordl1 { custom styling }
Would it be acceptable to add a shared class to all of the #worldN divs?:
.world { /* Styles general to class="world" */ }
#world1 { /* Styles specific to id="world1" */ }
#world1:hover { /* Styles specific to id="world1" hover state */ }
#world2 { /* Styles specific to id="world2" */ }
#world2:hover { /* Styles specific to id="world2" hover state */ }
And in your HTML:
<div class="world" id="world1"></div>
<div class="world" id="world2"></div>
Use classes for common style for all divs, and id's for unique style:
HTML:
<div class="myClass" id="div1" />
<div class="myClass" id="div2" />
<div class="myClass" id="div3" />
<div class="myClass" id="div4" />
CSS:
.myClass
{
///all your repeating CSS
}
#div1{}
#div2{}
#div3{}
#div4{}
You can group same rules of many elements with their class: http://www.w3.org/TR/html4/struct/global.html#h-7.5.2
ID will be used to apply UNIQUE styles.
Yes, just put everything that's common into a div css optionally giving it a class that the div must include then just add the specialist css to each world div. Note you can also do class="class1 class2 class3" to use more than one css class.
Take a loot at http://sass-lang.com/

Resources