Weerwidget met eigen iconen New
Calm weather widget with sample weather for Rotterdam: current temperature, short outlook and tabs for the coming hours or days (accessible tablist with arrow keys). The icons are custom SVG line drawings with very light motion (sun turns, cloud drifts, rain falls) that stand still with reduced motion. For leisure, terraces, events, construction and gardeners; connect it to a weather API.
Rotterdam · voorbeeldweer, do 14:20
14°
Half bewolkt, vanaf 17:00 regen
How to use it
- Paste the HTML where the numbers & charts should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Weerwidget met eigen iconen · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="wtr">
<div class="wtr__now"><div class="wtr__txt"><p class="wtr__plaats"><b>Rotterdam</b> · voorbeeldweer, do 14:20</p><p class="wtr__temp">14°</p><p class="wtr__desc">Half bewolkt, vanaf 17:00 regen</p></div><div class="wtr__big" aria-hidden="true"></div></div>
<div class="wtr__tabs" role="tablist" aria-label="Verwachting"><button type="button" role="tab" aria-selected="true" data-p="u">Komende uren</button><button type="button" role="tab" aria-selected="false" tabindex="-1" data-p="d">Komende dagen</button></div>
<ul class="wtr__list" role="tabpanel"></ul>
</div>
</div>/* Weerwidget met eigen iconen · NedDev · eigen werk. */
.wtr{position:absolute;inset:0;box-sizing:border-box;padding:12px 14px;background:#fff;color:#0a0a0a;font-family:'Switzer',sans-serif;display:flex;flex-direction:column;justify-content:center;gap:8px;container-type:inline-size}
.wtr__now{display:flex;justify-content:space-between;align-items:center;gap:10px}
.wtr__txt p{margin:0}
.wtr__plaats{font-size:12px;color:#5f5e5a}
.wtr__plaats b{color:#0a0a0a;font-weight:600;font-size:13px}
.wtr__temp{font-size:38px;font-weight:600;line-height:1.05;letter-spacing:-.02em}
.wtr__desc{font-size:13px;color:#3d3c39}
.wtr__big{width:72px;height:72px;flex:none}
.wtr__big svg,.wtr__ic svg{width:100%;height:100%;display:block;overflow:visible}
.wtr__tabs{display:flex;gap:14px;border-bottom:1px solid #e3e1dd}
.wtr__tabs button{min-height:26px;padding:0;border:0;border-bottom:2px solid transparent;margin-bottom:-1px;background:none;color:#6b6a66;font:500 12px 'Switzer',sans-serif;cursor:pointer}
.wtr__tabs button:hover{color:#0a0a0a}
.wtr__tabs button[aria-selected="true"]{color:#0a0a0a;font-weight:600;border-bottom-color:#F5480F}
.wtr__tabs button:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.wtr__list{list-style:none;margin:0;padding:4px 0 0;display:flex;justify-content:space-between;align-items:center}
.wtr__list:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.wtr__it{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:0;flex:1 1 0;animation:wtr-in .35s ease both;animation-delay:calc(var(--i)*40ms)}
.wtr__tm{font-size:12px;color:#6b6a66}
.wtr__ic{width:26px;height:26px}
.wtr__tp{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.wtr__tp small{font-size:12px;font-weight:400;color:#8a8883}
.ic-l{fill:none;stroke:#0a0a0a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.ic-c{fill:#fff;stroke:#0a0a0a;stroke-width:1.5;stroke-linejoin:round}
.ic-s{fill:#F5480F}
.ic-r{stroke:#F5480F}
.ic-d{stroke:#0a0a0a;stroke-width:1.5;stroke-linecap:round}
.wtr__big .ic-rays{animation:wtr-spin 40s linear infinite}
.wtr__big .ic-cl{animation:wtr-drift 7s ease-in-out infinite alternate}
.wtr__big .ic-d{animation:wtr-drop 1.4s ease-in infinite}
.wtr__big .ic-d:nth-child(2){animation-delay:.45s}.wtr__big .ic-d:nth-child(3){animation-delay:.9s}
@keyframes wtr-spin{to{transform:rotate(360deg)}}
@keyframes wtr-drift{from{transform:translateX(-.8px)}to{transform:translateX(.8px)}}
@keyframes wtr-drop{0%{transform:translateY(-1px);opacity:0}30%{opacity:1}100%{transform:translateY(3px);opacity:0}}
@keyframes wtr-in{from{opacity:0;transform:translateY(4px)}}
@container (max-width:380px){.wtr__temp{font-size:32px}.wtr__big{width:58px;height:58px}.wtr__ic{width:22px;height:22px}}
@media(prefers-reduced-motion:reduce){.wtr__big .ic-rays,.wtr__big .ic-cl,.wtr__big .ic-d,.wtr__it{animation:none}}// Weerwidget met eigen iconen · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.wtr');if(!w)return;
function sun(cx,cy,r){var g='<g class="ic-rays" style="transform-box:view-box;transform-origin:'+cx+'px '+cy+'px">';for(var i=0;i<8;i++){var a=i*Math.PI/4,r1=r+2,r2=r+4.2;g+='<line class="ic-l ic-r" x1="'+(cx+r1*Math.cos(a)).toFixed(2)+'" y1="'+(cy+r1*Math.sin(a)).toFixed(2)+'" x2="'+(cx+r2*Math.cos(a)).toFixed(2)+'" y2="'+(cy+r2*Math.sin(a)).toFixed(2)+'"/>';}return g+'</g><circle class="ic-s" cx="'+cx+'" cy="'+cy+'" r="'+r+'"/>';}
var CL='M7 19h9.5a4 4 0 0 0 .4-8 5.5 5.5 0 0 0-10.5 1.6A3.2 3.2 0 0 0 7 19z';
var IC={zon:sun(12,12,4.5),half:sun(15.5,8.5,3.4)+'<g class="ic-cl"><path class="ic-c" d="'+CL+'"/></g>',wolk:'<g class="ic-cl"><path class="ic-c" d="'+CL+'"/></g>',
regen:'<g class="ic-cl"><path class="ic-c" d="M7 15h9.5a4 4 0 0 0 .4-8 5.5 5.5 0 0 0-10.5 1.6A3.2 3.2 0 0 0 7 15z"/></g><g><line class="ic-d" x1="9" y1="18" x2="8.3" y2="20.5"/><line class="ic-d" x1="12.5" y1="18" x2="11.8" y2="20.5"/><line class="ic-d" x1="16" y1="18" x2="15.3" y2="20.5"/></g>',
maan:'<path class="ic-l" style="fill:#fff" d="M16.5 15.8A6.5 6.5 0 0 1 9.2 6a6.5 6.5 0 1 0 7.3 9.8z"/>'};
var NM={zon:'zonnig',half:'half bewolkt',wolk:'bewolkt',regen:'regen',maan:'helder'};
function svg(k){return '<svg viewBox="0 0 24 24" aria-hidden="true">'+IC[k]+'</svg>';}
w.querySelector('.wtr__big').innerHTML=svg('half');
var D={u:[['15:00','half',14],['16:00','wolk',13],['17:00','regen',12],['18:00','regen',11],['19:00','wolk',11],['20:00','maan',10]],
d:[['vr','regen',13,8],['za','half',15,9],['zo','zon',17,10],['ma','wolk',14,9],['di','half',15,8]]};
var list=w.querySelector('.wtr__list'),tabs=[].slice.call(w.querySelectorAll('.wtr__tabs button'));
var tid='wtr-'+Math.random().toString(36).slice(2,7);tabs.forEach(function(t,i){t.id=tid+'-'+i;});
function render(p){list.innerHTML=D[p].map(function(r,i){var tp=p==='u'?r[2]+'°':r[2]+'° <small>'+r[3]+'°</small>';var lab=p==='u'?r[0]+', '+NM[r[1]]+', '+r[2]+' graden':{vr:'vrijdag',za:'zaterdag',zo:'zondag',ma:'maandag',di:'dinsdag'}[r[0]]+', '+NM[r[1]]+', '+r[2]+' tot '+r[3]+' graden';
return '<li class="wtr__it" style="--i:'+i+'" aria-label="'+lab+'"><span class="wtr__tm" aria-hidden="true">'+r[0]+'</span><span class="wtr__ic">'+svg(r[1])+'</span><span class="wtr__tp" aria-hidden="true">'+tp+'</span></li>';}).join('');
var on=tabs.filter(function(t){return t.dataset.p===p;})[0];list.setAttribute('aria-labelledby',on.id);}
function sel(t,f){tabs.forEach(function(x){var on=x===t;x.setAttribute('aria-selected',on?'true':'false');x.tabIndex=on?0:-1;});if(f)t.focus();render(t.dataset.p);}
tabs.forEach(function(t,i){t.addEventListener('click',function(){sel(t);});t.addEventListener('keydown',function(e){var j=e.key==='ArrowRight'?i+1:e.key==='ArrowLeft'?i-1:null;if(j===null)return;e.preventDefault();sel(tabs[(j+tabs.length)%tabs.length],true);});});
render('u');
}
init(document.querySelector('.jouw-container'));
More numbers & charts
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →