Thursday, October 31, 2019

prefix-free y basta de prefijos en el CSS

prefix-free es un script que habría que tener muy en cuenta ya que nos ayuda a resolver uno de los problemas más molestos a la hora de escribir reglas de estilo "modernas" ya que lo que hace es agregar de modo automático, los prefijos correspondientes para cada navegador de tal modo que no sería necesarios escribir algo así:
.una-regla {
background-image: -moz-linear-gradient(#000,#FFF);
background-image: -webkit-linear-gradient(#000,#FFF);
background-image: -o-linear-gradient(#000,#FFF);
background-image: -ms-linear-gradient(#000,#FFF);
background-image: linear-gradient(#000,#FFF);
}
y todo ese exceso de líneas (que, inevitablemente uno termina equivocando u olvidando) se transformaría en es esto:
.una-regla {
background-image: linear-gradient(#000,#FFF);
}
es decir, sólo deebría usarse la propiedad especificada por la w3.org y del resto, se encargará el script.

¿En que navegadores funcionará? En todos aquellos que usen ese tipo de prefijos, Firefox, Chrome, Safari, Opera, IE9 en adelante y las versiones móviles más comunes. Obviamente, como IE8 no soporta la mayoría de las propiedades CSS3, nada ocurrirá allí pero tampoco tendrá influencia alguna, todo seguirá como antes.

¿Funciona en Blogger? Si, no debería haber problemas ya que el script se ejecuta tanto sobre etiquetas <style> </style>, estilos externos agregados con la etiqueta LINK o incluso, en estilos agregados inline con el atributo style en la misma etiqueta.

¿Cómo lo usamos? Descargamos el script desde la página del desarrollador (es muy pequeño) y lo alojamos en un servidor:
<script src='URL/prefixfree.min.js' type='text/javascript'/>
o simplemente lo copiamos y pegamos en la plantilla entre etiquetas
<script type='text/javascript'>
//<![CDATA[
....... acá pegamos el contenido del archvo js .......
//]]>
</script>
y, en ambos casos, conviene hacerles caso a los desarrolladores y agregarlo justo antes de </head>

Tres ejemplo rápidos:
/* un fondo con gradiente */
#pf1{background-image:linear-gradient(#000,#FFF);}

/* una transición */
#pf2{font-size: 0;line-height: 100px;border-radius:0;background-color: #000;transition:all 1s;}
#pf2:hover{background-color:#F0F8FF;border-radius:50px;background-color: #F00;font-size: 80px;}

/* una animación*/
#pf3{background-color:#000;animation: recrojo 1s infinite alternate;}
@keyframes recrojo {from {background-color:#000;} to {background-color:#F00;}}

Tuesday, October 22, 2019

Seguimiento de descargas

Algunas personas que tienen sitios desde donde se descargan archivos de distinto tipo, han preguntado si hay una forma de mantener un registro de esas descargas, algo que muchos servicios donde se alojan esos archivos permiten o incluyen pero otro nos y, desde Blogger, no hay muchas alternativas.

Una de ellas es usar Google Analytics que es un servicio que se integra desde la misma Configuración del blog o manualmente, copiando y pegando el script que ellos proveen.

Teniéndolo incluido, podemos, ellos nos dan la posibilidad de hacer un seguimiento de cualquier enlace en particular aunque las explicaciones que ahora nos muestran son poco claras; más fácil es entender el método leyendo la ayuda "vieja" aunque esté en inglés ya que la metodología no ha cambiado.

¿Qué nos dicen? Que si tenemos un enlace de cualquier tipo:
<a href="URL_archivo">descargar</a>
bastaría agregarle un evento onclick que llame a la función de Google Analytics y, de ese modo, las descarga del archivo será registrada por el servicio:
<a href="URL_archivo" onclick="_gaq.push(['_trackPageview','URL_archivo']);">descargar</a>
o bien:
<a href="URL_archivo" onclick="_gaq.push(['_trackEvent','URL_archivo']);">descargar</a>
Usar uno u otro sistema dependerá de la forma en que quisiéramos que se registraran los datos y las diferencias entre _trackPageview y _trackEvent quedan para ser estudiadas por cada uno ya que, además poseen parámetros opcionales.

Si quisiéramos automatizar esto y agregarlo a los enlaces sin tener que escribirlos manualmente, deberías usar alguna clase de script. Por ejemplo, usando jQuery podríamos usar una clase para identificar los archivos:
<a class="descarga" href="URL_archivo">descargar</a>
y poner una función así:
$('.descarga').click(function () {
_gaq.push(['_trackPageview', $(this).attr('href').replace('http://','')]);
});
o así:
$('.descarga').click(function () {
_gaq.push(['_trackEvent', 'MISdescargas']);
});
Y para quien no quiera complicarse la vida, llegado el caso, pueden usar entourage.js que es un script que agregamos antes de </head> o antes del código de Google Analytics y hará todo eso de modo automático.

Sunday, October 20, 2019

Muchos íconos en blanco y negro

Loop icons
Contiene 106 íconos de 16x16 en formato PNG.
descargar

Windows phone
Contiene 1482 íconos de 48x48 en formato PNG.
descargar

Thursday, October 17, 2019

Google Drive para alojar sitios web sencillos

Como en Blogger no podemos subir un mísero archivito, en un tiempo, cuando existían las Google Pages, las usábamos a destajo hasta que kaput porque "a los que saben" se les ocurrió crear Google Sites que no era lo mismo aunque ellos creían que si.

Nos quedamos colocados, mudando archivos de lado a lado, buscando alternativas, las encontramos, cada una con sus bemoles pero, acá seguimos.

El procedimiento es sencillo; entramos en Google Drive https://drive.google.com/ y creamos una carpeta nueva. Luego, con botón derecho, hacemos click en Compartir | Cambiar y marcamos que sea Publica:



Ahora, subimos nuestro archivo HTML a esa carpeta, lo editamos y, haciendo click en Vista Previa, copiamos la dirección url que nos muestra que será del tipo:
https://googledrive.com/host/xxxxxxxxxxxxx/nombre_archivo.html
Eso es todo, con esa dirección, podemos mostrarlo donde se nos ocurra, como en este ejemplo que lo abre en una ventana modal:


En este caso, el HTML no tiene nada especial, solo código normal, scripts internos y CSS pero, podemos ampliar las posibilidades y utilizar archivos externos que también alojamos en la misma carpeta y a los que accedemos desde el HTML, usando las direcciones url relativas.

Hasta ahí, es una forma sencilla de manejarse aunque no es cómodo que no sea posible crear o editar esos archivos desde el mismo Google Drive salvo que se agreguen aplicaciones externas como Drive Notepad que sólo funcionan en Chrome.

Tuesday, October 15, 2019

TinyScroller: Simple y personalizable

TinyScroller es un script muy sencillo que no requiere librerías extras y nos permite mostrar mucho contenido en un espacio pequeño tal como normalmente hacemos cuando usamos un contenedor con cierta altura dimensionada y le aplicamos la propiedad overflow para que se pueda ver utilizando una barra de desplazamiento.

El script es realmente pequeño, uno poco más de 50 líneas sin comprimir aunque el ZIP que lo contiene también incluye una versión minimizada.

Lo agregamos como cualquier otro, alojándolo en un servidor o directamente, antes de <head>:

<script type='text/javascript'>
//<![CDATA[
var TINY={};
function T$(id){return document.getElementById(id)}
function T$$$(){return document.all?1:0}
TINY.scroller=function(){
return{
init:function(a,c,b,s,d){
a=T$(a); a.c=c; a.s=s; c=T$(c); b=T$(b); s=T$(s); a.n=d||0;
b.style.display='block'; a.style.overflow='hidden';
var h=a.offsetHeight, t=c.offsetHeight;
if(t<h){
b.style.display='none'
}else{
a.m=h-t; a.d=t/h; s.style.height=(h*(h/t))+'px'; s.style.top=b.style.top=0;
s.onmousedown=function(event){TINY.scroller.st(event,a.id); return false};
s.onselectstart=function(){return false}
}
a.l=b.offsetHeight-s.offsetHeight
},
st:function(e,f){
var a=T$(f), s=T$(a.s); a.bcs=TINY.cursor.top(e); a.bct=parseInt(s.style.top);
if(a.mv){this.sp(f)}
a.mv=function(event){TINY.scroller.mv(event,f)};
a.sp=function(){TINY.scroller.sp(f)};
if(T$$$()){
document.attachEvent('onmousemove',a.mv); document.attachEvent('onmouseup',a.sp)
}else{
document.addEventListener('mousemove',a.mv,1); document.addEventListener('mouseup',a.sp,1)
}
if(a.d){s.className+=' '+a.n}
},
mv:function(e,f){
var a=T$(f), m=TINY.cursor.top(e)-a.bcs+a.bct, s=T$(a.s), c=T$(a.c);
if(m>=0&&m<a.l){
s.style.top=m+'px'; c.style.top=(m*-1*a.d)+'px'
}else if(m<0){
s.style.top=0; c.style.top=0
}else if(m>a.l){
s.style.top=a.l+'px'; c.style.top=a.m+'px'
}
},
sp:function(f){
var a=T$(f), s=T$(a.s); if(a.d){s.className=s.className.replace(' '+a.n,'')}
if(T$$$()){
document.detachEvent('onmousemove',a.mv); document.detachEvent('onmouseup',a.sp)
}else{
document.removeEventListener('mousemove',a.mv,1); document.removeEventListener('mouseup',a.sp,1)
}
a.mv=0;
}
}
}();
TINY.cursor=function(){
return{
top:function(e){
return T$$$()?window.event.clientY+document.documentElement.scrollTop+document.body.scrollTop:e.clientY+window.scrollY
}
}
}();
//]]>
</script>

Y lo usarmemos de este modo:
<div id="ejemplo-scroll" class="scroll">
<div id="ejemplo-scrollcontent" class="scrollcontent">
....... acá pondremos nuestro contenido .......
</div>
<div id="ejemplo-scrollbar" class="scrollbar">
<div id="ejemplo-scroller" class="scroller"></div>
</div>
</div>
e inmediantamente debajo, llamamos a la función que en este caso, sería así:
<script type="text/javascript">TINY.scroller.init('ejemplo-scroll','ejemplo-scrollcontent','ejemplo-scrollbar','ejemplo-scroller','buttonclick');</script>
Eso, lo haremos siempre del mismo modo, con la misma sintaxis, colocando en la función los cinco parámetros que son los IDs que hemos elegido:

el ID del contenedor que en este caso llamé ejemplo-scroll
el ID del contenido que llamé ejemplo-scrollcontent
los IDs de lso DIVs auxiliares que mostrarán la barra de desplazamiento y el botón: (ejemplo-scrollbar y ejemplo-scroller)
y la clase de ese botón (buttonclick)

Por último, necesitamos el CSS que es lo que podemos personalizar y que en este caso, rearmé agregando clases par que, de esa forma, pudieran mostrarse con distintos tamaños y detalles gráficos:
<style>

/* las reglas genéricas */
.scroll { /* el contenedor */
overflow: auto;
position: relative;
}
.scrollcontent { /* el contenido */
position: absolute;
z-index: 200;
}
.scrollbar { /* la barra de desplazamiento es una imagen */
background:url(URL_scroll-bg.gif);
display: none;
float: right;
position: relative;
width: 15px;
z-index: 100;
}
.scroller { /* el botón de desplazamiento también es una imagen */
background-color: #CCC;
background-image: url(URL_scroll-arrows.gif);
background-position: 50% 50%;
background-repeat: no-repeat;
cursor: pointer;
position: absolute;
top: 0;
width: 15px;
}
.buttonclick { background-color:#BBB; }

/* y defino los anchos, altos y otros detalles de cada uno de elllos */
#ejemplo-scroll { /*
background-color: #000;
margin: 0 auto;
height: 200px; /* el ancho */
width: 300px; /* el alto */
}
#ejemplo-scrollcontent {
width:275px; /* el ancho del contenedor menos el ancho de la barra de desplazamiento */
}
#ejemplo-scrollbar {
height: 200px; /* el mismo alto que el contenedor */
}

</style>

Bastaría establecer otros valores para crear otro modelo y usarlo en la misma página:
#otro-scroll{
background-color: #222;
border: 2px solid #000;
height: 270px;
margin: 0 auto;
outline: 1px solid #666;
width: 600px;
}
#otro-scroll{width: 575px;}
#otro-scroll{height: 270px; }

Thursday, October 10, 2019

El atributo required

El atributo required es otra de las nuevas alternativas que se agregan al HTML5 y lo que hace es indicar que cierto campo debe ser "llenado" y evitar que un formulario se envíe sin contenido.

Aunque la verificación final de los datos enviados desde un formulario debe ser hecha en el servidor que los procesará, siempre es bueno realizar una validación previa con JavaScript y así reducir los accesos y evitar el envío de datos vacíos o nulos.

Tuesday, October 8, 2019

Agregar fullscreen a distintos elementos

Mostrar contenido en pantalla completa no es algo exclusivo de los videos incrustados ya que puede hacerse sobre cualquier otro contenido aunque siempre veremos la advertencia del navegador que nos avisa que esta opción está en uso y que podemos volver atrás utilizando la tecla ESC.

Friday, October 4, 2019

simpleWeather: El tiempo en el blog con jQuery

simpleWeather es un plugin de jQuery que sirve para mostrar informacion sobre el estado del tiempo del tiempo en un lugar definido y que para eso, utiliza el API Weather feed de Yahoo.

El script es muy simple porque, en realidad, no genera la salida sino que simplemente obtiene los datos así que la parte complicada del asunto es que nosotros debemos armar el HTML correspondiente.

Una vez que agregamos el script a la plantilla, deberíamos crear la función que es lo que mostrará el resultado; básicamente es algo así:
$.simpleWeather({
location: 'xxxxxxxxxxx',
unit: 'c',
success: function(weather) { ... },
error: function(error) { ... }
});
donde location es la ciudad y unit indica la unidad de la temperatura.

Este es un ejemplo simple:
<script type="text/javascript">
//<![CDATA[
$(function() {
$.simpleWeather({
location: 'xxxxxxxxxxx',
unit: 'c',
success: function(weather) {
html = '<h2>'+weather.city+'</h2>';
html += '<img src="'+weather.image+'"/>';
html += '<p>'+weather.temp+'° '+weather.units.temp+'<span>'+weather.currently+'</span></p>';
$("#weather").html(html);
},
error: function(error) {
$("#weather").html('<p>'+error+'</p>');
}
});
});
//]]>
</script>
Así que ahora, bastaría colocar el DIV de salida allí donde quisiéramos mostrarlo:
<div id="weather"></div>
Y un poco de CSS:
<style>
#weather {
background-color: #456;
border: 4px solid #ABC;
overflow: hidden;
padding: 10px 20px 0;
position: relative;
text-align: center;
width: 185px;
}
#weather h2 {
color: #DEF;
font-family: Century Gothic;
font-size: 28px;
font-weight: normal;
letter-spacing: -3px;
margin: 0;
text-align: center;
}
#weather img {
margin-top: 10px;
}
#weather p {
color: #DEF;
font-family: Times New Roman;
font-size: 48px;
left: 80px;
letter-spacing: -6px;
margin: 0;
position: absolute;
top: 140px;
}
#weather p span {
color: #ABC;
display: block;
font-size: 20px;
letter-spacing: 0;
text-transform: lowercase;
}
</style>

Wednesday, October 2, 2019

Bordes, listas, el primero y el último

Esta es una solución sencilla a un problema común.

Tengo una lista cualquiera y quiero ponerle un borde o separador a cada uno de los items que la componen:
<div id="demobordes">
<ul>
<li>el primer item</li>
<li>el segundo item</li>
<li>el tercer item</li>
<li>el último item</li>
</ul>
Entonces pruebo con una regla básica:
<style>
#demobordes li {
background-color: #000;
border-bottom: 2px dotted #ABC;
border-top: 2px dotted #ABC;
color: #888;
padding: 5px 10px;
}
</style>
pero ... el primero se ve bien, el último también y los del medio se superponen, haciéndolos mas "gordos":

  • el primer item
  • el segundo item
  • el tercer item
  • el último item

Entonces, pruebo, sólo dejo un borde, el de abajo o el de arriba pero, en ambos casos siempre me falta uno; o el primer item no tiene un borde superior o le falta el borde al último y yo quiero que todos tengan un borde:

  • el primer item
  • el segundo item
  • el tercer item
  • el último item
  • el primer item
  • el segundo item
  • el tercer item
  • el último item

Y como el navegador no es adivino, lo que debo hacer es indicarle eso, si todos los items tienen un borde inferior (border-bottom) quiero que el primero tenga un borde superior y para eso, uso first-child:
#demobordes li {
.......
border-bottom: 2px dotted #ABC;
}
#demobordes li:first-child { border-top: 2px dotted #ABC; }
Y al revés, si todos tienen un borde superior (border-top) le digo que el último tenga un borde inferior con last-child:
#demobordes li {
.......
border-top: 2px dotted #ABC;
}
#demobordes li:last-child { border-bottom: 2px dotted #ABC; }
Y con eso resuelvo el asunto:

  • el primer item
  • el segundo item
  • el tercer item
  • el último item
  • el primer item
  • el segundo item
  • el tercer item
  • el último item

