Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <body>
  <div id="grid">

    <div class="row center">
        <h1 id="title">Weather</h1>
    </div>

    <div class="row center">
        <div class="weather-display col">
          <div class="row center">
            <div class="current-location"></div>
          </div>
          <div class="row center">
            <div class="weather-icon"></div>
          </div>
          <div class="row center-temp">
            <div class="high-temp"></div>
            <div class="low-temp"></div>
            <div class="current-temp"></div>
          </div>
          <div class="row center">
            <div class="weather-description"></div>
          </div>
          <div class="row center-other">
            <div class="wind-speed"></div>
            <div class="humidity"></div>
          </div>
        </div>
      </div>

      <div class="row center">
        <div class="switch">
          <input id="temp-unit" class="toggle toggle-round-flat" type="checkbox" />
          <label for="temp-unit" data-off="F" data-on="C"></label>
        </div>
        <div>
          <button type="button" id="gps">Get Location</button>
        </div>
      </div>

      <div class="row center">
        <footer>
          <p>
            2017 <a href="mailto:yasmine@yasminetriola.com">Yasmine Triola</a>
          </p>
        </footer>
      </div>

    </div>

</body>
</>
              
            
!

CSS

              
                * {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -ms-box-sizing: border-box;
  box-sizing: border-box;
}

body {
  font-family: 'Lato', sans-serif;
  background-color: rgba(18, 92, 215, 1);
  color: rgba(255, 255, 255, 1);
}

h1 {
  font-size: 3em;
  text-align: center;
  color: rgba(255, 255, 255, 1);
}

footer {
  font-size: 1em;
  text-align: center;
}

#grid {
  max-width: 960px;
  margin: 0 auto;
}

#gps {
  display: block;
}

.col {
}

.row {
  display: flex;
  flex: 1;
}

.row.center {
  justify-content: center;
  align-items: center;
}

.row.center-temp {
  justify-content: space-around;
  align-items: center;
}

.row.center-other {
  justify-content: space-between;
}

.weather-display {
  padding: 0.75em;
}

.current-location {
  font-size: 1.5em;
}

.weather-icon {
  font-size: 4.5em;
}

.current-temp {
  font-size: 3em;
  order: 1;
  padding-bottom: 0.25em;
}

.high-temp {
  padding: 0.5em;
  order: 2;
}

.low-temp {
  padding: 0.5em;
  order: 0;
}

.wind-speed {
  align-self: flex-start;
  padding: 0.5em;
}

.humidity {
  align-self: flex-end;
  padding: 0.5em;
}

.weather-description {
  font-size: 1.25em;
  padding-bottom: 0.5em;
}

.toggle {
  position: absolute;
  margin-left: -9999px;
  visibility: hidden;
}

.toggle + label {
  display: block;
  position: relative;
  cursor: pointer;
  outline: none;
  user-select: none;
}

input.toggle-round-flat + label {
  padding: 0.125em;
  width: 3.125em;
  height: 1.563em;
  background-color: rgba(221, 221, 221, 1);
  border-radius: 3.125em;
  transition: background 0.4s;
}

input.toggle-round-flat + label:before,
input.toggle-round-flat + label:after {
  display: block;
  position: absolute;
  color: rgba(255, 255, 255, 1);
}

input.toggle-round-flat + label:before {
  top: 0.125em;
  left: 0.125em;
  bottom: 0.125em;
  right: 0.125em;
  background-color: rgba(255, 255, 255, 1);
  border-radius: 1.563em;
  transition: background 0.4s;
}

input.toggle-round-flat + label:after {
  top: 0.25em;
  left: 0.25em;
  bottom: 0.25em;
  width: 1.063em;
  background-color: rgba(221, 221, 221, 1);
  border-radius: 1.063em;
  transition: margin 0.4s, background 0.4s;
}

input.toggle-round-flat:checked + label {
  background-color: rgba(18, 92, 215, 1);
}

input.toggle-round-flat:checked + label:after {
  margin-left: 1.563em;
  background-color: rgba(18, 92, 215, 1);
  content:attr(data-on);
}


label:before {
  content: '';
}

label:after {
  content:attr(data-off);
}

              
            
!

JS

              
                var model = {
  currentLocation: '',
  weatherIcon: '',
  iconID: null,
  currentTemp: null,
  highTemp: null,
  lowTemp: null,
  windSpeed: null,
  humidity: null,
  cloudCoverage: null,
  weatherMain: '',
  weatherDescription: '',
  rainVolume: null,
  snowVolume: null,
}

