묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결애플 웹사이트 인터랙션 클론!
영상 속 코드와 배포하신 소스 코드가 다르네요.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } body { height: 500vh; } .sample-video { position: fixed; top: 0; left: 0; width: 100%; } </style> </head> <body> <div class="container"> <!-- <video class="sample-video" src="../video/sample-low.mp4" muted></video> --> <video class="sample-video" src="../video/sample-high.mp4" muted></video> </div> <script> const videoElem = document.querySelector('.sample-video'); let videoDuration; videoElem.addEventListener('loadeddata', function() { console.log('비디오 로드 완료'); videoDuration = videoElem.duration; init(); }) let progress; let currentFrame; function init() { window.addEventListener('scroll', function () { progress = pageYOffset / (document.body.offsetHeight - window.innerHeight); console.log(progress); if (progress < 0) progress = 0; if (progress > 1) progress = 1; requestAnimationFrame(function() { videoElem.currentTime = videoElem.duration * progress; }) }); } </script> </body> </html>복붙해서 사용하세요.
-
해결됨쉽게 배우고, 포트폴리오로 만드는 반응형 웹! #설화수
안녕하세요 visual slide 질문이 있습니다.
방금전 선생님의 강의를 완강하고 복습중인데슬라이드 부분에 대해 질문이 있어서요.강의하신내용에 vosual 슬라이드부분을 왼쪽으로 부드럽게 animate로 넘기고 싶은데아직 제가 가진 지식으로는 혼자 작성해도 검색해보고 찾아봐도 안되서 질문드립니다.코드 어떤부분을 고쳐야 하는지 여쭤봅니다.ㅜㅜ
-
미해결Do It! 장고+부트스트랩: 파이썬 웹개발의 정석
포스트 목록 페이지 수정하기2 중에서 막히는 부분이 있습니다. (미분류)
안녕하세요 선생님. 강의 열심히 듣고 있습니다^^;다름이 아니라 아래와 같이 미분류 카운트가 입력되지 않아 오류가 발생하는 부분때문에 계속 찾아보았으나,답답한 마음에 질문글을 남깁니다.우선 카테고리 분류에서프로그래밍, 문화&예술 까진 카운트가 잘 입력됩니다.그렇지만 "미분류" 부분은 계속 () 으로 표시됩니다.분명 미분류 부분이 존재함에도 불구하고, 카운트가 되지 않는 건 무엇이 잘못되었는지 도저히 알기가 어렵습니다. 혹시 확인이 가능할까요?^^;; test.py 실행시 오류화면미분류() 카운트 부분을 주석처리하면 테스트는 잘 완료됩니다.총 4개의 페이지에 대한 코드를 올려봅니다.test.pybase.htmlviews.pypost_list.html test.pyfrom django.test import TestCase, Client from django.contrib.auth.models import User from bs4 import BeautifulSoup from .models import Post, Category # Create your tests here. class TestView(TestCase): def setUp(self): self.client = Client() # 방문하는 사람의 브라우저다 Client() self.user_trump = User.objects.create_user( username='trump', password='somepassword' ) self.user_obama = User.objects.create_user( username='obama', password='somepassword' ) self.category_programming = Category.objects.create( name='programming', slug='programming' ) self.category_music = Category.objects.create( name='music', slug='music' ) self.post_001 = Post.objects.create( title='첫 번째 포스트입니다.', content='Hello, world, we are the world', category=self.category_programming, author=self.user_trump, ) self.post_002 = Post.objects.create( title='두 번째 포스트입니다.', content='1등이 전부는 아니잖아요. 저는 개발을 좋아할겁니다.', category=self.category_music, author=self.user_obama, ) self.post_003 = Post.objects.create( title='세 번째 포스트입니다.', content='Category 가 없을 수도 있죠.', author=self.user_obama, ) def navbar_test(self, soup): navbar = soup.nav self.assertIn('Blog', navbar.text) self.assertIn('about_me', navbar.text) logo_btn = navbar.find('a', text='Do it Django') self.assertEqual(logo_btn.attrs['href'], '/') home_btn = navbar.find('a', text='Home') self.assertEqual(home_btn.attrs['href'], '/') blog_btn = navbar.find('a', text='Blog') self.assertEqual(blog_btn.attrs['href'], '/blog/') about_me_btn = navbar.find('a', text='about_me') self.assertEqual(about_me_btn.attrs['href'], '/about_me/') def category_card_test(self, soup): categories_card = soup.find('div', id='categories-card') self.assertIn('Categories', categories_card.text) self.assertIn( f'{self.category_programming} ({self.category_programming.post_set.count()})', categories_card.text ) self.assertIn( f'{self.category_music} ({self.category_music.post_set.count()})', categories_card.text ) self.assertIn( f'미분류 ({Post.objects.filter(category=None).count()})', categories_card.text ) def test_post_list_with_posts(self): self.assertEqual(Post.objects.count(), 3) # 1.1 포스트 목록 페이지 (post_list)를 연다. response = self.client.get('/blog/') # 1.2 정상적으로 페이지가 로드된다. self.assertEqual(response.status_code, 200) # 1.3 페이지 타이틀에 Blog 라는 문구가 있다. soup = BeautifulSoup(response.content, 'html.parser') self.assertIn('Blog', soup.title.text) self.navbar_test(soup) self.category_card_test(soup) # 3-2. 포스트 목록 페이지를 새로 고침 했을 때, response = self.client.get('/blog/') soup = BeautifulSoup(response.content, 'html.parser') # 3-3. 메인영역에 포스트 2개의 타이틀이 존재한다. main_area = soup.find('div', id='main-area') self.assertNotIn('아직 게시물이 없습니다.', main_area.text) post_001_card = main_area.find('div', id='post-1') self.assertIn(self.post_001.title, post_001_card.text) self.assertIn(self.post_001.category.name, post_001_card.text) post_002_card = main_area.find('div', id='post-2') self.assertIn(self.post_002.title, post_002_card.text) self.assertIn(self.post_002.category.name, post_002_card.text) post_003_card = main_area.find('div', id='post-3') self.assertIn(self.post_003.title, post_003_card.text) self.assertIn('미분류', post_003_card.text) self.assertIn(self.post_001.author.username.upper(), main_area.text) self.assertIn(self.post_002.author.username.upper(), main_area.text) self.assertIn(self.post_003.author.username.upper(), main_area.text) def test_post_list_without_post(self): Post.objects.all().delete() self.assertEqual(Post.objects.count(), 0) response = self.client.get('/blog/') self.assertEqual(response.status_code, 200) soup = BeautifulSoup(response.content, 'html.parser') self.navbar_test(soup) self.assertIn('Blog', soup.title.text) # 2-2. 메인영역에 "아직 게시물이 없습니다." 라는 문구가 나온다. main_area = soup.find('div', id='main-area') self.assertIn('아직 게시물이 없습니다.', main_area.text) def test_post_detail(self): self.assertEqual(Post.objects.count(), 3) # 1.2 그 포스트의 url은 '/blog/1/' 이다. self.assertEqual(self.post_001.get_absolute_url(), '/blog/1/') #.2. 첫 번째 포스트의 상세 페이지 테스트 # 2-1. 첫 번째 포스트의 url로 접근하면 정상적으로 작동한다. (status code : 200). response = self.client.get(self.post_001.get_absolute_url()) self.assertEqual(response.status_code, 200) soup = BeautifulSoup(response.content, 'html.parser') # # 2-2. 포스트 목록 페이지와 똑같은 네비게이션 바가 있다. self.navbar_test(soup) # 2-3. 첫 번째 포스트의 제목이 웹 브라우저 탭 타이틀에 들어있다. self.assertIn(self.post_001.title, soup.title.text) # 2-4. 첫 번째 포스트의 제목이 포스트 영역에 있다. main_area = soup.find('div', id='main-area') post_area = main_area.find('div', id='post-area') self.assertIn(self.post_001.title, post_area.text) # # 2-5. 첫 번째 포스트의 작성자(author)가 포스트 영역에 있다. (아직 구현할 수 없음) self.assertIn(self.user_trump.username.upper(), post_area.text) # # 2-6. 첫 번째 포스트의 내용(content)이 포스트 영역에 있다. self.assertIn(self.post_001.content, post_area.text) base.html<!DOCTYPE html> {% load static %} <html> <head> <title>{% block head_title %} Blog | 하도영 웹사이트 {% endblock %}</title> <link href="{% static 'blog/bootstrap/bootstrap.min.css' %}" rel="stylesheet" type="text/css"> <!-- <link href="./practice.css" rel="stylesheet" type="text/css"> --> <!-- 주석처리 키 ctrl + / --> <script src="https://kit.fontawesome.com/c1d4d1ab30.js" crossorigin="anonymous"></script> </head> <body> {% include 'blog/navbar.html' %} <div class="container"> <!-- 블로그 리스트 페이지 만들기 강의 5:04 blog 글자 부분 container 클래스에 의해 do it django 와 같은 간격으로 맞춰짐 --> <!-- 이 아래는 9:3, 좁을때는 8:4 로 나눌거임 --> <div class="row my-3"> <div class="col-md-8 col-lg-9", id="main-area"> {% block main_area %} {% endblock %} </div> <div class="col-md-4 col-lg-3"> <!-- Search widget--> <div class="card mb-4"> <div class="card-header">Search</div> <div class="card-body"> <div class="input-group"> <input class="form-control" type="text" placeholder="Enter search term..." aria-label="Enter search term..." aria-describedby="button-search" /> <button class="btn btn-primary" id="button-search" type="button">Go!</button> </div> </div> <!-- Categories widget--> <div class="card mb-4", id="categories-card"> <div class="card-header">Categories</div> <div class="card-body"> <div class="row"> <ul> {% for category in categories %} <li> <a href="#!">{{ category.name }} ({{ category.post_set.count }})</a> </li> {% endfor %} <!-- views.py 에 def get_context_data(self, **kwargs): 를 참고한다. --> <li> <a href="#!">미분류 ({{ no_category_post.count }})</a> </li> </ul> </div> </div> </div> </div> </div> </div> {% include 'blog/footer.html' %} <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script> </body> </html> views.pyfrom django.shortcuts import render from django.views.generic import ListView, DetailView from .models import Post, Category class PostList(ListView): model = Post # template_name = 'blog/post_list.html' ordering = '-pk' def get_context_data(self, **kwargs): context = super(PostList, self).get_context_data() context['categories'] = Category.objects.all() context['no_category_post.count'] = Post.objects.filter(category=None).count() # 미분류인 애들이 몇개인지 확인한다. filter기능을 이용해 none 인 애를 확인하고 count() 에 숫자를 담아 no_category_post.count에 넣어준다. return context class PostDetail(DetailView): model = Post template_name = 'blog/post_detail.html' # def index(request): # posts = Post.objects.all().order_by('-pk') # # pk는 순서대로 -pk 는 역순으로 최신 쓰레드가 위로 나오도록 조회 # return render( # request, # 'blog/index.html', # { # 'posts': posts, # } # ) # def single_post_page(request, pk): # post = Post.objects.get(pk=pk) # # return render( # request, # 'blog/single_page.html', # { # 'post': post, # } # ) post_list.html{% extends 'blog/base.html' %} {% block main_area %} <h1> Blog </h1> {% if post_list.exists %} {% for p in post_list %} <!-- Blog Post --> <div class="card mb-4", id="post-{{ p.id }}"> {% if p.head_image %} <img class="card-img-top" src="{{ p.head_image.url}}" alt="{{ p.title }}" /> {% else %} <img class="card-img-top" src="https://picsum.photos/seed/{{ p.id }}/600/200" alt="{{ p.title }}" /> {% endif %} <div class="card-body"> <!-- <div class="small text-muted">January 1, 2022</div>--> {% if p.category %} <span class="badge badge-secondary float-right">{{ p.category }} </span> {% else %} <span class="badge badge-secondary float-right">미분류</span> {% endif %} <h2 class="card-title h4">{{ p.title }}</h2> {% if p.hook_text %} <h5 class="text-muted">{{ p.hook_text }}</h5> {% endif %} <p class="card-text">{{ p.content | truncatewords:45 }}</p> <a href="{{ p.get_absolute_url }}" class="btn btn-primary">Read more →</a> </div> <div class="card-footer text-muted"> Posted on {{ p.created_at }} by <a href="#">{{ p.author | upper }}</a> </div> </div> {% endfor %} {% else %} <h1> 아직 게시물이 없습니다. </h1> {% endif %} <!-- Pagination--> <ul class="pagination justify-content-center my-4"> <li class="page-item"> <a class="page-link" href="#!">← Older</a> </li> <li class="page-item disabled"> <a class="page-link" href="#!">Newer →</a> </li> </ul> {% endblock %}
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
메인페이지 출력 오류
안녕하세요 메인 페이지 출력이 안되어서 질문 남깁니다해당 코드와 실행결과 사진으로 첨부했습니다
-
해결됨[코드캠프] 시작은 프리캠프
반복문 강의 예제 질문
안녕하세요.반복문 강의 예제를 복습하다가 궁금한 점이 생겨서 질문 남깁니다.나이를 12살에서 5살로 바꿔서 해봤는데, 어린이입니다가 뜨지 않고 에러 메세지가 뜨는데왜그런건지 모르겠습니다 ㅠㅠ
-
해결됨[코드캠프] 시작은 프리캠프
코딩 초보
안녕하세요. 강의 내용 관련된 질문은 아니지만..답답해서요ㅜㅠ 저는 코딩 공부를 시작한 지 2개월정도 된 완전 코린이입니다..! 원래 처음엔 이해가 안되고 어려운 게 맞겠죠..?ㅠ에러 뜰때마다 원인도 모르겠어서 몇시간 붙잡고 있던 적도 많고 개념 이해하기도 어려운데 ...지식공유자님은 처음에 어떤식으로 공부하셨는지 궁금합니다!! ㅠ
-
미해결비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
[해결완료]nginx root 경로 변경 404 not found
경로 설정은 잘 된거같은데not found가 나오네요 ㅠnginx restart도 해봤습니다.문제가 뭘까요?https://github.com/memilmooki/FoodMap
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
setProducts 질문
위 사진처럼 setProducts 밑에 console.log를 해봤는데한번 출력될 줄 알았는데 왜 두 번 출력되는 건가요?
-
해결됨[코드캠프] 시작은 프리캠프
id와 class
안녕하세요강의를 다 듣고나서 궁금한점이 생겼는데요. id선택자와 class선택자에 대한 부분인데요강의에서 css를 사용할때 class선택자를 사용하고 js를 사용할때 id선택자를 사용하였는데제가 알기로는 css에서도 id선택자를 사용할수 있고 js에서도 class선택자를 사용할 수 있는걸로 알고 있는데 강의에선 안쓰더라고요? 그럴만한 이유가 있을까요?? ++++좋은 강의 감사합니다!
-
해결됨[코드캠프] 시작은 프리캠프
싸이월드 만들기 1탄 과제 코드 질문
싸이월드 만들기 1탄 과제 만들기 코드를제가 한 과제와 비교하면서 공부하고 있습니다.저하고 다른 부분이 있어서 그 이유가 궁금합니다. HTML <div class="left__body__footer"> <div class="wrapper__feel"> <div class="feel__title">오늘의 기분</div> <select class="feel__select"> <option>기쁨 😊</option> <option>슬픔 😭</option> <option>화남 😠</option> <option>분노 😡</option> </select> </div> </div>html은 과제 class 이름 참고하면서 만들어서 똑같습니다. CSS.wrapper__feel { <--------- 과제 예시 코드 display: flex; flex-direction: column; justify-content: center; width: 100%; }위의 코드가 과제 예시 코드입니다.아래 코드가 제가 한 코드입니다..feel__select { <------ 제가 한 코드 width: 100%; } <-width 차이-> 저는 div태그가 블록레벨 태그라서 <div class="feel__title">오늘의 기분</div> 안에 있는 '오늘의 기분'은 왼쪽으로 정렬되기 때문에 그대로 두고위의 코드 예시처럼 select 박스만 크기 조절하여 해결했습니다. 저는 과제 내용의 셀렉트 박스의 width를 select 박스 자체에 100%로 주었고과제 예시 코드는 자식요소의 div와 select가 포함된 <div class="wrapper__feel"> div를 정렬한 뒤 width 100%를 주었더라구요.그런데 아래의 코드처럼 flex 정렬부분을 주석처리하니깐 width 속성이 안 먹더라구요.그 이유가 궁금합니다. .wrapper__feel { /* display: flex; flex-direction: column; justify-content: center; */ width: 100%; } +++ 제가 한 코드를 지우고 과제 예시 코드 중 width: 100%; 부분을 지워도 과제 예시 코드와 결과와 같습니다.flex 정렬이 되면 footer의 width 100% 속성이 상속되는 건가요?display 정렬과 width의 관계에 대해 알고 싶습니다..wrapper__feel { display: flex; flex-direction: column; justify-content: center; /* width: 100%; */ <---- 과제 예시 코드의 이 부분을 지워도 결과가 같습니다. }제가 한 코드를 지우고 이렇게만 해도 같은 결과가 나옵니다. 차이를 알고 싶습니다..feel__select { <- 제가 한 이 코드를 지우고 위의 코드 정렬부분만 실행해도 결과가 같음. width: 100%; }
-
미해결처음 만난 리액트(React)
(실습) Context를 사용하여 테마 변경 기능 만들기 에서 테마 변경이 안 돼요.
테마 변경 버튼을 눌러도 테마 색 변경이 안 됩니다. 이전에 카드 만들기 실습에서도 색이 안 나오는 걸 보면 제 습관적인 실수인데... 제 실수를 못 찾겠습니다...
-
해결됨[코드캠프] 시작은 프리캠프
싸이월드 2탄 코드가 없는 것 같습니다.
안녕하세요.싸이월드 2탄 코드가 없는 것 같습니다. 2탄이 1탄 코드와 동일한 것 같네요.강사님, 설명해주신 <div class="wrapper__right"> 관련된 코드가 전부 없네요.노션 페이지 업데이트 부탁드립니다.
-
해결됨코딩은 처음이라 with 웹 퍼블리싱 - HTML 기초
contact 부분을 filedset으로 만들어줘도 되나요 ?
contact 부분을 filedset으로 만들어줘도 되나요 ? filedset 대신 div 태그로 각각 따로 만들어준 이유가 궁금합니다 filedset 으로 만들때와 div로 만들때 어떤 차이가 있나요 ?
-
미해결비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지
git 내부에서 secret.js 삽입 후 node index.js 에러
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 현상은 다음과 같이 나오고 있습니다. secret.js에는 다음과 같이 잘 들어가있습니다. 저의 git에도 database라는 js파일이 존재합니다.왜그럴까요! 에러메세지 첨부합니다.root@ip-172-31-85-206:/home/ubuntu/FoodMap/back# node index.js internal/modules/cjs/loader.js:818 throw err; ^ Error: Cannot find module '../../back/config/database' Require stack: - /home/ubuntu/FoodMap/back/src/controllers/indexController.js - /home/ubuntu/FoodMap/back/src/routes/indexRoute.js - /home/ubuntu/FoodMap/back/config/express.js - /home/ubuntu/FoodMap/back/index.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15) at Function.Module._load (internal/modules/cjs/loader.js:667:27) at Module.require (internal/modules/cjs/loader.js:887:19) at require (internal/modules/cjs/helpers.js:74:18) at Object.<anonymous> (/home/ubuntu/FoodMap/back/src/controllers/indexController.js:1:18) at Module._compile (internal/modules/cjs/loader.js:999:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Module.require (internal/modules/cjs/loader.js:887:19) { code: 'MODULE_NOT_FOUND', requireStack: [ '/home/ubuntu/FoodMap/back/src/controllers/indexController.js', '/home/ubuntu/FoodMap/back/src/routes/indexRoute.js', '/home/ubuntu/FoodMap/back/config/express.js', '/home/ubuntu/FoodMap/back/index.js' ] }
-
미해결SCSS(SASS)+GRID+FLEX 실전 포트폴리오 퍼블리싱
live sass complier 버전 문제
안녕하세요!live sass compiler 익스텐션 설치 및 세팅 영상 공부하고 있는데요!강의에 나오는 ritwick dey의 익스텐션은 더 이상 사용이 불가하다고 하여, 그 아래에 있는 glenn marks 버전을 설치했습니다.설치 후 json 세팅을 하고 있는데설정 > 확장에 live sass compiler가 나오지 않아 문의 드립니다. sass를 검색했을 때 아래 부분만 나오는데요! json 세팅을 할 수 있는 다른 방법이 있을까요? 감사합니다.
-
미해결애플 웹사이트 인터랙션 클론!
pageYOffset || scrollY
안녕하세요-!선생님께서 pageYOffset을 사용하셨는데, 그 이유가 IE에서도 호환되기하기 위함이 맞을까요?IE를 고려하지 않는다면 scrollY를 사용하는게 맞는지 궁금합니다.
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
상품업로드 화면 구현 시 이미지 업로드 시점 관련
안녕하세요. 수업 잘 듣고 있습니다!수업관련 질문은 아니지만 일반적인 구현방법도 이런가해서 문의 남겨봅니다^^이미지 업로드 화면에서업로드 할 사진을 선택하면 서버측으로 먼저 이미지를 전송하는 방식으로 구현하셨는데 이미지 선택 시에는 로컬(클라이언트PC)의 이미지로 보여주고 [상품 등록하기] 버튼을 눌렀을 때 서버로 업로드 하면서 DB에 등록하는 것이 어떨까해서요.이미지를 계속 변경하면 서버에 업로드가 되는 듯 하여...문의한번 해봅니다^^ 다른 수강생분들에게도 문제 해결에 도움을 줄 수 있도록 좋은 질문을 남겨봅시다 :) 1. 질문은 문제 상황을 최대한 표현해주세요.2. 구체적이고 최대한 맥락을 알려줄 수 있도록 질문을 남겨 주실수록 좋습니다. 그렇지 않으면 답변을 얻는데 시간이 오래걸릴 수 있습니다 ㅠㅠex) A라는 상황에서 B라는 문제가 있었고 이에 C라는 시도를 해봤는데 되지 않았다!3. 먼저 유사한 질문이 있었는지 꼭 검색해주세요!
-
해결됨[코드캠프] 강력한 CSS
가상요소 선택자 after 기본 dislplay 값
강의 중에선 after의 display 기본 값이 block이기 때문에명시할 필요는 없지만 flex-direction 처럼 명시해주는 것이 좋다고 말씀해주셨습니다.근데, 개발자도구를 통해서 기본값을 확인해보니 display를 명시해주지 않으면 inline으로 지정되어 있는데 최근에 바뀐걸까요?
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
length 오류
콘솔 결과와 error가 같이 출력됩니다!
-
미해결[2025년 출제기준] 웹디자인기능사 실기시험 완벽 가이드
.sub-menu를 ABC형의 위치에 놓고 CSS를 작성했습니다.
잘 실행되는데요.이렇게 작성해도 될까요?<!DOCTYPE html><html lang="ko"><head> <meta charset="UTF-8"> <title>최종본 - D3</title> <link rel="stylesheet" href="css/style.css"></head><body> <div class="container"> <div class="main-content"> <div class="left"> <header> <div class="header-logo"> <a href="#none"><img src="images/header-logo.png" alt="header logo"></a> </div> <div class="navi"> <!-- Navigation --> <ul class="menu"> <li> <a href="#none">MENU-1</a> <div class="sub-menu"> <a href="#none">SUBMENU-1-1</a> <a href="#none">SUBMENU-1-2</a> <a href="#none">SUBMENU-1-3</a> <a href="#none">SUBMENU-1-4</a> </div> </li> <li> <a href="#none">MENU-2</a> <div class="sub-menu"> <a href="#none">SUBMENU-2-1</a> <a href="#none">SUBMENU-2-2</a> <a href="#none">SUBMENU-2-3</a> <a href="#none">SUBMENU-2-4</a> </div> </li> <li> <a href="#none">MENU-3</a> <div class="sub-menu"> <a href="#none">SUBMENU-3-1</a> <a href="#none">SUBMENU-3-2</a> <a href="#none">SUBMENU-3-3</a> <a href="#none">SUBMENU-3-4</a> </div> </li> <li> <a href="#none">MENU-4</a> <div class="sub-menu"> <a href="#none">SUBMENU-4-1</a> <a href="#none">SUBMENU-4-2</a> <a href="#none">SUBMENU-4-3</a> <a href="#none">SUBMENU-4-4</a> </div> </li> <div class="sub-back"></div> </ul> <!-- Navigation --> </div> <div class="spot-menu"> <a href="#none">로그인</a> <a href="#none">회원가입</a> </div> </header> </div> <div class="right"> <div class="slide"> <div class="slide-image"> <div class="slide-image-inner"> <a href="#none1"><img src="images/slide-d-01.jpg" alt="slide1"></a> <a href="#none2"><img src="images/slide-d-02.jpg" alt="slide2"></a> <a href="#none3"><img src="images/slide-d-03.jpg" alt="slide3"></a> </div> </div> <div class="slide-banner"> <a href="#none"><img src="images/banner-01.png" alt="banner1"></a> <a href="#none"><img src="images/banner-02.png" alt="banner2"></a> <a href="#none"><img src="images/banner-03.png" alt="banner3"></a> </div> </div> <div class="items"> <div class="shortcut"> <img src="images/shortcut-01.png" alt="shortcut thumnail"> <div class="shortcut-content"> <h3>얼리버드 선착순 할인 이벤트, 신규강의 최대 30% 할인</h3> <p> 12월은 사랑의 달~ 한일외국어학원이 여러분께 사랑을 뿌려요~ 12월 개강반을 12월 06일까지 접수하는 분들께는 15%~ 20% 의 얼리버드 할인을 제공합니다. 더불어 소중한 리뷰를 꼼꼼히 남겨주시는 분들을 뽑아 더 큰 적립금을 추가지급해 드릴 예정이오니 리뷰도 놓치지 마시고 작성해주세요~^^<br> <b>기간: 2022년 12월 18일~ 12월 25일</b> </p> </div> <a href="#none"><img src="images/shortcut-02.png" alt="shortcut icon"></a> </div> <div class="news-gallery"> <div class="tab-inner"> <div class="btn"> <a class="active" href="#none">공지사항</a> <a href="#none">갤러리</a> </div> <div class="tabs"> <div class="tab1"> <a class="open-modal" href="#none">스트리밍 서버 이전 작업으로 2시간 서비스 중지<b>2022.12.20</b></a> <a href="#none">얼리버드 선착순 할인 이벤트 최대 50% 할인 <b>2022.10.13</b></a> <a href="#none">내 집 마련의 꿈을 꿈이 아닌 현실로 만드는 진짜 방법 <b>2022.11.31</b></a> <a href="#none">외국인과 영어로 네이티브처럼 대화하는 노하우! <b>2022.08.09</b></a> <a href="#none">월 500만원 매출을 내는 블로그 운영하는 노하우 <b>2022.07.07</b></a> </div> <div class="tab2"> <a href="#none"> <img src="images/gallery-01.png" alt="gallery1"> <span>Gallery title Text</span> </a> <a href="#none"> <img src="images/gallery-02.png" alt="gallery2"> <span>Gallery title Text</span> </a> <a href="#none"> <img src="images/gallery-03.png" alt="gallery3"> <span>Gallery title Text</span> </a> <a href="#none"> <img src="images/gallery-04.png" alt="gallery4"> <span>Gallery title Text</span> </a> <a href="#none"> <img src="images/gallery-05.png" alt="gallery5"> <span>Gallery title Text</span> </a> <a href="#none"> <img src="images/gallery-06.png" alt="gallery6"> <span>Gallery title Text</span> </a> <a href="#none"> <img src="images/gallery-07.png" alt="gallery7"> <span>Gallery title Text</span> </a> </div> </div> </div> </div> </div> </div> </div> <footer> <div class="footer-logo"> <a href="#none"><img src="images/footer-logo.png" alt="footer logo"></a> </div> <div class="footer-content"> <div class="footer-link"> <a href="#none">기업소개</a> <a href="#none">제휴 및 입점 문의</a> <a href="#none">이용약관</a> <a href="#none">개인정보처리방침</a> <a href="#none">이메일무단수집거부</a> <a href="#none">사이트맵</a> <a href="#none">인재채용</a> </div> <div class="copyright"> 상호 : (주)코딩웍스 | 대표자 : 홍길동 | 개인정보관리책임자 : 성춘향 부장 사업장주소 : 경기도 남양주시 별내동 1234 코딩웍스 빌딩 6층 (주)코딩웍스 </div> </div> </footer> </div> <!-- Modal --> <div class="modal"> <div class="modal-content"> <h2>스트리밍 서버 이전으로 서비스 장애</h2> <p> 스트리밍 서버 이전 작업으로 2시간 서비스 중지됩니다. 주요 작업 내용은 아래와 같습니다. <ol> <li>서버 이전에 따른 DNS 이전으로 기존 호스팅 서비스 대체</li> <li>문자셋을 utf-8로 변경 후 모바일 등에 대처하기 위해 미리 조치</li> <li>스트리밍 서버 CDN과 연동 후 멀티미디어 이러닝 서비스가 제공</li> </ol> 위 내용을 보시면 제법 큰 작업이었음을 알 수 있습니다. 특히 문자셋의 변경에 따라 기존의 DB, data, 웹사이트 솔루션 등의 커스트마이징 등에 상당한 어려움이 있었고, 이에 따른 일부 접속 오류가 있을 수 있었음에 양해를 구합니다. 특히 인터넷익스플로러 11로 접속하셨을 경우 일부 문제은행 목차가 출력되지 않았을 수도 있습니다.<br><br> 서버 이전 작업으로 고객님들께 불편을 드려서 대단히 죄송합니다. 정상 운영되도록 최선을 다하겠습니다. 감사합니다. </p> <a class="close-modal" href="#none">닫기</a> </div> </div> <!-- Modal --> <script src="script/jquery-1.12.4.js"></script> <script src="script/custom.js"></script> </body></html>@charset "utf-8";body { margin: 0; background-color: #fff; color: #333;}a { text-decoration: none; color: inherit;}/* Entire Layout */.container {}.main-content { display: flex;}.main-content > div {}.left { width: 200px;}.right { flex: 1;}/* Header */header {}header > div {}.header-logo { height: 100px; padding-top: 10px; box-sizing: border-box;}.navi { height: 150px;}/* Navigation */.menu{ width: 90%; margin: 0 auto; margin-top: 10px; padding: 0; position: relative; } .menu li{ text-align: center; box-sizing: border-box; position: relative; } .menu li> a{ display: block; border: 1px solid black; padding: 5px; transition: 0.5s; } .menu li:hover > a{ background-color: rgba(0, 0, 0, 0.5); color: #fff; } .sub-menu{ width: 1000px; height: 35px; position: absolute; top:0; left: 100%; display: none; z-index: 100; } .sub-menu a{ float: left; width: 150px; color: #fff; padding: 5px; transition: 0.5s; } .sub-menu a:hover{ background-color: #000; color: #fff; } .sub-back{ width: calc(100vw - 190px); height: 135px; background-color: rgba(0, 0, 0, 0.5); position: absolute; left: 100%; top: 0; z-index: 90 ; display: none; }/* spot-menu */.spot-menu { text-align: center;}.spot-menu a:after { content: '|'; margin-left: 5px;}.spot-menu a:last-child:after { display: none;}.spot-menu a:hover { text-decoration: underline;} /* Slide */.slide { height: 400px; position: relative;}.slide > div {}.slide-image { height: 400px;}.slide-image-inner { height: inherit;}.slide-image-inner a { /* 실제로 움직이는 요소 */ position: absolute; top: 0; left: 0; animation: slide 10s linear infinite; visibility: hidden; height: inherit; width: 100%;}.slide-image-inner a:nth-child(1) { animation-delay: 0s;}.slide-image-inner a:nth-child(2) { animation-delay: 3.5s;}.slide-image-inner a:nth-child(3) { animation-delay: 7s;}.slide-image-inner a img { width: inherit; height: inherit; object-fit: cover;}@keyframes slide { 0% { opacity: 0; } 5% { visibility: visible; /* 0% 구간에 visibility: hidden 상태를 보이는 상태로 전환 */ opacity: 1; } 35% { opacity: 1; } 40% { visibility: hidden; /* 보이는 구간이 끝났으니까 투명도 0과 함께 실제로도 보이지 않는 상태로 전환 */ opacity: 0; } 100% { opacity: 0; }}.slide-banner { position: absolute; top: 0; right: 0;}.slide-banner img { width: 150px; display: block;}/* Shortcut */.shortcut { height: 200px; display: flex; align-items: center; margin: 0 15px; gap: 25px; }/* News & Gallery */.items {}.items > div {}/* News & Gallery */.news-gallery { /* border: 1px solid green; */ height: 250px;}.tab-inner { width: 95%; margin: auto; margin-top: 25px;}.btn {}.btn a { border: 1px solid #000; display: inline-block; width: 100px; text-align: center; padding: 5px; border-radius: 5px 5px 0 0; margin-right: -6px; border-bottom: none; margin-bottom: -1px; background-color: #ddd;}.btn a.active { background-color: #fff;}.tabs {}.tab1 { border: 1px solid #000; padding: 0 15px;}.tab1 a { display: block; padding: 5px; border-bottom: 1px dashed #bbb;}.tab1 a:last-child { border-bottom: none;}.tab1 a b { float: right; font-weight: normal;}.tab2 { display: none; border: 1px solid #000; height: 170px; text-align: center; padding-top: 20px; box-sizing: border-box;}/* ▼ D유형과 E유형 공개도면에 따라 약간의 수정 */.tab2 a { display: inline-block; text-align: center; margin: 0 15px;}.tab2 a img { height: 120px; border-radius: 5px;}.tab2 a span { display: block;}/* Footer */footer { display: flex;}footer > div { height: 120px;}.footer-logo { width: 200px; padding-top: 20px; box-sizing: border-box; /* display: flex; align-items: center; */}.footer-content { flex: 1;}.footer-content div { height: 60px; box-sizing: border-box; /* display: flex; align-items: center; */}.footer-link { padding-top: 30px;}.copyright { padding-top: 10px;}.footer-link a { color: royalblue;}.footer-link a:after { content: '|'; color: #ccc; margin: 0 5px;}.footer-link a:last-child:after { display: none;}.footer-link a:hover { text-decoration: underline;}/* Modal */.modal { background-color: rgba(0, 0, 0, 0.19); position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 100; display: none;}.modal-content { width: 450px; background-color: #fff; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 20px; border-radius: 10px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.13);}.close-modal { float: right; border: 1px solid #000; padding: 5px 10px;}/* 이건 하면 좋고 안해도 괜찮습니다. */.modal-content h2 { text-align: center; background-color: yellowgreen; color: #fff; padding: 7px;}.modal-content ol { padding-left: 18px; font-size: 14px; font-weight: 500;}/* Navigation */// $('.menu li').mouseenter(function(){// $('.sub-menu, .sub-back').stop().slideDown()// })// $('.menu').mouseleave(function(){// $('.sub-menu, .sub-back').stop().slideUp()// })$('.menu li').mouseenter(function(){ $('.sub-menu, .sub-back').stop().fadeIn()})$('.menu').mouseleave(function(){ $('.sub-menu, .sub-back').stop().fadeOut()})/* Tab Menu */$('.btn a:first-child').click(function () { $('.tab1').show() $('.tab2').hide() $(this).addClass('active') $(this).siblings().removeClass('active')})$('.btn a:last-child').click(function () { $('.tab2').show() $('.tab1').hide() $(this).addClass('active') $(this).siblings().removeClass('active')})/* Modal */$('.open-modal').click(function(){ $('.modal').fadeIn()})$('.close-modal').click(function(){ $('.modal').fadeOut()})