One div: Iconos CSS

One div es un sitio donde podemos buscar y copiar el código necesario para utilizar íconos o símbolos creados exclusivamente con CSS; una técnica cuyo uso se va va extendiendo ya que tiene la ventaja de no utilizar imágenes y de ser flexibles porque podemos variar su tamaño con sencillez sin que se deformen.

Además, basta un poco de imaginación para aprovechar las distintas propiedades, cambiar colores, agregar animaciones o utilizar efectos aunque, claro está, como todas estas cosas, la compatibilidad con los distintos navegadores es una limitación importante pero, poco a poco, es algo que deberíamos dejar de lado y empezar a aceptar que esas limitaciones existirán siempre y que nada es universal excepto que 2+2=4.

Algunos ejemplos:

<style>
.mug_animate {
  box-shadow: 0 -3em 0 0 #0AF inset;
  height: 2.5em;
  position: relative;
  -moz-transition: all 1000ms linear 0s;
  -webkit-transition: all 1000ms linear 0s;
  -o-transition: all 1000ms linear 0s;
  -ms-transition: all 1000ms linear 0s;
  transition: all 1000ms linear 0s;
  width: 1.5em;
}
.mug_animate:after {
  border-color: #DDD transparent #DDD #DDD;
  border-image: none;
  border-radius: 0.75em 0 0 0.75em;
  border-style: solid none solid solid;
  border-width: 0.25em medium 0.25em 0.25em;
  content: "";
  height: 1.5em;
  left: -1em;
  position: absolute;
  top: 0.25em;
  width: 0.75em;
}
.mug_animate:before {
  border: 0.25em solid #DDD;
  border-radius: 0 0 0.2em 0.2em;
  content: "";
  height: 2.5em;
  left: -0.20em;
  position: absolute;
  top: -0.5em;
  width: 1.5em;
}
.mug_animate:hover {
  box-shadow: 0 0 0 0 #00F inset;
}
</style>