var weatherIconList = {
  //thunderstorm with light rain
  200: 'storm-showers',
  //thunderstorm with rain
  201: 'thunderstorm',
  //thunderstorm with heavy rain
  202: 'thunderstorm',
  //light thunderstorm
  210: 'thunderstorm',
  //thunderstorm
  211: 'lightning',
  //heavy thunderstorm
  212: 'lightning',
  //ragged thunderstorm
  221: 'lightning',
  //thunderstorm with light drizzle
  230: 'storm-showers',
  //thunderstorm with drizzle
  231: 'storm-showers',
  //thunderstorm with heavy drizzle
  232: 'storm-showers',
  //light intensity drizzle
  300: 'sprinkle',
  //drizzle
  301: 'sprinkle',
  //heavy intensity drizzle
  302: 'rain',
  //light intensity drizzle rain
  310: 'rain-mix',
  //drizzle rain
  311: 'rain',
  //heavy intensity drizzle rain
  312: 'rain',
  //shower rain and drizzle
  313: 'showers',
  //heavy shower rain and drizzle
  314: 'rain',
  //shower drizzle
  321: 'sprinkle',
  //light rain
  500: 'sprinkle',
  //moderate rain
  501: 'rain',
  //heavy intensity rain
  502: 'rain',
  //very heavy rain
  503: 'rain',
  //extreme rain
  504: 'rain',
  //freezing rain
  511: 'rain-mix',
  //light intensity shower rain
  520: 'showers',
  //shower rain
  521: 'showers',
  //heavy intensity shower rain
  522: 'showers',
  //ragged shower rain
  531: 'storm-showers',
  //light snow
  600: 'snow',
  //snow
  601: 'snow',
  //heavy snow
  602: 'snow',
  //sleet
  611: 'sleet',
  //shower sleet
  612: 'sleet',
  //light rain and snow
  615: 'rain-mix',
  //rain and snow
  616: 'rain-mix',
  //light shower snow
  620: 'snow',
  //shower snow
  621: 'snow',
  //heavy shower snow
  622: 'snow',
  //mist
  701: 'showers',
  //smoke
  711: 'smoke',
  //haze
  721: 'day-haze',
  //sand, dust whirls
  731: 'dust',
  //fog
  741: 'fog',
  //sand
  751: 'sandstorm',
  //dust
  761: 'dust',
  //volcanic ash
  762: 'volcano',
  //squalls
  771: 'cloudy-gusts',
  //tornado
  781: 'tornado',
  //clear sky
  800: 'day-sunny',
  //few clouds
  801: 'cloudy-gusts',
  //scattered clouds
  802: 'cloudy-gusts',
  //broken clouds
  803: 'cloudy-gusts',
  //overcast clouds
  804: 'cloudy',
  //tornado
  900: 'tornado',
  //tropical storm
  901: 'storm-showers',
  //hurricane
  902: 'hurricane',
  //cold
  903: 'snowflake-cold',
  //hot
  904: 'hot',
  //windy
  905: 'windy',
  //hail
  906: 'hail',
  //calm
  951: 'day-sunny',
  //light breeze
  952: 'windy',
  //gentle breeze
  953: 'windy',
  //moderate breeze
  954: 'windy',
  //fresh breeze
  955: 'windy',
  //strong breeze
  956: 'windy',
  //high wind, near gale
  957: 'strong-wind',
  //gale
  958: 'strong-wind',
  //severe gale
  959: 'strong-wind',
  //storm
  960: 'storm-showers',
  //violent storm
  961: 'storm-showers',
  //hurricane
  962: 'hurricane'

}

