├── README.md ├── index.html ├── index.js └── styles.css /README.md: -------------------------------------------------------------------------------- 1 | # RECIPE_APP-using-html-css-js -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | RecipeApp 11 | 12 | 13 | 14 |
15 | 22 |
23 |
24 |
25 |
26 |

Search your favourite recipes...

27 |
28 |
29 | 34 |
35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const searchBtn = document.querySelector('.searchBtn'); 2 | const searchBox = document.querySelector('.searchBox'); 3 | const recipeContainer = document.querySelector('.recipe-container'); 4 | const recipeDetailsContent = document.querySelector('.recipe-details-content'); 5 | const recipeCloseBtn = document.querySelector('.recipe-close-btn'); 6 | 7 | 8 | const fetchRecipes = async (query) => { 9 | recipeContainer.innerHTML = "

Fetching Recipes...

"; 10 | try { 11 | 12 | 13 | const data = await fetch(`https://www.themealdb.com/api/json/v1/1/search.php?s=${query}`); 14 | const response = await data.json(); 15 | recipeContainer.innerHTML = ""; 16 | response.meals.forEach(meal => { 17 | const recipeDiv = document.createElement('div'); 18 | recipeDiv.classList.add('recipe'); 19 | recipeDiv.innerHTML = ` 20 |

${meal.strMeal}

21 |

${meal.strArea} Dish

22 |

Belongs to ${meal.strCategory} category

` 23 | 24 | 25 | const button = document.createElement('button'); 26 | button.textContent = "View Recipe"; 27 | recipeDiv.appendChild(button); 28 | button.addEventListener('click', () => { 29 | openRecipePopup(meal); 30 | }); 31 | 32 | recipeContainer.appendChild(recipeDiv); 33 | 34 | }); 35 | } catch (error) { 36 | recipeContainer.innerHTML = "

Error in Fetching Recipes...

"; 37 | } 38 | } 39 | 40 | 41 | const fetchIngredients = (meal) => { 42 | let ingredientsList = ""; 43 | for (let i = 1; i <= 20; i++) { 44 | const ingredient = meal[`strIngredient${i}`]; 45 | if (ingredient) { 46 | const measure = meal[`strMeasure${i}`]; 47 | ingredientsList += `
  • ${measure} ${ingredient}
  • ` 48 | } 49 | else { 50 | break; 51 | } 52 | } 53 | return ingredientsList; 54 | } 55 | 56 | 57 | const openRecipePopup = (meal) => { 58 | recipeDetailsContent.innerHTML = `

    ${meal.strMeal}

    59 |

    Ingredients:

    60 | 61 |
    62 |

    Instructions:

    63 |

    ${meal.strInstructions}

    64 |
    65 | 66 | ` 67 | 68 | 69 | recipeDetailsContent.parentElement.style.display = "block"; 70 | } 71 | recipeCloseBtn.addEventListener('click', () => { 72 | recipeDetailsContent.parentElement.style.display = "none"; 73 | }); 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | searchBtn.addEventListener('click', (e) => { 87 | e.preventDefault(); 88 | const searchInput = searchBox.value.trim(); 89 | if (!searchInput) { 90 | recipeContainer.innerHTML = `

    Type the meal in the search box.

    `; 91 | return; 92 | } 93 | fetchRecipes(searchInput); 94 | }); 95 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: Verdana, Geneva, Tahoma, sans-serif; 6 | 7 | } 8 | 9 | body { 10 | background-color: #2b1d0f; 11 | color: #fff; 12 | } 13 | 14 | header nav { 15 | background-color: #212121; 16 | padding: 20px; 17 | display: flex; 18 | justify-content: space-between; 19 | align-items: center; 20 | z-index: 1; 21 | } 22 | 23 | header nav h1 { 24 | font-size: 26px; 25 | font-weight: 700; 26 | letter-spacing: 1px; 27 | text-transform: uppercase; 28 | } 29 | 30 | header nav form { 31 | display: flex; 32 | justify-content: center; 33 | 34 | } 35 | 36 | form input[type="text"], 37 | button [type="submit"] { 38 | border: none; 39 | font-size: 18px; 40 | padding: 10px; 41 | border-radius: 4px; 42 | 43 | } 44 | 45 | button { 46 | margin-left: 10px; 47 | padding: 10px; 48 | } 49 | 50 | form button[type="submit"] { 51 | background-color: #f44336; 52 | color: #fff; 53 | cursor: pointer; 54 | transition: background-color 0.2s ease-in-out; 55 | 56 | } 57 | 58 | form button[type="submit"]:hover, 59 | .recipe button:hover, 60 | .recipe-close-btn:hover { 61 | background-color: #ff5c5c; 62 | } 63 | 64 | .recipe-container { 65 | text-align: center; 66 | margin-top: 20px; 67 | display: grid; 68 | grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); 69 | grid-gap: 40px; 70 | width: 80%; 71 | margin: 10px auto; 72 | padding: 20px; 73 | place-items: center; 74 | } 75 | 76 | .recipe { 77 | background-color: #fff; 78 | display: flex; 79 | flex-direction: column; 80 | color: #000; 81 | border-radius: 6px; 82 | box-shadow: 0 5px 10px rgba(78, 73, 73, 0.1), -5px -5px 10px rgba(34, 34, 34, 0.5); 83 | cursor: pointer; 84 | max-width: 350px; 85 | transition: transform 0.3s ease-in-out; 86 | 87 | } 88 | 89 | .recipe:hover { 90 | transform: scale(1.02); 91 | } 92 | 93 | .recipe img { 94 | height: 300px; 95 | } 96 | 97 | .recipe h3 { 98 | font-size: 20px; 99 | margin-block: 5px; 100 | } 101 | 102 | .recipe p { 103 | font-size: 20px; 104 | color: #4a4a4a; 105 | margin: 5px 0; 106 | } 107 | 108 | .recipe span { 109 | font-weight: 600; 110 | } 111 | 112 | .recipe button { 113 | font-size: 20px; 114 | font-weight: 600; 115 | padding: 10px; 116 | border-radius: 5px; 117 | cursor: pointer; 118 | margin: 18px auto; 119 | background-color: #f44336; 120 | color: #fff; 121 | border: none; 122 | } 123 | 124 | @media screen and (max-width:600px) { 125 | header nav form { 126 | width: 80%; 127 | margin-top: 20px; 128 | 129 | } 130 | 131 | header nav { 132 | flex-direction: column; 133 | } 134 | 135 | 136 | } 137 | 138 | .recipe-details { 139 | display: none; 140 | position: fixed; 141 | top: 50%; 142 | left: 50%; 143 | transform: translate(-50%, -50%); 144 | background-color: #694c3f; 145 | -webkit-transform: translate(-50%, -50%); 146 | border-radius: 12px; 147 | width: 40%; 148 | height: 60%; 149 | font-size: 20px; 150 | transition: all 0.5s ease-in-out; 151 | overflow-y: scroll; 152 | } 153 | 154 | .recipe-details::-webkit-scrollbar { 155 | width: 10px; 156 | } 157 | 158 | .recipe-details::-webkit-scrollbar-thumb { 159 | background-color: #b5b5ba; 160 | border-radius: 16px; 161 | --webkit-border-radius: 16px; 162 | 163 | } 164 | 165 | body::-webkit-scrollbar { 166 | width: 16px; 167 | } 168 | 169 | body::-webkit-scrollbar-thumb { 170 | background-color: #a1a1a1; 171 | border-radius: 6px; 172 | 173 | 174 | } 175 | 176 | body::-webkit-scrollbar-track { 177 | background-color: #ebebeb; 178 | } 179 | 180 | 181 | 182 | .recipe-details-content { 183 | padding: 30px; 184 | 185 | } 186 | 187 | .recipeName { 188 | text-align: center; 189 | text-transform: uppercase; 190 | text-decoration: underline; 191 | margin-bottom: 20px; 192 | } 193 | 194 | .ingredientList li { 195 | margin-top: 10px; 196 | margin-left: 20; 197 | } 198 | 199 | .recipeInstructions p { 200 | line-height: 30px; 201 | white-space: pre-line; 202 | margin-bottom: 20px; 203 | } 204 | 205 | .recipe-close-btn { 206 | border: none; 207 | font-size: 18px; 208 | padding: 8px; 209 | border-radius: 4px; 210 | background-color: #f44336; 211 | color: #fff; 212 | position: absolute; 213 | top: 20px; 214 | right: 20px; 215 | width: 20px; 216 | height: 20px; 217 | display: flex; 218 | justify-content: center; 219 | align-items: center; 220 | 221 | } 222 | 223 | .ingredientList { 224 | margin-bottom: 20px; 225 | } --------------------------------------------------------------------------------