<div class="mug_animate"></div>



<style>
.fir {
  box-shadow: 0em 0.9em 0 -0.8em #4D4,0em 1em 0 -0.8em #4D4,0em 1.1em 0 -0.8em #4D4,0em 1.2em 0 -0.8em #4D4;
  border-bottom: 1.7em solid #4D4;
  border-left: 1em solid transparent;
  border-right: 1em solid transparent;
  font-size: 20px;
  height: 0em;
  position: relative;
  width: 0em;
}

.fir:before {
  border-bottom: 1em solid #4D4;
  border-left: 0.7em solid transparent;
  border-right: 0.7em solid transparent;
  content: '';
  display: block;
  height: 0em;
  left: -0.7em;
  position: absolute;
  top: -0.2em;
  width: 0em;
}

.fir::after {
  border-bottom: 0.7em solid #4D4;
  border-left: 0.5em solid transparent;
  border-right: 0.5em solid transparent;
  content: '';
  display: block;
  height: 0em;
  left: -0.5em;
  position: absolute;
  top: -0.5em;
  width: 0em;
}
</style>

<div class="fir"></div>



<style>
.pacman {
  background-image: -webkit-radial-gradient(1.75em .75em, circle, transparent 10%, #EE0 10%);
  background-image: -moz-radial-gradient(1.75em .75em, circle, transparent 10%, #EE0 10%);
  background-image: -o-radial-gradient(1.75em .75em, circle, transparent 10%, #EE0 10%);
  background-image: -ms-radial-gradient(1.75em .75em, circle, transparent 10%, #EE0 10%);
  background-image: radial-gradient(1.75em .75em, circle, transparent 10%, #EE0 10%);
  border-radius: 3em 3em 0 0;
  height: 1.5em;
  position: relative;
  -moz-transform: rotate(-45deg);
  -webkit-transform: rotate(-45deg);
  -o-transform: rotate(-45deg);
  -ms-transform: rotate(-45deg);
  transform: rotate(-45deg);
  width: 3em;
}

.pacman:after {
  background-color: #EE0;
  border-radius: 0 0 3em 0;
  content: '';
  height: 1.5em;
  left: 0em;
  position: absolute;
  top: 1.45em;
  -moz-transform: rotate(90deg);
  -webkit-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
  width: 1.5em;
}
</style>

<div class="pacman"></div>