var controller = {
  init: function initController() {
    controller.getIPLocation();
    controller.setupTempListener();
    controller.setupGPSListener();
  },

  //Initially get location using user's IP address and freegeoip.net API.
  //Then pass lon/lat coordinates to controller.getWeather().
  getIPLocation: function getIPLocation() {
    $.getJSON({
      url: 'https://freegeoip.net/json',
      dataType: 'jsonp'
    })
    .done(function(data){
      controller.getWeather(data.latitude, data.longitude);
    });
  },

  //On user click getLocation gets GPS location and passes it to getWeather.
  getLocation: function getLocation() {
    if("geolocation" in navigator) {
      navigator.geolocation.getCurrentPosition(function(position) {
        controller.getWeather(position.coords.latitude, position.coords.longitude);
      })
    }
    else {
      console.log("Sorry, your browser does not support geolocation.")
    }
  },

  //getLocation or getIPLocation passes coordinates to getWeather. getWeather
  //sends AJAX call and adds data to the model.
  getWeather: function getWeather(latitude, longitude) {
    //Open Weather Map API url with parameters to use in AJAX request
    var url = 'http://api.openweathermap.org/data/2.5/weather?';
    var params = {lat: latitude, lon: longitude, APPID: ''};
    url += $.param(params);

    //AJAX request to openweathermap API.
    $.ajax({
      url: url
    })
    .done(function(data) {
      var weatherData = data;
      model.currentLocation = weatherData.name;
      model.currentTemp = weatherData.main.temp;
      model.highTemp = weatherData.main.temp_max;
      model.lowTemp = weatherData.main.temp_min;
      model.humidity = weatherData.main.humidity;
      model.windSpeed = weatherData.wind.speed;
      model.cloudCoverage = weatherData.clouds.all;
      model.weatherMain = weatherData.weather[0].main;
      model.weatherDescription = weatherData.weather[0].description;
      model.iconID = weatherData.weather[0].id;

      //If rain or snow are properties in the response, add them to model data.
      if (weatherData.hasOwnProperty('rain') || weatherData.hasOwnProperty('snow')) {
        if (weatherData.hasOwnProperty('rain')) {
          model.rainVolume = weatherData.rain['3h'];
        }
        else if (weatherData.hasOwnProperty('snow')) {
          model.snowVolume = weatherData.snow['3h'];
        }
      }
      model.weatherIcon = weatherIconList[model.iconID];

      //Initialize view after adding data to model.
      view.init();
    });
  },

  //Gets requested data from the model.
  getModelData: function getModelData(prop) {
    return model[prop];

  },

  //Sets up an event listener to listen for changes in the checked status of temperature switch.
  setupTempListener: function setupTempListener() {
    $("#temp-unit").change(function tempCheck() {
      var tempButton = $("input");
      view.renderTemp();
    });
  },

  //Sets up an event listener to listen for clicks on the GPS button.
  setupGPSListener: function setupGPSListener() {
    $("#gps").click(function gpsClick() {
      controller.getLocation();
    });
  }

}

var view = {
  //Initialize view.
  init: function initView() {
    var self = this;

    self.render();
    self.renderTemp();

  },

  render: function renderView() {
    var currentLocDiv = $(".current-location");
    var weatherIconDiv = $(".weather-icon");
    var windSpeedDiv = $(".wind-speed");
    var humidityDiv = $(".humidity");
    var weatherDescriptionDiv = $(".weather-description");

    var currentLocation = controller.getModelData('currentLocation');
    var weatherIcon = controller.getModelData('weatherIcon');
    var windSpeed = controller.getModelData('windSpeed');
    var humidity = controller.getModelData('humidity');
    var weatherMain = controller.getModelData('weatherMain');
    var weatherDescription = controller.getModelData('weatherDescription');


    currentLocDiv.empty();
    currentLocDiv.append(currentLocation);

    weatherIconDiv.empty();
    weatherIconDiv.append('<i class="wi wi-' + weatherIcon + '"></i>');

    windSpeedDiv.empty();
    windSpeedDiv.append('Wind: ' + windSpeed + 'mph');

    humidityDiv.empty();
    humidityDiv.append('Humidity: ' + humidity + '%');

    weatherDescriptionDiv.empty();
    weatherDescriptionDiv.append(weatherDescription);
  },

  //Render temperature depending on position of temperature switch.
  renderTemp: function renderTemp() {
    var currentTemp = controller.getModelData('currentTemp');
    var highTemp = controller.getModelData('highTemp');
    var lowTemp = controller.getModelData('lowTemp');

    var tempSwitch = $("input");
    var currentTempDiv = $(".current-temp");
    var highTempDiv = $(".high-temp");
    var lowTempDiv = $(".low-temp");

    if(tempSwitch.prop('checked')) {
      currentTempDiv.empty();
      currentTempDiv.append((Math.round(currentTemp - 273.15)) + '<i class="wi wi-celsius"></i>');

      highTempDiv.empty();
      highTempDiv.append((Math.round(highTemp - 273.15)) + '<i class="wi wi-celsius"></i>');

      lowTempDiv.empty();
      lowTempDiv.append((Math.round(lowTemp - 273.15)) + '<i class="wi wi-celsius"></i>');
    }
    else {
      currentTempDiv.empty();
      currentTempDiv.append((Math.round(currentTemp * 1.8 - 459.67)) + '<i class="wi wi-fahrenheit"></i>');

      highTempDiv.empty();
      highTempDiv.append((Math.round(highTemp * 1.8 - 459.67)) + '<i class="wi wi-fahrenheit"></i>');

      lowTempDiv.empty();
      lowTempDiv.append((Math.round(lowTemp * 1.8 - 459.67)) + '<i class="wi wi-fahrenheit"></i>');

    }

  }

}

//Initialize controller
controller.init();

              
            
!
999px

Console