243 lines
9.3 KiB
HTML
243 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Neat HaCSS Combo!</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
<style>
|
|
/* +-----------------------------------------------------------------------+ *\
|
|
|* | with all their powers combined!.. | *|
|
|
|* | (c) 2014 Michał "rysiek" Woźniak <rysiek@hackerspace.pl> | *|
|
|
\* +-----------------------------------------------------------------------+ */
|
|
/*
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
*[data-tooltip] {
|
|
position:relative;
|
|
}
|
|
|
|
*[data-tooltip]::before,
|
|
*[data-tooltip]::after {
|
|
text-indent:0em !important;
|
|
position:absolute;
|
|
opacity:0.8;
|
|
visibility:hidden;
|
|
font-size:80%;
|
|
font-family:sans-serif;
|
|
transition-duration:0s;
|
|
-moz-transition-duration:0s;
|
|
-webkit-transition-duration:0s;
|
|
|
|
}
|
|
|
|
*[data-tooltip]::before {
|
|
content:attr(data-tooltip);
|
|
top:-3.1em;
|
|
left:1em;
|
|
height:1.5em;
|
|
min-width:10em;
|
|
max-width:20em;
|
|
white-space:nowrap;
|
|
overflow:hidden;
|
|
text-overflow:ellipsis;
|
|
padding:0.5em 0.7em 0.7em 0.7em;
|
|
display:block;
|
|
border-radius:0.3em;
|
|
text-align:center;
|
|
|
|
color:white;
|
|
background-color:rgba(6,6,6,0);
|
|
}
|
|
|
|
*[data-tooltip]::after {
|
|
content:" ";
|
|
background:transparent;
|
|
width:1px;
|
|
height:1px;
|
|
border:solid 0.4em rgba(6, 6, 6, 0);
|
|
display:block;
|
|
border-bottom:none;
|
|
border-left:solid 0.3em transparent;
|
|
border-right:solid 0.3em transparent;
|
|
top:-0.9ex;
|
|
left:4em;
|
|
}
|
|
|
|
*[data-tooltip]:hover::before,
|
|
*[data-tooltip]:hover::after {
|
|
border-top-color:rgba(6,6,6,1);
|
|
visibility:visible;
|
|
transition:background-color 0.3s ease-out, border-top-color 0.3s ease-out;
|
|
-moz-transition:background-color 0.3s ease-out, border-top-color 0.3s ease-out;
|
|
-webkit-transition:background-color 0.3s ease-out, border-top-color 0.3s ease-out;
|
|
}
|
|
|
|
*[data-tooltip]:hover::before {
|
|
background-color:rgba(6,6,6,1);
|
|
}
|
|
|
|
/* by default, in a .displayable-container do not display direct-descending .displayable */
|
|
.displayable-container > .displayable {
|
|
max-height:0px;
|
|
overflow:hidden;
|
|
-moz-transition:max-height ease-out 0.5s;
|
|
-webkit-transition:max-height ease-out 0.5s;
|
|
transition:max-height ease-out 0.5s;
|
|
}
|
|
/* a hidden control checkbox should be hidden */
|
|
.displayable-control.hide {
|
|
display:none;
|
|
}
|
|
/* display the section once the checkbox is :checked */
|
|
.displayable-container > .displayable-control:checked ~ .displayable {
|
|
max-height:500px;
|
|
}
|
|
/* targetables */
|
|
.targetable {
|
|
display:none;
|
|
}
|
|
|
|
/* yeah, these have to be explicit */
|
|
.targetable#displayable-targetable-1:target ~ .displayable-container #displayable-control-1:not(:checked) ~ .displayable {
|
|
max-height:500px;
|
|
}
|
|
/* we have to invert the regular direction when using targetable with just a checkbox... */
|
|
.targetable#displayable-targetable-1:target ~ .displayable-container #displayable-control-1:checked ~ .displayable {
|
|
max-height:0px;
|
|
}
|
|
|
|
|
|
/* reverse dependancy */
|
|
.parent {
|
|
position:relative;
|
|
}
|
|
.parent > label {
|
|
display:block;
|
|
text-indent:1.5em;
|
|
margin:0px;
|
|
}
|
|
.parent > input ~ label {
|
|
display:inline-block;
|
|
text-indent:0px;
|
|
}
|
|
.parent .indicator {
|
|
display:block;
|
|
width:1px;
|
|
height:1px;
|
|
position:absolute;
|
|
top:0em;
|
|
left:0.2em;
|
|
}
|
|
.parent .indicator::before {
|
|
content:" ";
|
|
display:inline-block;
|
|
font-size:100%;
|
|
border:solid 0.15em black;
|
|
color:black;
|
|
width:0.6em;
|
|
height:0.6em;
|
|
line-height:0.6em;
|
|
border-radius:0.2em;
|
|
}
|
|
/* any checkboxes checked? by default act as if all were checked */
|
|
.parent .displayable > input:checked ~ .indicator::before {
|
|
content:"✔";
|
|
color:black;
|
|
}
|
|
/* if there is a checked-unchecked or unchecked-checked combo, that means not *all* are checked, right? */
|
|
/* TODO: can it be done with counters too? */
|
|
.parent .displayable > input:not(:checked) ~ input:checked ~ .indicator::before,
|
|
.parent .displayable > input:checked ~ input:not(:checked) ~ .indicator::before {
|
|
color:gray;
|
|
}
|
|
|
|
/* some eye-candy */
|
|
body {
|
|
font-family:sans-serif;
|
|
}
|
|
label {
|
|
cursor:pointer;
|
|
}
|
|
.displayable, .parent {
|
|
background:rgba(0, 0, 0, 0.15);
|
|
margin:0.5em;
|
|
}
|
|
</style>
|
|
<script>
|
|
function updateDependables() {
|
|
var ndp = document.getElementById('non-dependable')
|
|
var dps = document.getElementsByClassName('dependable')
|
|
for (var i=0; i < dps.length; i++) {
|
|
dps[i].checked = ndp.checked
|
|
}
|
|
return true;
|
|
}
|
|
function updateNonDependable() {
|
|
var ndp = document.getElementById('non-dependable')
|
|
var dps = document.getElementsByClassName('dependable')
|
|
var status = false;
|
|
for (var i=0; i < dps.length; i++) {
|
|
status = (status || dps[i].checked)
|
|
}
|
|
ndp.checked = status
|
|
return true;
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<p>So we have a setting <a href="#displayable-targetable-1">with very fine controls</a>; the user needs only the basic information up-front -- is it at all enabled, or partially enabled?</p>
|
|
<p>With JS we're able to use an additional checkbox here, and give the user a chance to set all the fine-controls at the same time; without JS we at least can show the basic status.</p>
|
|
|
|
<!-- this one is needed for handling :target -->
|
|
<!--input type="radio" class="displayable-control hide" name="section" id="displayable-control-none" checked="checked" title="Non-section radiobutton (default)"/-->
|
|
|
|
<!-- where the magic happens -->
|
|
<div class="parent">
|
|
|
|
<!-- the label to make it all work -->
|
|
<noscript><!--</noscript>
|
|
<input type="checkbox" name="non-dependable" title="Checkbox 1" data-tooltip="Set/unset all fine settings" id="non-dependable" onclick="updateDependables()"/>
|
|
<noscript>--></noscript>
|
|
<label for="displayable-control-1" data-tooltip="Show/hide fine controls">Some setting with very finely-grained controls</label>
|
|
|
|
<!-- the targetable -->
|
|
<div class="targetable" id="displayable-targetable-1">Targetable #3</div>
|
|
|
|
<!-- the container for the displayable -->
|
|
<div class="displayable-container">
|
|
|
|
<!-- the hidden "displayable-state" checkbox -->
|
|
<input type="checkbox" class="displayable-control hide" name="section" id="displayable-control-1" title="Fine-grained settings checkbox"/>
|
|
|
|
<!-- the displayable section itself -->
|
|
<div class="displayable">
|
|
<p>Fine controls.</p>
|
|
<input type="checkbox" class="dependable" name="dependable1" id="dependable1" title="Checkbox 1" onclick="updateNonDependable()"/>
|
|
<input type="checkbox" class="dependable" name="dependable2" id="dependable2" title="Checkbox 2" onclick="updateNonDependable()"/>
|
|
<input type="checkbox" class="dependable" name="dependable3" id="dependable3" title="Checkbox 3" onclick="updateNonDependable()"/>
|
|
<input type="checkbox" class="dependable" name="dependable3" id="dependable4" title="Checkbox 3" onclick="updateNonDependable()"/>
|
|
<input type="checkbox" class="dependable" name="dependable4" id="dependable5" title="Checkbox 4" onclick="updateNonDependable()"/>
|
|
<!-- yes, noscript tags are styleable, and visible ONLY when JS is disabled; perfect for our needs! -->
|
|
<noscript class="indicator"></noscript>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p>This is one if the <a href="http://rys.io/en/123/">neat hacss</a>. Code is <a href="https://code.hackerspace.pl/rysiek/neat-hacss/">here</a>.</p>
|
|
</body>
|
|
</html> |