Project 0 : Search
Project 0 - CS50's Web Programming with Python and JavaScript
Search - CS50's Web Programming with Python and JavaScript
Process
Directory Structure & Wireframe
search - index.html
advanced.html
images.html
styles.css
Google Search Page(index.html)
Google HTML
<a class="gb_X" aria-label="이미지 검색 " data-pid="2" href="https://www.google.com/imghp?hl=ko&authuser=0&ogbl" target="_top">이미지</a>
- jscontroller: Google's JavaScript properties. Internal systems for connecting features to specific UI elements.
- <header>: Semantic tag. The top area of the page that usually contains logos, navigation, user menus.
- aria-label: Accessibility properties. Read as a link name in the accessibility tool.
- data-pid: Custom data that is defined by developers, not standard attribute.
- target: Specifies where to display the linked URL.
_self: Default. Load the URL into the same as current window.
_blank: Load the URL into a new tab.
_parent: Load the URL into the parent.
_top: Load the URL into the top-level browsing context.
- role: One of the ARIA(Accessibility) properties that tells the secondary device such as screen reader what role this element is. / Usually, no need to put a "role" on the tag.
<form action="/search" autocomplete="off" method="GET" role="search">
<input name="source" type="hidden" value="hp">
- autocomplete="off": Turn off the browser's autocomplete function. Basically, <input type="text"> makes the browser suggest a previous search term, but Google provides its own autocomplete.
- jsmodel, jsdata: Properties for Google front-end framework
- <input type="hidden">: Input fields that aren't visible on the screen but send values to the server. / source=hp: Where to start searching(homepage)
<center>
<input class="gNO89b" value="Google 검색" aria-label="Google 검색" name="btnK" role="button" tabindex="0" type="submit" data-ved="0ahUKEwi_6pHqjsuPAxUqm68BHWR3O-QQ4dUDCB8">
<input jscontroller="s980lf" class="RNmpXc" value="I’m Feeling Lucky" aria-label="I’m Feeling Lucky" name="btnI" type="submit" jsaction="rcuQ6b:npT2md;QIWlh" data-ved="0ahUKEwi_6pHqjsuPAxUqm68BHWR3O-QQ19QECCA"> </center>
- name="btnk" / "btnI": Each button has a different name, allowing the server to know which button the user has pressed.
- tabindex="0": Properties that define the order of tab key movement with the keyboard. / 0: default / 1: Selected first when pressing the tab key.
- data-ved: The data-* property is for storing custom data. / Google uses the value 'ved' for tracking/analysis.
- jsaction: Properties used by Google's internal JS framework. Mapping: "Run this function if this event occurs".
index.html
1. Navigation Bar, Logo
<nav class="navbar" role="navigation">
<a href="images.html" target="_top">Images</a>
<a href="adevanced.html" target="_top">Advanced</a>
</nav>
<main class="content">
<div class="logo">
<img src="googlelogo.png" alt="Google Logo" width="272" height="92">
</div>
> header vs. nav
- The <nav> tag is used to define navigation sections. I used a <nav> tag to include two links: Images search and Advanced Search.
- The role="navigation" attribute makes the purpose of this section clear for screen readers.
> <a> tag
- The <a> tag is used to create hyperlinks, which are essential for navigating between different web pages or sections within the same page.
- 'href' attribute specifies the URL of the page the link goes to.
> target="_top"
- To loads the page in the full window.
2. Search Form
<div class="search">
<form action = "https://google.com/search" method="get">
<div class="search-box">
<span class="search-icon">🔍</span>
<input type="text" name="q" title="search">
</div>
<div class="search-btn">
<input type="submit" value="Google Search" name="btnK">
<input type="submit" value="I'm Feeling Lucky" name="btnI">
</div>
</form>
</div>
> <form action = "https://google.com/search" method="get">
- When the user enters or presses the submit button, the request is sent to the URL in the action.
> <input type="text" name="q">
- The search query is delivered in the form q=search word.
> <input type="submit" value="I'm Feeling Lucky" name="btnI">
- I'm Feeling Lucky button -> /search?q=&btnI Request with search word -> Directly redirected to the first site without going through the search results.
> There was a warning notification from the developer tool(F12).
- Warning: Form Elements must have labels: Element has no title attribute Element has no place attribute.
- For a simple solution, I added title="search" to <input>.
3. Footer
The <footer> tag is used to indicate the content of the author of a text or content area, copyright information, links to related documents.
<footer>
<a href="https://policies.google.com/privacy?hl=en&fg=1" target="_blank">Privacy</a>
<a href="https://policies.google.com/terms?hl=en&fg=1" target="_blank">Terms</a>
</footer>
- I used a actual links to Google's Privacy and Terms, and set them to open in a new tab.
- The footer contains links to Privacy and Terms.
- target="_blank" ensures the links open in a new tab.
Google Image Search Page (images.html)
images.html
1. Navigation Bar & Logo
<nav class="navbar" role="navigation">
<a href="index.html" target="_top">Google Search</a>
</nav>
<main class="content">
<div class="logo">
<div class="logo-box">
<img src="googlelogo.png" alt="Google Logo" width="272" height="92">
<span class="images-label">Images</span>
</div>
</div>
- At the top, added a navigation bar with links to Google Search and Advanced Search page.
- Added the Google logo image and a "Images" label.
- To make "Images" appear at the bottom-right corner of the Google logo, I added <div class="logo-box">
2. Search Form
<div class="search">
<form action = "https://google.com/search" method="get">
<input type="text" name="q">
<input type="hidden" name="tbm" value="isch">
<div class="search-btn">
<input type="submit" value="Google Search" name="btnK">
</div>
</form>
</div>
> <input type="hidden" name="tbm" value="isch"> : tbm&isch is a traditional parameter that tells the server that it is Google Image search. You can add to a Google search URL to tell Google to perform an image search.
- When I did a Google Image Search, I could see that the Request URL uses &sca_esv as shown below:
- However, I used 'tbm=isch' to utilise explicit and stable parameters in my project and I checked that the image search performed well.
3. Footer
Same as the footer in index.html
Google Advanced Search Page (advanced.html)
Google HTML - header
<div class="bottom-wrapper">
<header class="" id="gb" role="banner" style="">
<div 5개>
<a class="" aria-label="Google 홈페이지로 이동" href="/webhp?tab=ww&authuser=0">
<span class="" aria-hidden="true" role="presentation">
<div class="">Google 홈페이지로 이동
<div aria-hidden="true" style="overflow:...">
<iframe role="presentation" name="app"...>
<div aria-hidden="true" style="...">
</header>
<div class="appbar">
<div class="gy3Eif"(구분선)>
<div class="Mza7yc">
<form action="/search id="" method="GET" name="f">
<input value="ko" name="hi" type="hidden">
<div
<div style">
- bottom-wrapper: Full page container
- appbar: Grey area with "Advanced Search" title
- aria-* attributes: Convey meaning to assistive technologies (screen readers, etc.) for accessibility
- aria-label: Accessibility attribute. Used to tell screen readers the name of an element.
- <span>: Meaningless inline container tags. Used for applying styling or scripts. / Google uses <span> to place icons or visually hidden text for design control.
- aria-hidden="true": This element should be ignored in assistive technology, screen readers do not read it. / Ex) icons, decorative images, duplicate text.. Cases where it is unnecessary to read aloud to the user.
- <iframe>: Used when embedding another HTML document within the current document. / Google typically loads UI elements like menus, settings, and app panels using iframes. / When role="presentation" is present, accessibility tools treat it as meaningless decoration.
- <label>: This tag represents the label for control elements that provide a user interface. Used with control elements and serves to enhance readability and web accessibility.
Google HTML - main
<div class>
<form action="/search" id="" method="GET" name="f">
<input value="ko" name="hl" type="hidden">
<div class="otByu">
<div class="yjQOUb">
<div class="l1Kbt">
<div class="IOTAE">
<span>Find pages with...</span>
<div class="HoCfzc"> </div>
<div class="orcpGe">
<div class="IOTAE">검색창에서 검색하려면...
<div class="otByu">
<div class="ylQOUb">
<div class="FAcADc">
<div class="IOTAE">
<label for="xX4UFf">all these words:</label>
<div class="jVcxOe">
<div class="PLLUQc">
<input class="jfk-textinput" value autofocus="autofocus" id="xX4UFf" name="as_q" type="text">
<div class="cwqNnb dulCv">
<div class="IOTAE">"중요 단어 입력: "
<span class="BFIQMb">오색 빛깔의 무지개떡
<div class="ylQOUb">
<!--BUTTON-->
<div class="" style="text-align:right">
<input id="" name="tbs" type="hidden" value>
<input class="jfk-button jfk-button-action dUBGpe" style="-webkit-user-select:none:user-select:none;line-height:100%;height:30px;min-width:120px" value="고급검색" type="submit">
- action="/search": Send the user's input to the "/search" path(to Google search page)
- method="GET": Send data via a query string(?q=...)
- name="hl": host language(page language)
- : Non-breaking Space. Prevents automatic line breaks to help keep the text the way it was intended.
- <label for="xX4UFf">: Connects to <input> with id="xX4UFf". When a user clicks on the label, focus is automatically applied to the input field.
<div style="clear:both;font-size:13px;line-height:18px;margin-bottom:90px">
<span>고급 검색...
<a href="https://support.google.com/websearch?p=adv_pages_similar&hl=ko">URL과 비슷한 페이지 찾기</a>
<a href="https://support.google.com/websearch?p=adv_pages_visited&hl=ko">방문한 페이지 검색
<a href="https://support.google.com/websearch?p=adv_operator&hl=ko">검색창에서 연산자 사용
<a href="/preferences?hl=ko">
advanced.html
1. Header Section
<header role="banner">
<div class="header-top">
<a href="https://www.google.com">
<img src="https://www.gstatic.com/images/branding/googlelogo/svg/googlelogo_clr_74x24px.svg"
alt="Google" class="logo">
</a>
<nav class="navbar" role="navigation">
<a href="index.html" target="_top">Google Search</a>
</nav>
</div>
<div class="header-title">
<h1>Advanced Search</h1>
</div>
</header>
- The <header> element marks the top banner of the page.
- The Google logo is placed inside <a>, so clicking the logo takes users back to the Google homepage.
- <nav> with role="navigation" provides a link to the Google Search page.
- The <h1> clearly declares the title, 'Advanced Search'.
2. Search Form
<form class="as" action="https://google.com/search" method="get" name="f" role="search">
<input value="en" name="hl" type="hidden">
<h2 class="search-title">Find pages with...</h2>
<label for="all">all these words:</label>
<input id="all" name="as_q" type="text">
<div class="hint">
Type the important words:
<span class="example">tricolor rat terrier</span>
</div>
- The <form> is where the user inputs search queries.
- action="" sends the request directly to Google's search engine.
- method="get" makes the search parameters appear in the URL.
-> Search Form(Modified)
<main class="content">
<form class="as" action="https://google.com/search" method="get" name="f" role="search">
<input value="en" name="hl" type="hidden">
<div class="as-title">
<h2 class="search-title">Find pages with...</h2>
<div class="empty-cell"></div>
<div class="hint-title">To do this in the search box:</div>
</div>
<div class="as-row">
<div class="as-label">
<label for="all">all these words:</label>
</div>
<div class="as-input">
<input id="all" name="as_q" type="text">
</div>
<div class="as-hint">
<div class="hint">Type the important words:
<span class="example">tricolor rat terrier</span>
</div>
</div>
</div>
- I felt that the html needed a structural adjustment while writing my CSS. Each row has .as-label, .as-input, .as-hint, and this matches google's 3-column layout.
3. Submit Form
<div class="form-action">
<input class="as-btn" type="submit" value="Advanced Search">
</div>
- The button is placed inside a <div> with a semantic class name "form-action".
- Clicking the button submits the form and triggers a Google Search with the advanced parameters.
-> Submit Form(Modified)
<div class="as-row action-row">
<div class="as-label"></div>
<div class="btn-cell">
<input class="as-btn" type="submit" value="Advanced Search">
</div>
<div class="as-hint"></div>
</div>
4. Links
<div class="as-links">
<p>Advanced Search...</p>
<ul>
<li><a href="https://support.google.com/websearch?p=adv_pages_similar&hl=en" target="_blank">Find pages similar to a URL</a></li>
<li><a href="https://support.google.com/websearch?p=adv_pages_visited&hl=en" target="_blank">Search pages you've visited</a></li>
<li><a href="https://support.google.com/websearch?p=adv_operators&hl=en" target="_blank">Use operators in the search box</a></li>
<li><a href="https://www.google.com/preferences?hl=en" target="_blank">Customize your search settings</a></li>
</ul>
</div>
- This section provides helpful links for learning how to use advanced search techniques.
- A <ul> is used to group related links, while CSS can remove the default bullet points for a cleaner look.
5. Footer
<footer>
<a href="https://support.google.com/websearch/?p=ws_results_help&hl=en&fg=1" target="_blank">Support</a>
<a href="https://policies.google.com/privacy?hl=en&fg=1" target="_blank">Privacy</a>
<a href="https://policies.google.com/terms?hl=en&fg=1" target="_blank">Terms</a>
</footer>
- The <footer> contains global links for support, privacy, and terms of service.
6. About codes
- Semantic HTML improves accessibility and SEO.
- Using <label> for each <input> makes the form more user-friendly, especially for screen readers.
- Wrapping the button in '.form-action' improves code organization and styling.
> Why did I use <ul> + list-style:none instead of <br>?
- <ul> + list-style: none; is a better approach than using <br> tags for multiple links.
- Semantically, <br> is signifies a "visual line break" and does not mean a list or item separation, so it's difficult to understand the structure in search engines, screen reader.
- It's inconvenient to maintain because you have to adjust the <br> one by one to change the style.
- Difficult to control line break in mobile responsive design.
styles.css
Google DevTools
> Strikethrough
- In a Google DevTools, a strikethrough on a style property indicates that the property is not being applied and has been 'overridden' by another style.
- If there are more specific selectors and more powerful rules, these are applied instead.
- Later code and inline styles take precedence.
- Styles written directly within HTML tags are the most powerful.
- When used like this 'color:green !important;' is enforced against all other rules.
- The actual applied value can be found in the 'Computed' tab on the right.
> body{display:block;}
- In the Computed tab of the Google DevTool, the style that the browser finally applied to the body.
- User agent stylesheet.
- display:block is the default, so don't have to specify it.
> Image/Search Links
- color: rgba(0,0,0,.87) //Color of the letters. (red, green, blue, alpha(transparency))
- cursor: pointer //When you mouse over sth, the cursor changes to a finger shape.
- display: inline-block //It's placed in one line like text. Allows width, height, padding.. to be given like a block element. To arrange and align the link <a> in more detail than simple text.
- font-family: arial, sans-serif //A font designation. Arial is the default, and use the San Serif family basic font if you don't have Arial.
- font-size: 13px
- line-height: 24px //Line height, including the up and down margins of the text.
- text-decoration: none; //By default, the <a> tag is underlined, but this property removes it. It changes the color slightly or shows the underline again in the hover(:hover).
> :hover
- A pseudo-class that allows you to apply styles to an element when a user's pointer is hovering over it.
- 'nav.navbar a:hover' means that the style applies when you mouse over the link <a> in the navigation bar.
> [type="text"]
- Attribute selector. Select only the elements with the type="text" property among the input tags.
> Why Google CSS doesn't have 'text-align: right'
- The placement of the inner container was controlled by flexbox.
> Google Logo, Logo Image
color:rgb(31, 31, 31)
display:block
font-family:Arial, sans-serif
font-size:14px
height:92px
margin-top:36px
max-height:92px
position:relative: A positioning value that allows an element to be positioned relative to its normal position in the document flow
unicode-bidi:isolate: Process text direction(LTR/RTL) independently to prevent directional confusion when displaying multiple languages
width:272px
color:rgb(31, 31, 31)
display:inline :Image is an inline element by default(in the middle of a sentence)
font-family:Arial, sans-serif
font-size:14px
height:92px
max-height:100%
max-width:100%
object-fit:contain :Maintain image proportions and fit within the area. Keep the original proportion without cutting out the image and display it "full in the box".
object-position:50% 100% :Align horizontal to center(50%) and vertical to bottom(100%)
overflow-clip-margin:content-box
overflow-x:hidden :If the image is out of the area, cut it out.
overflow-y:hidden
width:272px
> 'Images' text next to the Google Logo
.T8VaVe {
color: #4285f4;
font: 16px / 16px Arial, sans-serif;
position: absolute; :Precisely place the text relative to the logo, ensuring it aligns perfectly at the bottom-right of the logo area.
left: 215px;
bottom: 0;
white-space: nowrap; :Prevents the word from breaking onto multiple lines.
}
> Search Form
margin: 0 auto; :Align the entire <div> horizontally by automatically aligning the left and right margins
max-width: 688px; :Limit the maximum width
padding-top: 6px;
position: relative; :Place the form based on the inside absolute element.
> Search Container(.RNNXgb)
display: flex :To place icons/input space/voice button horizontally inside search bar
z-index: 3 :Prioritize to appear before other elements(drop-down search suggestions list)
position: relative :Helps icons to be fixed in a specific location in the search box
min-height: 50px :Keep internal content(text, icon) at least 50px high
background: #fff
border: 1px solid #dadce0 :A light gray line on the edge of the search bar
box-shadow: 0px 3px 10px 0px rgba(31, 31, 31, 0.08) :Shadow effect of the search bar
border-radius: 26px :Oval search box
margin: 0 auto :Horizontal center alignment by parent container
> Input area (Some css of Styles)
line-height: 22px
border-bottom: 8px solid transparent :Make space to underline during focus effects
padding-top: 14px :Upper margin of the search word in the search box
overflow-x: hidden :To prevent the horizontal scroll bar from when long text is entered
width: 100% :Reactive layout
resize: none :Disable sizing to prevent edge drag when textarea
background-color: transparent
border: none, margin: 0, padding: 0 :Balance search bar by removing all margins
word-wrap: break-word :Auto line long words
outline: none :Remove blue borders when clicked
display: flex
-webkit-tap-highlight-color: transparent :Remove highlights when mobile tab
font-size: 16px
flex: 100%
> Buttons
lJ9FBc {
height: 70px;
}
FPdoLc {
padding-top: 18px;
} :To adjust the upper spacing of the entire button area
> Buttons input[type="submit"]
background-color: #f8f9fa;
border: 1px solid #f8f9fa; :Use the same color for the border and background
border-radius: 8px;
color: #3c4043;
font-family: Arial, sans-serif;
font-optical-sizing: none;
font-size: 14px;
font-weight: 400;
margin: 11px 4px; Intervals between buttons
padding: 0 16px; :Internal margin(left, right)
height: 36px;
min-width: 54px;
text-align: center;
cursor: pointer;
user-select: none; :Prevent button text drag
> header, nav bar
display: block :Ensures <header> acts as a block-level container.
min-width :Prevents header collapsing on small screens
position:relative :For placing icons, dropdowns..
font:13px / 27px Roboto, Arial, sans-serif
z-index:986 :Keeps header above other page elements
min-width:0 :Ensures flex items can shrink properly instead of overflowing
padding:4px
padding-left:8px
transition: background-color .4x
box-sizing:border-box :Makes width include padding and border
position:relative
width:100% :Makes header span the entire available width so it stretches across the page
display:flex :For aligning elements horizontally
justify-content:space-between :Distributes items at far left(logo) and right(link)
> Small Google Logo
display: inline-block :Allows sizing and positioning, flows inline
position:relative
overflow:hidden :Hides overflowing parts of the image
top:2px
user-select:none
padding-left:12px
line-height:normal :Resets inherited line-height to avoid extra space. Ensures image is vertically centered properly
position:relative
<a>
max-width:100% :Prevents the image or link area from exceeding its container width
<span>
display:inline-block
outline:none :Removes default browser outline when focused
vertical-align:middle :Vertically aligns the span content with the middle of the line
> Title
color: #d93025
font-size: 20px
margin: 25px 35px
<label>
font-weight: 400 : 400==normal
margin-left: 10px
> Search Form
max-width: 1140px
min-width: 200px
width: 96% : 96% width of the parent, leaving small side gaps
margin: 40px 2% 0 45px : top/right/bottom/left
> Search Title
color:rgb(51, 51, 51)
font-family: Arial, sans-serif
sont-size: 16px
font-weight:500
vertical-align: baseline
> Hint Title
height: 30px
display: table-cell : Makes the element behave like a cell inside an HTML table
vertical-align: middle : This only works on table cells(or inline, inline-block), vertically centers the text inside the 30px area.
> label
color: rgb(34, 34, 34)
font-size: 13px
font-style: normal
font-weight: 400
line-height: 16px
vertical-align: baseline :Align the element's bottom with the baseline of the parent text / This is the default for most inline elements such as <label>, <span>, etc.
> Input
border-radius: 1px
border: 1px solid #d9d9d9
border-top: 1px solid #c0c0c0
font-size: 13px
height: 25px
padding 1px 8px
width: 496.638px
> Hint
color: rgb(102, 102, 102)
font-family: monospace
font-size: 11px
font-style: normal :Not italic
font-weight: 400 :Standard weight
> Hint Example
color: #666
font-family: monospace
font-size: 11px
white-space: pre : Keep all spaces exactly as typed, keep all line breaks and don't wrap text automatically
vertical-align: baseline
text-decoration: none
> AS - Button
user-select: none
line-height: 100%
height: 30px
min-width: 120px
float: right
margin: 10px 0
padding: 0 12px
box-shadow: none
background-color: #4d90fe
border: 1px solid #3079ed
color: #fff
border-radius: 2px
font-size: 11px
font-weight: bold
text-align: center
white-space: nowrap
outline: 0
styles.css
1. body
body {
height: 100%;
margin: 0;
padding: 0;
font-size: 14px;
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
- font-size and font-family are inherited to other css.
- display: flex;: Flexbox(flex container). Creates a block level flex container.(display:inline-flex creates inline level flex container) / Properties: flex-direction, justify-content, align-items, flex-wrap, align-content, gap
- flex-direction: column;: Sets the direction of the main axis
2. nav.navbar
nav.navbar{
display: flex;
justify-content: flex-end;
align-items: center;
gap: 15px;
padding: 15px 20px 15px 0;
width: 100%;
box-sizing: border-box;
}
- display: flex; :Use Flexbox to easily align and space out the nav items. It turns out the <nav> element into a flexible container that controls how its children are laid out.
- justify-content: flex-end; :Aligns all the links to the right side of the nav bar. / justify-content: Sort by horizontal axis / flex-end: align to the right end
- align-items: center;:Ensures that all links are vertically centered inside the navbar, even if their height changes.
- gap: 15px;: Adds a 15px space between each nav link. It's cleaner and modern than using margin-right on each <a> tag.
- padding: 15px 20px 15px 0; : Creates a space inside the navbar. / top-right-bottom-left
- width: 100%;: Children occupy all parent widths to maintain right alignment
- box-sizing: border-box;
> box-sizing: Defines how the total width and height of an element are calculated.
- content-box: Default value. The width and height properties include only the content, excluding padding and border.
- border-box: The width and height properties include the content, padding, and border, but not the margin.
* Why a child element needs 'width: 100%' to properly use right-alignment('justify-content :flex-end') when its parent has 'display:flex'
> Pre-Flex layout: Before applying 'display: flex' to the <body>
body {
text-align: center;
}
nav.navbar {
display: flex;
justify-content: flex-end;
}
- The <body> automatically takes up the full width of the viewport(width:100% by default)
- A child element <nav> also automatically occupies the full width of its parent <body>.
- So, if you set a text alignment on the <body> and a specific alignment(flex-end) on the <nav>, the alignment works across the entire screen width because the <nav> spans the full width.
> The problem: When I set the <body> to 'display: flex', its layout changes
- The <body> becomes a Flex Container, and the <nav> becomes a Flex Item.
- Flex Containers default to fitting their content(width:auto). The <body> no longer automatically stretches to the full viewport width, its width shrinks to the minimum size required to contain its flex items(<nav>, two links).
> The consequence of shrinking width
- At this point, when I applied 'justify-content: flex-end' to the <nav>, the right-alignment only happens within the <nav>'s content-sized width. It cannot push the content to the right of the screen because the container isn't wide enough.
> The solution: Set width: 100% on the <nav>
- This forces the <nav>(the flex item) to re-expand and take up the full width of its parent <body>. Once the <nav> spans the entire viewport, 'justify-content: flex-end' can successfully push the content all the way to the right edge of the screen.
=> When the body is a Flex Container, the 'width: 100%' must be specified so that the child takes up the entire width of the parent so that 'justify-content' works on a screen-by-screen basis.
=> When the <body> acts as a Flex Container, 'width:100%' should be specified on the child element to ensure the child occupies the entire width of the viewport. This allows 'justify-content:flex-end' to correctly push the content to the right edge of the screen.
3. nav.navbar a
nav.navbar a{
color: rgba(0, 0, 0, .87);
font-size: 13px;
line-height: 24px;
text-decoration: none;
cursor: pointer;
}
- color: rgba(0, 0, 0, .87); : Uses a slightly transparent black.
- text-decoration: none; : Removes the underline from links.
- cursor: pointer; : Ensures the cursor changes when hovering, indicating it's clickable.
4. nav.navbar a:hover
nav.navbar a:hover{
text-decoration: underline;
}
- Underline when mouse over the link.
5. .logo
.logo{
margin-top: 36px;
display: flex;
justify-content: center;
}
- This handles centering the logo group.
- margin-top: 36px; : Adds top margin to create spacing from the elements above
6. .logo-box
.logo-box{
position: relative;
display: inline-block;
}
- This creates a smaller box that wraps tightly around the image, giving .images-label a local positioning context.
- position: relative;: To place 'Images' label precisely in relation to this container.
> Why use display: inline-block; on .logo-box? : Want the .logo-box to wrap tightly around the image, not stretch full width.
- display: block :Element takes the entire width of its parent(100%), which would make the .logo-box as wide as the screen.
- display: inline :Element only takes the width of its content, but you can't use width, height, position:relative properly on it.
-display: inline-block :Behaves like inline(fits tightly around content) but still allows block feature like position:relative, margins, padding.
=> 'inline-block': small, self contained box around the image & allows 'position:relative' so the .images-label can be positioned absolutely inside it.
* Inline vs. Inline-block: Inline elements do not respect width and height properties / Inline-block respect those and allow top and bottom margins, paddings.
* block vs. inline-block: Block elements add a line break after the element. Inline-block don't, allowing them to sit next to other elements.
7. .logo img
.logo img{
object-fit: contain;
display: block;
}
- object-fit: contain;: Ensures the logo keeps its original proportions without stretching or cropping.
- display: block;: By default, <img> elements are inline elements. They sit on the text baseline, leave a small gap below, can cause layout misalignment. / The image becomes a block-level element, removing the extra baseline space and ensuring it aligns cleanly within its parent box. It prevents small white gaps below the image. / 'block' makes the image behave like a solid rectangular box, easier to align and measure.
8. images-label
.images-label{
color: rgb(66, 133, 244);
font-size: 16px;
position: absolute;
right: 0;
bottom: 0;
font-weight: 400;
line-height: 16px;
white-space: nowrap;
}
- position: absolute;: Removes the element from the normal document flow and positions it relative to its closest positioned ancestor(relative, absolute, fixed, sticky).
- white-space: nowrap;: Ensures the text remains on a single line without breaking.
- This class styles the small blue 'Images' text next to the logo.
> right:0, bottom:0 :Because .images-label is absolutely positioned inside .logo-box.
- right: 0; :Stick to the right edge of .logo-box
- bottom: 0; :Stick to the bottom edge of .logo-box
=> Positions the "Images" text exactly in the bottom-right corner of the logo image's box.
9. .search
.search{
margin: 0 auto;
max-width: 688px;
padding-top: 40px;
width: 100%;
}
> The problem: The search box appeared shorter(275px) than expected(688px).
- Originally, I only had 'max-width: 688px', this limited the overall size of the container.
- Adding 'width: 100%' to .search itself and the child elements(search form, search-box). This fixed the issue by making the container stretch to fill its parent, allowing its children to inherit the correct width(688px).
- Width inheritance in flex layouts isn't automatic. If the parent's width isn't explicitly defined, a child's width won't actually have anything to base itself on. 'width:100%' should be added to all of the parents and the children, so that .search -> search form -> .search-box should be connected.
10. .search form
.search form{
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
- flex-direction: column;: Means the main axis is vertical.
- align-items: center; : horizontal alignment / 'justify-content: center': vertical alignment => I wanted the search box and buttons to stack vertically but be centered horizontally.
11. .search-box
.search-box{
display: flex;
align-items: center;
width: 100%;
max-width: 688px;
min-height: 50px;
padding: 0 15px;
background: #fff;
border: 1px solid #dadce0;
border-radius: 26px;
box-shadow: 0px 3px 10px 0px rgba(31, 31, 31, 0.08);
position: relative;
}
- '.search-box' is a flex container holding the search icon and the input field.
- By default, the .search-box only grew to fit its content. So adds 'width:100%' to ensure it fills its parent container's width(688px).
- position: relative; :The relative value for this property can position the element relative to its normal position in the document flow. It means that you can move the element from its defalut position without affecting the position of the other elements. / Helps icons to be fixed in a specific location in the search box.
12. .search-box:hover
.search-box:hover{
box-shadow: 0px 3px 10px rgba(31, 31, 31, 0.28);
}
- box-shadow: offset-x(required) offset-y(required) blur-radius spread-radius color inset;
13. .search-box input
.search-box input{
flex: 1; /*flex-grow:1; flex-shrink:1, flex-basis:0;:occupy all remaining space*/
line-height: 22px;
border-bottom: 8px solid transparent;
padding-top: 14px;
resize: none;
background-color: transparent;
border: none;
margin: 0;
padding: 0;
outline: none;
word-wrap: break-word;
display: flex;
font-size: 16px;
}
- border: none; : Removes the border from the element. For inputs or buttons, this gives a clean flat look instead of the browser's default outline.
- outline: none; : Removes the focus outline that browsers automatically draw when an element is selected.
> The problem: My input only took up about one-third of the search box width.
- The reason: In a flex container, elements only take s much space as their content unless you tell them to grow.
- The solution: Adds flex: 1; - Makes the input expand to fill all the remaining horizontal space in the .search-box.
* flex
- flex-grow: The default value is 0; inflexible. The number means that the rest of the margin is divided by the proportion excluding flex-basis. If the value is greater than or equal to 1, changes fluidly depending on the width of the screen; flexible.
- flex-shrink: A property determining whether an item can shrink below its flex-basis. The default value is 1, a value of 1 or greater indicates the item can shrink proportionally to that value; flexible. If the value is 0, the item can't shrink below its flex-basis; inflexible.
- flex-basis: The default size of a item. The default value 'auto' means the width of the content.
=> flex:1 = flex-grow:1; flex-shrink:1; flex-basis:0;. This means that the size of the flex item increases or decreases depending on the size of the flex container.
> Why I removed 'overflow-x: hidden'
- I had 'overflow-x:hidden' but in Google DevTools, it appeared crossed out, meaning the property wasn't applied.
- 'overflow-x' only works on scrollable block-level elements. My 'input' is display:flex, not block. And browser-native text inputs don't create scrollable content areas.
- This property is meaningful in scrollable containers like a <div>, but not for <input> elements.
14. .search-icon
.search-icon {
font-size: 17px;
margin-right: 10px;
pointer-events: none;
}
- pointer-events: none; : Makes element completely ignore mouse interactions like clicks, hovers.
15. .search-btn
.search-btn{
display: flex;
justify-content: center;
margin-top: 18px;
}
- justify-content: center; : Centers along the main axis. Horizontal by default.
- align-items: center; : Centers along the cross axis. Vertical by default.
16. .search-btn input
.search-btn input{
background-color: rgb(248, 249, 250);
border: 1px solid rgb(248, 249, 250);
border-radius: 8px;
font-weight: 400;
margin: 11px 4px;
padding: 0 16px;
height: 36px;
min-width: 54px;
cursor: pointer;
user-select: none;
}
- user-select: none; : Prevents the user from selecting the text inside the element.
17. .search-btn input:hover
.search-btn input:hover{
border: 1px solid #dadce0;
box-shadow: 0 1px 1px rgba(15, 15, 15, 0.1);
}
- When you mouse over the button, it creates a shadowy border like Google's.
18. header
header{
display: block; /*default*/
background-color: #fff;
color: #000;
font-size: 13px;
border-bottom: 1px solid #dadce0;
padding: 8px 8px;
position: relative;
}
- display: block; : Makes the header occupy the full available width(width:100%) and stack vertically above the rest of the content. / This isn't necessary because the default behaviour of <header> is 'display:block'.
- border-bottom: 1px solid #dadce0; : Adds a faint divider below the header.
- padding: 8px 8px; : (top/bottom)+(left/right)
19. .header-top
.header-top{
display: flex;
align-items: center;
justify-content: space-between;
}
- display: flex; : Turns this container into a flexbox. Horizontal layout. / To set the logo on the left, the navigation link on the right.
- align-items: center; : In a flex container, this vertically centers all items along the cross-axis (vertical direction for flex-direction:row). / The logo image(height:24px) and text link(font-size:13px) are in the same row, 'align-items:center' aligns them nicely in the middle. Without it, they'll be unevenly aligned.
- justify-content: space-between; : Pushes the first child(logo) to the far left, and the second(link) to the far right.
20. .header-top img
.header-top img{
object-fit: contain;
user-select: none;
display: inline-block;
position: relative;
top: 2px;
padding-left: 12px;
line-height: normal;
}
- object-fit: contain; : Scales the image proportionally so it fits within its box without cropping
- user-select: none; : Prevents the logo from being highlighted when clicked/dragged
- display: inline-block; : Allows the image to flow inline with other elements, but also have its own width/height and padding. / If I use 'display:block', it would start on a new line and push text below it. And if 'inline', I couldn't apply padding/top.
- position: relative; : Creates a local positional context(top:2px)
- line-height: normal; : Resets inherited line-height
21. .header-title
.header-title{
margin: 25px 35px;
}
- margin: (top/bottom) (left/right)
22. .header-title h1
.header-title h1{
font-size: 20px;
font-weight: 400;
color: rgb(217, 48, 37);
margin-left: 10px;
}
23. .as
.as{
max-width: 1100px;
min-width: 1000px;
width: 100%;
margin: 40px 2% 0 52px;
}
- min-width: 1000px;: The layout won't shrink below 1000px, preventing overlap of input + hint.
- margin: 40px 2% 0 52px;: Adds top and left spacing. (top right bot left)
24. .as-title
.as-title{
display: table;
width: 100%;
table-layout: fixed;
margin-bottom: 20px;
}
- display: table;: This turns the element into a table container. Children with 'display: table-cell' will behave like table cells.
- table-layout: fixed;: Column widths are determined entirely by CSS, content cannot stretch the column wider and layout is predictable.
25. .as .search-title
.as .search-title{
display: table-cell;
vertical-align: middle;
width: 180px;
color: rgb(51, 51, 51);
font-family: Arial, sans-serif;
font-size: 16px;
font-weight: 500;
}
- display: table-cell;: Makes this behave like a column cell.
- vertical-align: middle;: Centers the text vertically inside the row.
26. .as .empty-cell
.as .empty-cell{
display: table-cell;
width: 460px;
}
- This creates a blank column between the title and the hint title.
27. .as . hint-title
.as .hint-title{
display: table-cell;
width: 320px;
vertical-align: middle;
font-family: Arial, sans-serif;
font-size: 13px;
color: rgb(119, 119, 119);
padding-left: 20px;
}
- padding-left: 20px;: Creates space between input and hint.
28. .as-row
.as-row{
display: table;
table-layout: fixed;
width: 100%;
max-width: 1100px;
margin-bottom: 12px;
}
- Each row(label / input / hint) behaves like a table with 3 columns.
- 180px: label, search-title / 460px: input, empty-cell / 320px: hint, hint-title
29. .as-label
.as-label{
display: table-cell;
vertical-align: middle;
width: 180px;
}
- Vertical centering makes labels align naturally next to input boxes.
30. .as label
.as label{
color: rgb(22, 21, 21);
font-size: 13px;
line-height: 16px;
}
31. .as-input
.as-input{
display: table-cell;
vertical-align: middle;
width: 460px;
padding-right: 20px;
}
- padding-right: 20px;: Makes space between input and hint to prevent overlap.
32. .as input
.as input[type="text"]{
border: 1px solid #d9d9d9;
border-top: 1px solid #c0c0c0;
border-radius: 1px;
font-size: 13px;
height: 25px;
padding: 1px 8px;
width: 100%;
font-family: Arial;
}
33. .as input:focus
.as input[type="text"]:focus{
border-color: rgb(66, 133, 244);
outline: none;
}
- Creates the blue border effect when the user focuses the input.
34. .as-hint
.as-hint{
display: table-cell;
vertical-align: middle;
width: 320px;
padding-left: 20px;
}
35. .hint
.hint{
color: rgb(102, 102, 102);
font-family: monospace;
font-size: 11px;
}
- Monospace font for hints.
36. .hint .example
.hint .example{
color: #666;
font-family: monospace;
font-size: 11px;
white-space: pre;
}
- white-space: pre;: Preserves spaces and line breaks, ensures spacing in the example isn't collapsed.
> The problem: 1. Input and hint text overlapping. 2. No space between the two titles.
> Why happened
- The form rows were structured as table-like elements using display:table and table-layout:fixed. 'table-layout:fixed' strictly enforces widths, and when the browser can't fit all fixed width cells comfortably, the last cell is compressed.
> Solution
- Add 'padding-right: 20px' to as-input, and 'padding-left: 20px' to as-hint.
2. No space between the two titles.
> Solution
- Add an 'empty cell' to create a blank space between the titles. And set the empty cell to the same pixel as the input box below.
37. .as-row.action-row
.as-row.action-row{
display: table;
width: 100%;
max-width: 1100px;
}
- This row is displayed as a table to stay consistent with the layout structure used for the other rows.
38. .btn-cell
.btn-cell{
display: table-cell;
vertical-align: middle;
width: 475px;
}
- vertical-align: middle;: Vertically centers the button within the row.
- width: 475px;: Input width(460px) + padding(15px) = btn-cell width(475px) / The width of 475px matches the width of the input column, so the button sits exactly underneath the input boxes.
39. .as-btn
.as-btn{
user-select: none;
height: 30px;
min-width: 120px;
float: right;
margin: 10px 0;
padding: 0 12px;
background-color: #4d90fe;
border: 1px solid #3079ed;
color: #fff;
font-size: 12px;
font-weight: bold;
text-align: center;
white-space: nowrap;
border-radius: 2px;
cursor: pointer;
}
- user-select: none;: Prevents text selection when clicking the button
- float: right;: Pushes the button to the right side of its cell.
- white-space: nowrap;: Ensures the text never wraps onto a second line
- cursor: pointer;: Not in Google's CSS, but I added it as it seems to look better visually.
40. .as-btn:hover
.as-btn:hover{
background-color: #357ae8;
border: 1px solid #2f5bb7;
}
41. .as-btn:focus
.as-btn:focus{
box-shadow: inset 0 0 0 1px #fff;
border: rgba(0, 0, 0, 0) solid 1px;
}
- 'inset' makes the shadow appear inside the element when it's pressed down.
42. footer
footer{
background: #f2f2f2;
display: flex;
justify-content: flex-end;
padding: 0 20px;
height: 50px;
align-items: center;
}
- Turns the footer into a flex container, pushes all child elements to the right side of the footer. And vertically centers the child elements within the footer's height.
43. footer a
footer a{
color: #1f1f1f;
font-size: 14px;
font-family: Arial, sans-serif;
padding: 0 15px;
text-decoration: none;
}
- text-decoration: none;: Removes the default underline from links
- I removed 'cursor: pointer' because <a> elements already use the pointer cursor.
44. footer a:hover, aslinks a:hover
footer a:hover, .as-links a:hover{
text-decoration: underline;
}
- When the user hovers over a link, the underline reappears.
> To make the footer stay at the bottom
- Rewrote html. Added <main class="content"> to index/images/advanced.html.
- The 'body' is already a flex container, add html{height:100%;} and .content{flex:1;}.
- When 'body' is display:flex & flex-direction: column, '.content' expands to fill leftover vertical space.
45. .as-links
.as-links{
margin-top: auto;
margin-bottom: 40px;
}
- margin-top: auto;: Pushes the section to the bottom within a flex container
46. .as-links p
.as-links p{
color: rgb(51, 51, 51);
font-family: Arial, sans-serif;
font-size: 16px;
font-weight: 500;
margin-left: 52px;
}
47. .as-links ul
.as-links ul{
list-style: none;
margin: 0;
padding: 0;
}
- list-style: none;: Removes default bullets.
48. .as-link a
.as-links a{
color: rgb(0, 0, 238);
font-family: Arial, sans-serif;
font-size: 13px;
line-height: 18px;
margin-left: 52px;
text-decoration: none;
}
Result: Screen Shot
Result: Video
Ref.
- HTML <footer> 태그 – 올바른 이해와 사용 방법 - 코딩에브리바디
- HTML <label> 태그 – 올바른 이해와 사용 방법 - 코딩에브리바디
- HTML <hr> 태그 – 가로(수평)선 요소 - 코딩에브리바디
- HTML <p> 태그 – 문단 요소 - 코딩에브리바디
- [hover]hover에 대하여
- https://developer.mozilla.org/en-US/docs/Web/CSS/display
- justify-content - CSS: Cascading Style Sheets | MDN
- CSS position: absolute 완벽 가이드 - 코딩에브리바디
- [CSS] CSS Position (relative, absolute) 한 방에 정리!
- [CSS] Margin auto
- [CSS] box-shadow 속성 사용법 총정리 – 모두의매뉴얼
- flex: 1 1 0 의 의미
- CSS border 속성 - ofcourse
- [CSS] 레이아웃 속성 display:flex : 네이버 블로그
- [html/css] display 속성 (inline, block, none, inline-block 차이), visibility 속성(visible, hidden, collapse 차이)
- CSS table-layout 속성 – 테이블 너비 레이아웃 구현 방식 선택 - 코딩에브리바디

댓글 없음:
댓글 쓰기